Trailing Stoploss

Created at 13 May 2019, 22:49
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!
RY

ryan.a.blake

Joined 28.01.2019

Trailing Stoploss
13 May 2019, 22:49


Hi,

I have a trailing stop-loss within my Cbot, however recently it has not been working. Not sure whether this was due to an update for the trading platform. Any ideas as to what could have caused this? 


@ryan.a.blake
Replies

ryan.a.blake
13 May 2019, 22:51

My code is below.

 

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.UTC, AccessRights = AccessRights.None)]
    public class MACbot : Robot
    {
        private DateTime _stopTime;
        private DateTime _startTime;

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double StartTime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 17.3)]
        public double StopTime { get; set; }

        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

        [Parameter("Lot Size", DefaultValue = 0.01)]
        public double lotsize { get; set; }

        [Parameter("Source #1")]
        public DataSeries Source1 { get; set; }

        [Parameter("Source #2")]
        public DataSeries Source2 { get; set; }

        [Parameter("Period #1", DefaultValue = 1, MinValue = 1, MaxValue = 100)]
        public int Period1 { get; set; }

        [Parameter("Period #2", DefaultValue = 2, MinValue = 1, MaxValue = 100)]
        public int Period2 { get; set; }

        [Parameter("Loss", DefaultValue = 50)]
        public double loss { get; set; }

        [Parameter("TakeProfitPips", DefaultValue = 10)]
        public int TP { get; set; }

        [Parameter("StopLossPips", DefaultValue = 10, MinValue = 0)]
        public int SL { get; set; }

        [Parameter("Trigger ", DefaultValue = 20)]
        public int Trigger { get; set; }

        [Parameter("Trailing", DefaultValue = 10)]
        public int Trailing { get; set; }

        private SimpleMovingAverage _sma1 { get; set; }
        private SimpleMovingAverage _sma2 { get; set; }

        protected override void OnStart()
        {
            // 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);

            _sma1 = Indicators.SimpleMovingAverage(Source1, Period1);
            _sma2 = Indicators.SimpleMovingAverage(Source2, Period2);
        }
        protected override void OnTick()
        {
            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 (_sma1.Result.Last(2) > _sma2.Result.Last(2) && (_sma2.Result.Last(1) < _sma1.Result.Last(1)))

                if (Positions.Count(x => x.TradeType == TradeType.Buy) == 0)
                {

                    double volume = Symbol.QuantityToVolumeInUnits(lotsize);

                    ExecuteMarketOrder(TradeType.Buy, Symbol, volume, InstanceName, SL, TP);

                    ClosePosition(TradeType.Sell);
                }
            if (_sma1.Result.Last(2) < _sma2.Result.Last(2) && (_sma2.Result.Last(1) > _sma1.Result.Last(1)))

                if (Positions.Count(x => x.TradeType == TradeType.Sell) == 0)
                {
                    {
                        double volume = Symbol.QuantityToVolumeInUnits(lotsize);

                        ExecuteMarketOrder(TradeType.Sell, Symbol, volume, InstanceName, SL, TP);

                        ClosePosition(TradeType.Buy);
                    }
                }
        }
        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName, Symbol, type);

            if (p != null)
            {
                ClosePosition(p);
            }

            if (Account.Balance <= loss)
                Stop();

            TRAILING();
        }
        private void TRAILING()
        {
            if (Trailing > 0 && Trigger > 0)
            {

                Position[] positions = Positions.FindAll(InstanceName, 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);
                            }
                        }
                    }
                }
            }
        }
    }
}


@ryan.a.blake

PanagiotisCharalampous
14 May 2019, 09:19

Hi ryan.a.blake,

Can you please explain to us what do you mean when you say it is not working. What does it do and what did you expect it to do instead?

Best Regards,

Panagiotis


@PanagiotisCharalampous

ryan.a.blake
14 May 2019, 10:17

Hi,

Previously the Cbot would set a stoploss and when price moved into profit and reached a specified pip amount (Trigger) the stoploss would move to the trailing distance specified in the parameters. However recently this has not been the case. A stoploss is placed but when price moves into profit and reaches the trigger amount of pips, the stoploss then does not trail behind as expected. Is this due to a recent upgrade to the platform, and i now need to alter some of the code to suit?

Kind regards.


@ryan.a.blake

ryan.a.blake
15 May 2019, 00:15

Apologies, looking back i had pasted the wrong code.

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.UTC, AccessRights = AccessRights.None)]
    public class EnvelopeCbot : Robot
    {
        private DateTime _stopTime;
        private DateTime _startTime;

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double StartTime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 17.3)]
        public double StopTime { get; set; }

        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

        [Parameter("Lot Size", DefaultValue = 0.01)]
        public double lotsize { get; set; }

        [Parameter("Loss", DefaultValue = 50)]
        public double loss { get; set; }

        [Parameter("TakeProfitPips", DefaultValue = 10)]
        public int TP { get; set; }

        [Parameter("StopLossPips", DefaultValue = 10, MinValue = 0)]
        public int SL { get; set; }

        [Parameter("Trigger When Gaining", DefaultValue = 1)]
        public double Trigger { get; set; }

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


        [Parameter("Band Distance", DefaultValue = 0.07)]
        public double band { get; set; }

        [Parameter("Envelope Period", DefaultValue = 20)]
        public int period { get; set; }

        [Parameter("MAType")]
        public int matype { get; set; }


        private Envelopes _env { get; set; }

 

        protected override void OnStart()
        {

            _env = Indicators.GetIndicator<Envelopes>(period, band, matype);

        }


        protected override void OnTick()
        {

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

            if (!tradeTime)
                return;

            if ((MarketSeries.Close.LastValue > _env.ChannelUp.Last(1)))


                if (Positions.Count(x => x.TradeType == TradeType.Buy) == 0)
                {

                    double volume = Symbol.QuantityToVolumeInUnits(lotsize);

                    ExecuteMarketOrder(TradeType.Buy, Symbol, volume, InstanceName, SL, TP, null);

                    ClosePosition(TradeType.Sell);
                }
            if ((MarketSeries.Close.LastValue < _env.ChannelLow.Last(1)))

                if (Positions.Count(x => x.TradeType == TradeType.Sell) == 0)
                {
                    {
                        double volume = Symbol.QuantityToVolumeInUnits(lotsize);

                        ExecuteMarketOrder(TradeType.Sell, Symbol, volume, InstanceName, SL, TP, null);

                        ClosePosition(TradeType.Buy);
                    }
                }
        }

        private void ExecuteMarketOrder(TradeType buy, Symbol symbol, double volume, string instanceName, string v, int sL, int tP, object p)
        {
            throw new NotImplementedException();
        }

        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName, Symbol, type);

            if (p != null)
            {
                ClosePosition(p);
            }

            if (Account.Balance <= loss)
                Stop();
        }
        private void TRAILING()
        {
            if (Trailing > 0 && Trigger > 0)
            {

                Position[] positions = Positions.FindAll(InstanceName, 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);
                            }
                        }
                    }
                }
            }
        }
    }
}

 


@ryan.a.blake

PanagiotisCharalampous
15 May 2019, 09:22

Hi ryan.a.blake,

TRAILING() method is not called anywhere in the cBot.

Best Regards,

Panagiotis


@PanagiotisCharalampous

ryan.a.blake
15 May 2019, 10:14

RE:

 

I see, I believe I have now fixed the problem. Thankyou for your assistance.


@ryan.a.blake