How to Stop the cBot after each Trade

Created at 24 May 2022, 10:24
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!
ST

steel.export

Joined 19.01.2021

How to Stop the cBot after each Trade
24 May 2022, 10:24


Dear Mr. Ahmad,

Below is the code for SuperTrend Reference cBot, it Continuously executes Buy and Sell Trades as per SuperTrend Indicator. Kindly advise how to change the code so that it stops after each trade, and does not enter the next trade continuously.

Thanks & Regards,

Altaf

 

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {

        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }


        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;


        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }


            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;

        }

        protected override void OnTick()
        {

            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;

            }
        }

        protected override void OnBar()
        {

            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }

        }
        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);
            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);
                OnStop();
            }
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
            }
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }


        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;

        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }


            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

 


@steel.export
Replies

amusleh
24 May 2022, 10:42

Hi,

What do you mean by stop? do you mean stopping the cBot itself?


@amusleh

steel.export
24 May 2022, 10:53

RE: How to Stop the cBot after each Trade

amusleh said:

Hi,

What do you mean by stop? do you mean stopping the cBot itself?

Dear Mr. Ahmad,

Thanks for your prompt reply.

Yes, Stopping the cBot itself after each trade.

Thanks & Regards,

Altaf


@steel.export

amusleh
24 May 2022, 11:16

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {
        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }

        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;

        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }

            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;
        }

        protected override void OnTick()
        {
            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;
            }
        }

        protected override void OnBar()
        {
            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }
        }

        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);

            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);
            }

            Stop();
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
            }
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }

        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;
        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }

            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

 


@amusleh

steel.export
24 May 2022, 11:59

RE: How to Stop the cBot after each Trade

amusleh said:

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {
        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }

        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;

        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }

            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;
        }

        protected override void OnTick()
        {
            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;
            }
        }

        protected override void OnBar()
        {
            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }
        }

        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);

            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);
            }

            Stop();
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
            }
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }

        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;
        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }

            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

 

Dear Mr. Ahmed,

Thanks for your reply.

In the code you have sent the Robot Stops as soon as it starts the Trade and we have to Stop the Trade manually.

But I want to start the Robot Manually and it will Stop Automatically after it finishes the trade as per the SuperTrent Indicator (that means It stops Automatically when the Trend is over). And it does not start a new Trade in opposite direction. So we can manually start the Robot for next Trade.

Thanks & Best Regards,

Altaf


@steel.export

amusleh
24 May 2022, 12:43

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {
        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }

        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;

        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }

            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;
        }

        protected override void OnTick()
        {
            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;
            }
        }

        protected override void OnBar()
        {
            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }
        }

        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);

            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);

                OnStop();
            }
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
            }

            Stop();
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }

        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;
        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }

            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

 


@amusleh

steel.export
24 May 2022, 14:28

RE: How to Stop the cBot after each Trade

amusleh said:

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {
        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }

        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;

        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }

            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;
        }

        protected override void OnTick()
        {
            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;
            }
        }

        protected override void OnBar()
        {
            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }
        }

        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);

            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);

                OnStop();
            }
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
            }

            Stop();
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }

        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;
        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }

            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

 

Dear Mr. Ahmad,

Thanks for your reply.

In the code you have sent the cBot is not executing any trade and is Stopping without executing any trade.

Thanks & Best Regards,

Altaf


@steel.export

amusleh
24 May 2022, 15:33

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {
        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }

        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;

        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }

            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;
        }

        protected override void OnTick()
        {
            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;
            }
        }

        protected override void OnBar()
        {
            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }
        }

        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);

            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);

                OnStop();
            }
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            bool isClosed = false;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
                else
                {
                    isClosed = true;
                }
            }
            
            if (isClosed)
            {
                Stop();
            }
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }

        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;
        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }

            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

I don't have the referenced indicator inside your cBot so I can't test it.


@amusleh

steel.export
24 May 2022, 16:17

RE:

