Adding a Trailing stop

Created at 27 Nov 2020, 13:57
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!
DE

Depugno

Joined 27.11.2020

Adding a Trailing stop
27 Nov 2020, 13:57


Hi together, i tried to set a trailing stop to this bot. but it doesn't work and i don't know why.

Is anyone able to fix this? The bot has good results in backtesting and i think with a trailing stop it could be nice.

thx for your help

 

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.None)]
    public class Gerbil : Robot
    {
        [Parameter("Start Hour", DefaultValue = 10.0)]
        public double StartTime { get; set; }
        [Parameter("Stop Hour", DefaultValue = 12.0)]
        public double StopTime { get; set; }
        [Parameter("Take Profit (Pips)", DefaultValue = 6, MinValue = 1, Step = 1)]
        public int TakeProfit { get; set; }
        [Parameter("Stop Loss (Pips)", DefaultValue = 150, MinValue = 1, Step = 1)]
        public int StopLoss { get; set; }
        [Parameter("trigger ", DefaultValue = 20)]
        public int Trigger { get; set; }
        [Parameter("Trailing", DefaultValue = 10)]
        public int Trailing { get; set; }
        [Parameter("Calculate Volume by Percentage?", DefaultValue = false)]
        public bool RiskPercent { get; set; }
        [Parameter("Quantity (%Risk or Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }
        [Parameter("RSI Source")]
        public DataSeries RSISource { get; set; }
        [Parameter("RSI Period", DefaultValue = 7, MinValue = 1, Step = 1)]
        public int RSIPeriods { get; set; }
        [Parameter("RSI Overbought Level", DefaultValue = 80, MinValue = 1, Step = 1)]
        public int RSIOverB { get; set; }
        [Parameter("RSI Oversold Level", DefaultValue = 40, MinValue = 1, Step = 1)]
        public int RSIOverS { get; set; }
        [Parameter("ATR Periods", DefaultValue = 15, MinValue = 1, Step = 1)]
        public int ATRPeriods { get; set; }
        [Parameter("ATR From", DefaultValue = 10, MinValue = 1, Step = 1)]
        public int ATRFrom { get; set; }
        [Parameter("ATR To", DefaultValue = 100, MinValue = 1, Step = 1)]
        public int ATRTo { get; set; }
        [Parameter("Max Positions", DefaultValue = 1, MinValue = 1, Step = 1)]
        public int MaxPos { get; set; }
        [Parameter("Max DD Positions", DefaultValue = 0, MinValue = 0, Step = 1)]
        public int MaxDDPos { get; set; }
        [Parameter("KillHours", DefaultValue = 0, MinValue = 0, Step = 1)]
        public int KillHours { get; set; }

        private DateTime _startTime;
        private DateTime _stopTime;
        private RelativeStrengthIndex rsi;
        private AverageTrueRange atr;
        private int DDPos = 0;
        private const string label = "SampleRSI";

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(RSISource, RSIPeriods);
            atr = Indicators.AverageTrueRange(ATRPeriods, MovingAverageType.Simple);
            {
                // Start Time is the same day at 22:00:00 Server Time
                _startTime = Server.Time.Date.AddHours(StartTime);

                // Stop Time is the next day at 06:00:00
                _stopTime = Server.Time.Date.AddHours(StopTime);

                Print("Start Time {0},", _startTime);
                Print("Stop Time {0},", _stopTime);
            }
        }
        protected override void OnBar()
        {
            if (Trade.IsExecuting)
                return;

            var currentHours = Server.Time.TimeOfDay.TotalHours;
            bool tradeTime = StartTime < StopTime ? currentHours > StartTime && currentHours < StopTime : currentHours < StopTime || currentHours > StartTime;

            if (!tradeTime)
                return;

            if (Positions.Count != 0)
                return;
            {
                var atrVal = atr.Result.LastValue * 100000;
                if (atrVal > ATRFrom && atrVal < ATRTo)
                {
                    if (Positions.Count < MaxPos)
                    {
                        if (rsi.Result.LastValue < RSIOverS)
                        {
                            Open(TradeType.Buy);
                        }
                        else if (rsi.Result.LastValue > RSIOverB)
                        {
                            Open(TradeType.Sell);
                        }
                    }
                }
            }
            if (KillHours != 0)
            {
                foreach (var position in Positions.FindAll("SampleRSI", Symbol))
                {
                    if (Time > position.EntryTime.AddMinutes(KillHours * 60))
                        ClosePosition(position);
                }
            }
        }


        private void Open(TradeType tradeType)
        {
            //var position = Positions.Find("SampleRSI", Symbol, tradeType);
            var volumeInUnits = CalculateVolume();

            ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, "SampleRSI", StopLoss, TakeProfit);
        }
        private void TRAILING()
        {
            if (Trailing > 0 && Trigger > 0)
            {

                Position[] positions = Positions.FindAll(label, Symbol);

                foreach (Position position in positions)
                {

                    if (position.TradeType == TradeType.Sell)
                    {

                        double distance = position.EntryPrice - Symbol.Ask;

                        if (distance >= Trigger * Symbol.PipSize)
                        {

                            double newStopLossPrice = Symbol.Ask + Trailing * Symbol.PipSize;

                            if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
                            {

                                ModifyPosition(position, newStopLossPrice, position.TakeProfit);

                            }
                        }
                    }

                    else
                    {

                        double distance = Symbol.Bid - position.EntryPrice;

                        if (distance >= Trigger * Symbol.PipSize)
                        {

                            double newStopLossPrice = Symbol.Bid - Trailing * Symbol.PipSize;

                            if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
                            {

                                ModifyPosition(position, newStopLossPrice, position.TakeProfit);

                            }
                        }
                    }
                }
            }
        }




        double CalculateVolume()
        {
            if (!RiskPercent)
            {
                return (Symbol.QuantityToVolumeInUnits(Quantity));
            }
            else
            {
                // Calculate the total risk allowed per trade.
                double riskPerTrade = (Account.Balance * Quantity) / 100;
                double totalSLPipValue = (StopLoss + Symbol.Spread) * Symbol.PipValue;
                double calculatedVolume = riskPerTrade / totalSLPipValue;

                double normalizedCalculatedVolume = Symbol.NormalizeVolumeInUnits(calculatedVolume, RoundingMode.ToNearest);
                return normalizedCalculatedVolume;
            }
        }


    }
}


@Depugno
Replies

firemyst
29 Nov 2020, 09:57

How did you "try" adding a trailing stop loss?

The simple way to do it is:

 position.ModifyTrailingStop(true);

or

 position.ModifyTrailingStop(false);

 

 

 


@firemyst