Trailing Stop Order (not stop loss)

Created at 20 Dec 2017, 14:02
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!
97

9718853

Joined 14.10.2014

Trailing Stop Order (not stop loss)
20 Dec 2017, 14:02


Hi,

I'd like to place a stop order below the current market price (for long trades) and trail it at a certain distance in anticipation for a retracement to enter the trade.

Is this possible?

 

Many thanks in advance, Ian...


@9718853
Replies

PanagiotisCharalampous
20 Dec 2017, 15:19

Dear Trader,

If you want to place a Buy pending order below the current market price, you need to place a Limit Order. Buy Stop orders cannot be placed below the market price. If you want to implement trailing of the order based on price movement, you can have a look at ModifyPendingOrder function and use it to modify the order accordingly on each tick. 

Let me know if the above information helps you.

Best Regards,

Panagiotis


@PanagiotisCharalampous

Drummond360
22 Dec 2017, 13:18

What if you want to place a sell order below the current price? Would that be a StopOrder?

and would you still use ModifyPendingOrder to trail it onTick?


@Drummond360

PanagiotisCharalampous
22 Dec 2017, 14:42

RE:

Drummond360 said:

What if you want to place a sell order below the current price? Would that be a StopOrder?

and would you still use ModifyPendingOrder to trail it onTick?

Hi Drummond360,

The answer to both of your questions is yes.

Best Regards,

Panagiotis


@PanagiotisCharalampous

Drummond360
22 Dec 2017, 15:07

RE: RE:

Thank you for such a quick reply, much appreciated...

My current code, below, is clearly flawed as I'm having to define the long and short target price... Can anyone help me define a single target price based on TradeType?

 

 

   var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize;
            var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize;
           


            foreach (var order in PendingOrders)
            {
                if (order.StopLossPips == null)
                    ModifyPendingOrder(order, buyOrderTargetPrice, order.StopLoss, order.TakeProfit, Server.Time.AddMinutes(Duration));
             
            }

 

Many thanks in adavance,

Drummond360


@Drummond360

Drummond360
22 Dec 2017, 23:00

This is my best effort so far:

 

  var targetPrice = (order.TradeType == TradeType.Buy) ? Symbol.Ask + PipsAway * Symbol.PipSize : (order.TradeType == TradeType.Sell) ? Symbol.Bid - PipsAway * Symbol.PipSize:

 

It doesn't work as I'm such a programming newb, however I do feel like it gets the point acorss as to what I'm trying to achieve! Any pointers would be greatly appreciated...

 


@Drummond360

PanagiotisCharalampous
27 Dec 2017, 14:13

Hi Drummond360,

The correct way to write the condition is the following

 var targetPrice = (order.TradeType == TradeType.Buy) ? Symbol.Ask + PipsAway * Symbol.PipSize : Symbol.Bid - PipsAway * Symbol.PipSize;

Best Regards,

Panagiotis


@PanagiotisCharalampous

Drummond360
30 Dec 2017, 15:35

That's great thank you very much for your time... : )


@Drummond360

Drummond360
04 Jan 2018, 14:12

This code isn't working, can you please advise on my mistake?

Is it possible to make the order.TargetPrice respect the variable targetPrice?

    foreach (var order in PendingOrders)
            {
                var targetPrice = (order.TradeType == TradeType.Buy) ? Symbol.Ask + PipsAway * Symbol.PipSize : Symbol.Bid - PipsAway * Symbol.PipSize;

                if (order.StopLossPips == null)

                    ModifyPendingOrder(order, targetPrice, order.StopLoss, order.TakeProfit, Server.Time.AddMinutes(Duration));
                Print("MODIFYING PENDING ORDER target price is " + order.TargetPrice + " targetPrice Variable result =  " + targetPrice + " order ID = " + order.Id);
            }

Any help would be greatley appreciated...


@Drummond360

PanagiotisCharalampous
04 Jan 2018, 15:04

Hi Drummond360,

Is it possible to post the full code of the cBot? It will be easier to advise you if we have the full cBot code.

Best Regards,

Panagiotis


@PanagiotisCharalampous

Drummond360
04 Jan 2018, 16:40

Thank you Panagiotis, here's the code

 

