StopTriggerMethod.Opposite not working.

Created at 21 Apr 2021, 08:05
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
MC

mcho911

Joined 20.09.2020

StopTriggerMethod.Opposite not working.
21 Apr 2021, 08:05


I have my code below trying to set Stop Trigger Method to the Opposite. I couldn't to get it to work for some reasons. The Order is placed but the Trigger Method is still set as the default "Trade". No Errors in the console. Thank you in advance. 

TradeOperation result = PlaceStopLimitOrderAsync(TradeType.Sell, SymbolName, volumeLots, _lowest - Symbol.Spread, slippage, "Buy", null, null, addExpiryHours, _comment,
                false, StopTriggerMethod.Opposite);

 


@mcho911
Replies

amusleh
21 Apr 2021, 08:40

Hi,

It works fine, try this sample:

using cAlgo.API;
using System;
using System.Globalization;

namespace cAlgo.Robots
{
    /// <summary>
    /// This sample bot shows how to place different types of pending orders
    /// </summary>
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class PendingOrderPlacingSample : Robot
    {
        [Parameter("Type", DefaultValue = PendingOrderType.Limit)]
        public PendingOrderType OrderType { get; set; }

        [Parameter("Direction", DefaultValue = TradeType.Buy)]
        public TradeType OrderTradeType { get; set; }

        [Parameter("Volume (Lots)", DefaultValue = 0.01)]
        public double VolumeInLots { get; set; }

        [Parameter("Distance (Pips)", DefaultValue = 20, MinValue = 1)]
        public double DistanceInPips { get; set; }

        [Parameter("Stop (Pips)", DefaultValue = 10, MinValue = 0)]
        public double StopInPips { get; set; }

        [Parameter("Target (Pips)", DefaultValue = 10, MinValue = 0)]
        public double TargetInPips { get; set; }

        [Parameter("Limit Range (Pips)", DefaultValue = 10, MinValue = 1)]
        public double LimitRangeInPips { get; set; }

        [Parameter("Expiry", DefaultValue = "00:00:00")]
        public string Expiry { get; set; }

        [Parameter("Label")]
        public string Label { get; set; }

        [Parameter("Comment")]
        public string Comment { get; set; }

        [Parameter("Trailing Stop", DefaultValue = false)]
        public bool HasTrailingStop { get; set; }

        [Parameter("Stop Loss Method", DefaultValue = StopTriggerMethod.Trade)]
        public StopTriggerMethod StopLossTriggerMethod { get; set; }

        [Parameter("Stop Order Method", DefaultValue = StopTriggerMethod.Trade)]
        public StopTriggerMethod StopOrderTriggerMethod { get; set; }

        [Parameter("Async", DefaultValue = false)]
        public bool IsAsync { get; set; }

        protected override void OnStart()
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);

            DistanceInPips *= Symbol.PipSize;

            var stopLoss = StopInPips == 0 ? null : (double?)StopInPips;
            var takeProfit = TargetInPips == 0 ? null : (double?)TargetInPips;

            TimeSpan expiry;

            if (!TimeSpan.TryParse(Expiry, CultureInfo.InvariantCulture, out expiry))
            {
                Print("Invalid expiry");

                Stop();
            }

            var expiryTime = expiry != TimeSpan.FromSeconds(0) ? (DateTime?)Server.Time.Add(expiry) : null;

            TradeResult result = null;

            switch (OrderType)
            {
                case PendingOrderType.Limit:
                    var limitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask - DistanceInPips : Symbol.Ask + DistanceInPips;

                    if (IsAsync)
                        PlaceLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, OnCompleted);
                    else
                        result = PlaceLimitOrder(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod);

                    break;

                case PendingOrderType.Stop:
                    var stopPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;

                    if (IsAsync)
                        PlaceStopOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
                    else
                        result = PlaceStopOrder(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);

                    break;

                case PendingOrderType.StopLimit:
                    var stopLimitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;

                    if (IsAsync)
                        PlaceStopLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
                    else
                        result = PlaceStopLimitOrder(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);

                    break;

                default:
                    Print("Invalid order type");

                    throw new ArgumentOutOfRangeException("OrderType");
            }

            if (!IsAsync) OnCompleted(result);
        }

        private void OnCompleted(TradeResult result)
        {
            if (!result.IsSuccessful) Print("Error: ", result.Error);

            Stop();
        }
    }
}

There is two stop trigger method parameters, one for stop loss order and another for stop order itself.


@amusleh

mcho911
21 Apr 2021, 12:11

RE:

amusleh said:

Hi,

It works fine, try this sample:

using cAlgo.API;
using System;
using System.Globalization;

