Trailing Stoploss

13 May 2019, 22:49Trailing Stoploss#1
ryan.a.blakeposts: 20since: 28 Jan 2019

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? 

13 May 2019, 22:51#2
ryan.a.blakeposts: 20since: 28 Jan 2019

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);
                            }
                        }
                    }
                }
            }
        }
    }
}

14 May 2019, 09:19#3
Panagiotis Charalampousposts: 2978since: 13 Jan 2017

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


Head of Community Management at cTrader
14 May 2019, 10:17#4
ryan.a.blakeposts: 20since: 28 Jan 2019

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.

15 May 2019, 00:15#5
ryan.a.blakeposts: 20since: 28 Jan 2019

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);
                            }
                        }
                    }
                }
            }
        }
    }
}

 

15 May 2019, 09:22#6
Panagiotis Charalampousposts: 2978since: 13 Jan 2017

Hi ryan.a.blake,

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

Best Regards,

Panagiotis


Head of Community Management at cTrader
15 May 2019, 10:14RE:#7
ryan.a.blakeposts: 20since: 28 Jan 2019

 

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