using System;
using System.Linq;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Requests;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Scalper : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Pips Away", DefaultValue = 1, MinValue = 1)]
        public int PipsAway { get; set; }

        [Parameter("Initial Pips Away", DefaultValue = 1, MinValue = 1)]
        public int InitialPipsAway { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 100, MinValue = 1)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 25, MinValue = 1)]
        public int TakeProfit { get; set; }

        //[Parameter("Volume", DefaultValue = 10000, MinValue = 1000)]
        //public int Volume { get; set; }


        [Parameter("Order Duration", DefaultValue = 5, MinValue = 1)]
        public int Duration { get; set; }

        [Parameter("Risk % on A/C: 1 = 1 mini lot on £10K", DefaultValue = 1, MinValue = 0.1, MaxValue = 100)]
        public double risk { get; set; }


        [Parameter("Trailing Stop Loss Distance", DefaultValue = 10)]
        public double TrailingStopLossDistance { get; set; }

        public int Count { get; set; }

        Dictionary<int, int> dic = new Dictionary<int, int>();
        string label = "Scalper";

        protected override void OnStart()
        {


        }
        private void ExecuteOrder(int volume, TradeType tradeType)
        {
            ExecuteMarketOrder(tradeType, Symbol, volume, label, StopLoss, TakeProfit);
        }
        protected override void OnTick()
        {
            var longPosition = Positions.Find(label, Symbol, TradeType.Buy);
            var shortPosition = Positions.Find(label, Symbol, TradeType.Sell);
            var totalOrders = PendingOrders.Count;
            var sellOrderTargetPrice = Symbol.Bid - InitialPipsAway * Symbol.PipSize;
            var buyOrderTargetPrice = Symbol.Ask + InitialPipsAway * Symbol.PipSize;
            var smartVolume = Symbol.NormalizeVolume(risk * Account.Balance, RoundingMode.Down);


            if (shortPosition == null && totalOrders < 1)
            {
                PlaceStopOrder(TradeType.Sell, Symbol, smartVolume, sellOrderTargetPrice, label, StopLoss, TakeProfit, Server.Time.AddMinutes(Duration));

            }

            if (longPosition == null && totalOrders < 1)
            {
                PlaceStopOrder(TradeType.Buy, Symbol, smartVolume, buyOrderTargetPrice, label, StopLoss, TakeProfit, Server.Time.AddMinutes(Duration));

            }


            // Once orders are placed they trail the spot price by 1 pip awaitng the price reversal
            foreach (var order in PendingOrders)
            {
                var targetPrice = (order.TradeType == TradeType.Buy) ? Symbol.Ask - PipsAway * Symbol.PipSize : Symbol.Bid + PipsAway * Symbol.PipSize;

                if (order.StopLossPips == null)

                    ModifyPendingOrder(order, targetPrice, order.StopLoss, order.TakeProfit, Server.Time.AddMinutes(Duration));
                Print("MODIFYING PENDING ORDER target price is " + order.TargetPrice + " targetPrice Variable result =  " + targetPrice + " ...order ID = " + order.Id + " ...Pips away Value = " + PipsAway + " ...PipsAway*SymbolPipsize = " + PipsAway * Symbol.PipSize);
            }

            // Once a position is open it is indexed to be managed individually
            var symbolSearch = Positions.FindAll(label, Symbol);

            int posCount = Positions.Count;

            foreach (Position position in symbolSearch)

                for (int y = posCount - 1; y >= 0; y--)
                {
                    int totalPips = (int)(Positions[y].Pips);

                    int test = 0;
                    if (!dic.TryGetValue(Positions[y].Id, out test))
                    {
                        dic[Positions[y].Id] = 0;
                    }

                    //If a position enters a profit of 1 pip or more then start trailing the stop loss
                    if (totalPips >= 0.001)

                        //Based on the position's direction, we calculate the new stop loss price and we modify the position
                        // Using Symbol.PipSize instead of Symbol.PipValue seems the correct logic but is less profitable! What calculation is actually happening here?!?!

                        if (Positions[y].TradeType == TradeType.Buy)
                        {
                            var newSLprice = Symbol.Ask - (Symbol.PipValue * TrailingStopLossDistance);
                            if (newSLprice > Positions[y].StopLoss)
                            {
                                ModifyPosition(Positions[y], newSLprice, null);
                            }
                        }
                        else
                        {
                            var newSLprice = Symbol.Bid + (Symbol.PipValue * TrailingStopLossDistance);
                            if (newSLprice < Positions[y].StopLoss)
                            {
                                ModifyPosition(Positions[y], newSLprice, null);

                            }
                        }
                }
        }
    }
}






 


@Drummond360

PanagiotisCharalampous
04 Jan 2018, 16:52

Hi Drummond360,

Thanks for the code. Can you please explain what is the purpose of the following line of code is

   if (order.StopLossPips == null)

From what I see you always specify a stop loss, therefore

 if (order.StopLossPips == null) 
    ModifyPendingOrder(order, targetPrice, order.StopLoss, order.TakeProfit, Server.Time.AddMinutes(Duration));              

will never execute.

Best Regards,

Panagiotis


@PanagiotisCharalampous

Drummond360
04 Jan 2018, 17:03

Thank you Panagiotis...

Yes I did think about that conflict. The code is from one of the sample snippets on this forum..

After deleting that if statement it seems to be working, I'll keep testing...

Thanks again...

 


@Drummond360