namespace cAlgo.Robots
{
    /// <summary>
    /// This sample bot shows how to place different types of pending orders
    /// </summary>
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class PendingOrderPlacingSample : Robot
    {
        [Parameter("Type", DefaultValue = PendingOrderType.Limit)]
        public PendingOrderType OrderType { get; set; }

        [Parameter("Direction", DefaultValue = TradeType.Buy)]
        public TradeType OrderTradeType { get; set; }

        [Parameter("Volume (Lots)", DefaultValue = 0.01)]
        public double VolumeInLots { get; set; }

        [Parameter("Distance (Pips)", DefaultValue = 20, MinValue = 1)]
        public double DistanceInPips { get; set; }

        [Parameter("Stop (Pips)", DefaultValue = 10, MinValue = 0)]
        public double StopInPips { get; set; }

        [Parameter("Target (Pips)", DefaultValue = 10, MinValue = 0)]
        public double TargetInPips { get; set; }

        [Parameter("Limit Range (Pips)", DefaultValue = 10, MinValue = 1)]
        public double LimitRangeInPips { get; set; }

        [Parameter("Expiry", DefaultValue = "00:00:00")]
        public string Expiry { get; set; }

        [Parameter("Label")]
        public string Label { get; set; }

        [Parameter("Comment")]
        public string Comment { get; set; }

        [Parameter("Trailing Stop", DefaultValue = false)]
        public bool HasTrailingStop { get; set; }

        [Parameter("Stop Loss Method", DefaultValue = StopTriggerMethod.Trade)]
        public StopTriggerMethod StopLossTriggerMethod { get; set; }

        [Parameter("Stop Order Method", DefaultValue = StopTriggerMethod.Trade)]
        public StopTriggerMethod StopOrderTriggerMethod { get; set; }

        [Parameter("Async", DefaultValue = false)]
        public bool IsAsync { get; set; }

        protected override void OnStart()
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);

            DistanceInPips *= Symbol.PipSize;

            var stopLoss = StopInPips == 0 ? null : (double?)StopInPips;
            var takeProfit = TargetInPips == 0 ? null : (double?)TargetInPips;

            TimeSpan expiry;

            if (!TimeSpan.TryParse(Expiry, CultureInfo.InvariantCulture, out expiry))
            {
                Print("Invalid expiry");

                Stop();
            }

            var expiryTime = expiry != TimeSpan.FromSeconds(0) ? (DateTime?)Server.Time.Add(expiry) : null;

            TradeResult result = null;

            switch (OrderType)
            {
                case PendingOrderType.Limit:
                    var limitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask - DistanceInPips : Symbol.Ask + DistanceInPips;

                    if (IsAsync)
                        PlaceLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, OnCompleted);
                    else
                        result = PlaceLimitOrder(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod);

                    break;

                case PendingOrderType.Stop:
                    var stopPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;

                    if (IsAsync)
                        PlaceStopOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
                    else
                        result = PlaceStopOrder(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);

                    break;

                case PendingOrderType.StopLimit:
                    var stopLimitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;

                    if (IsAsync)
                        PlaceStopLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
                    else
                        result = PlaceStopLimitOrder(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);

                    break;

                default:
                    Print("Invalid order type");

                    throw new ArgumentOutOfRangeException("OrderType");
            }

            if (!IsAsync) OnCompleted(result);
        }

        private void OnCompleted(TradeResult result)
        {
            if (!result.IsSuccessful) Print("Error: ", result.Error);

            Stop();
        }
    }
}

There is two stop trigger method parameters, one for stop loss order and another for stop order itself.

HI @amusleh,

Thank you for this detailed sample. It makes much more sense to how to do it properly. It seems to work at first. However, it cancel the StopLimit Order when price hit instead of triggering the order. 

It's strange that it catch the error to stop the cbot but wouldn't print the error to the console. Any solution? 

 

 


@mcho911

amusleh
21 Apr 2021, 13:50

RE: RE:

mcho911 said:

HI @amusleh,

Thank you for this detailed sample. It makes much more sense to how to do it properly. It seems to work at first. However, it cancel the StopLimit Order when price hit instead of triggering the order. 

It's strange that it catch the error to stop the cbot but wouldn't print the error to the console. Any solution? 

 

 

Hi,

What do you mean? I just tried two buy and sell stop limit orders with opposite trigger method and it got triggered without any problem.


@amusleh

mcho911
21 Apr 2021, 22:19 ( Updated at: 21 Apr 2021, 22:48 )

RE: RE: RE:

amusleh said:

mcho911 said:

HI @amusleh,

Thank you for this detailed sample. It makes much more sense to how to do it properly. It seems to work at first. However, it cancel the StopLimit Order when price hit instead of triggering the order. 

It's strange that it catch the error to stop the cbot but wouldn't print the error to the console. Any solution? 

 

 

Hi,

What do you mean? I just tried two buy and sell stop limit orders with opposite trigger method and it got triggered without any problem.

HI,

Your code works perfectly fine. It is when I'm trying to code it into my project that seems to be a problem...

It placed the StopLimit orders. The StopTriggerMethod.Trade works perfectly. It's just when I set the parameters of StopOrderTriggerMethod to StopTriggerMethod.Opposite. It would still placed the order but it would just cancel the order when it was supposed to trigger when the price hit it.

I printed null for errors. So I'm not sure what went wrong in my code..

Update:

False alarm! Your code is perfect. I've learned a ton from your help. Thank you kindly. Looks like some orders got triggered. I'm guessing it might be the slippage setting got cancelled the orders. Let's see if I can figure this out.

You are amazing! 


@mcho911