amusleh said:

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperTrendReference_cBot : Robot
    {
        [Parameter(DefaultValue = "SuperTrendReference_cBot")]
        public string cBotLabel { get; set; }

        [Parameter("Serial Key", DefaultValue = "12")]
        public string SerialKey { get; set; }

        [Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
        public double Lots { get; set; }

        [Parameter("Martingale - Yes/No:", DefaultValue = true)]
        public bool UseMartingale { get; set; }

        [Parameter("Multiplication Factor:", DefaultValue = 1.5)]
        public double MultiplicationFactor { get; set; }

        [Parameter("Tolerance - Yes/No:", DefaultValue = true)]
        public bool UseTolerance { get; set; }

        [Parameter("Tolerance in pips:", DefaultValue = 10.0)]
        public double TolerancePips { get; set; }

        [Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
        public int ST_Period { get; set; }

        [Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
        public double ST_atrMulti { get; set; }

        [Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ST_AtrSource { get; set; }

        [Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
        public int StartTimeHour { get; set; }

        [Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int StartTimeMinute { get; set; }

        [Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
        public int EndTimeHour { get; set; }

        [Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
        public int EndTimeMinute { get; set; }

        [Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
        public double MaxDDPrct { get; set; }

        [Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
        public bool UseCoffeeBreak { get; set; }

        [Parameter("Profit:", DefaultValue = 500.0)]
        public double CBProfit { get; set; }

        [Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
        public int SignalBar { get; set; }

        private SuperTrendExperto SuperTrend_;
        private double currentTradeLots;

        private DateTime StartTimeHour_;
        private DateTime EndTimeHour_;
        private DateTime StartTimeMinute_;
        private DateTime EndTimeMinute_;

        private double InitialDDAccountBalance;
        private double CurrentClosedPosBal;

        protected override void OnStart()
        {
            if (SerialKey != "0")
            {
                Print("Serial Key is NOT valid!");
                Stop();
            }

            SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);

            if (UseMartingale == true)
            {
                currentTradeLots = Lots;
            }

            StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
            EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
            StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
            EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);

            InitialDDAccountBalance = Account.Balance;
            CurrentClosedPosBal = 0.0;
        }

        protected override void OnTick()
        {
            if (IsReach_DDPrct(MaxDDPrct) == true)
            {
                CloseAllPositions(TradeType.Buy);
                CloseAllPositions(TradeType.Sell);

                Print("DD is Hit!");
                InitialDDAccountBalance = Account.Balance;
                CurrentClosedPosBal = 0.0;
            }
        }

        protected override void OnBar()
        {
            if (IsTradingHours() == true)
            {
                if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
                {
                    CloseAllPositions(TradeType.Sell);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Sell);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Buy, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Buy, Lots);
                }
                else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
                {
                    CloseAllPositions(TradeType.Buy);
                    if (UseMartingale == true)
                        UpdateTradeVolume(TradeType.Buy);
                    if (UseMartingale == true)
                        OpenMarketOrder(TradeType.Sell, currentTradeLots);
                    else
                        OpenMarketOrder(TradeType.Sell, Lots);
                }
            }
        }

        private void OpenMarketOrder(TradeType tradeType, double dLots)
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
            volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);

            //in final version need add attempts counter
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);

            if (!result.IsSuccessful)
            {
                Print("Execute Market Order Error: {0}", result.Error.Value);

                OnStop();
            }
        }

        private int CalculatePositionsQnty(TradeType tradeType)
        {
            return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
        }

        private void CloseAllPositions(TradeType tradeType)
        {
            bool isClosed = false;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
            {
                var result = ClosePosition(position);
                if (!result.IsSuccessful)
                {
                    Print("Closing market order error: {0}", result.Error);
                }
                else
                {
                    isClosed = true;
                }
            }
            
            if (isClosed)
            {
                Stop();
            }
        }

        private bool IsReach_DDPrct(double DDPrctValue)
        {
            return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
        }

        private double CalculatePL()
        {
            double CurrentPL = 0.0;
            foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
            {
                CurrentPL += position.NetProfit;
            }
            return CurrentPL;
        }

        private bool IsTradingHours()
        {
            var currentTimeHour = Server.Time.TimeOfDay.Hours;
            var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
            if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
                return true;

            return false;
        }

        private void UpdateTradeVolume(TradeType tradeType)
        {
            RefreshData();
            HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
            if (lastClosedPosition == null)
                return;
            CurrentClosedPosBal += lastClosedPosition.NetProfit;

            if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
            {
                currentTradeLots = Lots;
            }
            else
            {
                if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
                {
                    currentTradeLots *= MultiplicationFactor;
                }
                else
                {
                    //same lot size
                }
            }

            if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
            {
                Print("Coffee Break is Hit!");
                Stop();
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

I don't have the referenced indicator inside your cBot so I can't test it.

Dear Mr. Ahmad,

It is working correctly. Thanks a lot for your help.

Thanks & Regards,

Altaf


@steel.export