cbot not opening positions in demo account

Created at 24 Jul 2023, 18:27
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!
QC

qcwojt

Joined 12.03.2019

cbot not opening positions in demo account
24 Jul 2023, 18:27


Hi,

I have an issue with my cbot, it can open position(s) with no problem in backtest (both tick data and m1bar data) but it doesn't want to open in demo account, I've tried many currency's and random different RSI settings, still issue persist, I also checked the log, no issues reported and build code message is satisfactory, and trading hours function was not active during the test,  can you help? 

see code below, thanks 

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MyRSI : Robot
    {
        private RelativeStrengthIndex rsi;
        private int maxPositions = 1; // Maximum number of positions to be opened at once

        [Parameter("Max Positions", DefaultValue = 1)]
        public int MaxPositions
        {
            get { return maxPositions; }
            set { maxPositions = value; }
        }

        [Parameter("Take Profit (Pips)", DefaultValue = 60)]
        public int TakeProfitPips { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 30)]
        public int StopLossPips { get; set; }

        [Parameter("Use Take Profit", DefaultValue = true)]
        public bool UseTakeProfit { get; set; }

        [Parameter("Use Stop Loss", DefaultValue = true)]
        public bool UseStopLoss { get; set; }

        [Parameter("Use Break Even", DefaultValue = true)]
        public bool UseBreakEven { get; set; }

        [Parameter("RSI Periods", DefaultValue = 14)]
        public int RsiPeriods { get; set; }

        [Parameter("Volume Selection", DefaultValue = 0.1)]
        public double VolumeSelection { get; set; }

        [Parameter("Upper RSI Threshold", DefaultValue = 70)]
        public double UpperRsiThreshold { get; set; }

        [Parameter("Lower RSI Threshold", DefaultValue = 30)]
        public double LowerRsiThreshold { get; set; }

        [Parameter("Activate Upper Threshold", DefaultValue = true)]
        public bool ActivateUpperThreshold { get; set; }

        [Parameter("Activate Lower Threshold", DefaultValue = true)]
        public bool ActivateLowerThreshold { get; set; }

        [Parameter("Close On Signal Reversal", DefaultValue = false)]
        public bool CloseOnSignalReversal { get; set; }

        [Parameter("Activate Trading Hours", DefaultValue = true)]
        public bool ActivateTradingHours { get; set; }

        [Parameter("Start Hour (GMT)", DefaultValue = 8)]
        public int StartHour { get; set; }

        [Parameter("End Hour (GMT)", DefaultValue = 20)]
        public int EndHour { get; set; }
        
        [Parameter("Currency pair", DefaultValue = "EURUSD")]
        public string TradeSymbol { get; set; }

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

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, RsiPeriods);
        }

        protected override void OnBar()
        {
            if (ActivateTradingHours && !IsWithinTradingHours())
                return;

            double rsiValue = rsi.Result.Last(1); // Get RSI value for the previous closed bar

            foreach (var position in Positions)
            {
                if (position.Pips > 0)  // Skip profitable positions
                    continue;

                if (UseBreakEven)
                {
                    double breakEvenPrice;

                    if (position.TradeType == TradeType.Sell)
                    {
                        breakEvenPrice = position.EntryPrice - Symbol.PipSize;
                    }
                    else
                    {
                        breakEvenPrice = position.EntryPrice + Symbol.PipSize;
                    }

                    if ((position.TradeType == TradeType.Sell && Symbol.Bid <= breakEvenPrice) ||
                        (position.TradeType == TradeType.Buy && Symbol.Ask >= breakEvenPrice))
                    {
                        ClosePosition(position);
                    }
                }
            }

            if (ActivateUpperThreshold && rsiValue >= UpperRsiThreshold && Positions.Count < maxPositions)
            {
                ExecuteTrade(TradeType.Sell);
            }
            else if (ActivateLowerThreshold && rsiValue <= LowerRsiThreshold && Positions.Count < maxPositions)
            {
                ExecuteTrade(TradeType.Buy);
            }
            else if (CloseOnSignalReversal && Positions.Count > 0)
            {
                var lastPosition = Positions.Last();
                double prevRsiValue = rsi.Result.Last(2); // Get RSI value for the second last closed bar

                if ((lastPosition.TradeType == TradeType.Sell && prevRsiValue <= LowerRsiThreshold) ||
                    (lastPosition.TradeType == TradeType.Buy && prevRsiValue >= UpperRsiThreshold))
                {
                    ClosePosition(lastPosition);
                }
            }
        }

        private void ExecuteTrade(TradeType tradeType)
        {
            var symbolCode = SymbolName;

            var tradeParams = new TradeParams
            {
                SymbolName = symbolCode,
                TradeType = tradeType,
                Label = "RSI Trade",
                StopLossPips = UseStopLoss ? StopLossPips : 0,
                TakeProfitPips = UseTakeProfit ? TakeProfitPips : 0
            };

            var volumeInUnits = GetVolumeInUnits(symbolCode, VolumeSelection, tradeParams);

            var tradeResult = ExecuteMarketOrder(tradeParams.TradeType, tradeParams.SymbolName, volumeInUnits, tradeParams.Label, tradeParams.StopLossPips, tradeParams.TakeProfitPips);

            if (!tradeResult.IsSuccessful)
            {
                Print("Trade execution failed: " + tradeResult.Error);
            }
        }

        private double GetVolumeInUnits(string symbolCode, double volumeSelection, TradeParams tradeParams)
        {
            var symbol = Symbols.GetSymbol(symbolCode);
            var volumeInUnits = symbol.NormalizeVolumeInUnits(volumeSelection);

            if (symbolCode == "XAUUSD")
            {
                // Adjust volume for XAUUSD symbol
                var unitToVolumeFactor = 0.1; // Conversion factor from unit to volume

                volumeInUnits *= unitToVolumeFactor;
            }
            else if (symbolCode == "XAGUSD")
            {
                // Adjust volume for XAGUSD symbol
                var unitToVolumeFactor = 1.0; // Conversion factor from unit to volume

                volumeInUnits *= unitToVolumeFactor;
            }
            else if (symbolCode == "XTIUSD")
            {
                // Adjust volume for XTIUSD symbol
                var unitToVolumeFactor = 50.0; // Conversion factor from unit to volume

                volumeInUnits *= unitToVolumeFactor;
            }
            else
            {
                // Forex instruments
                var desiredVolume = volumeSelection * ForexVolume;

                return desiredVolume;
            }

            return symbol.QuantityToVolumeInUnits(volumeInUnits);
        }

        private bool IsWithinTradingHours()
        {
            var currentHour = Server.Time.Hour;

            if (StartHour < EndHour)
            {
                return currentHour >= StartHour && currentHour <= EndHour;
            }
            else if (StartHour > EndHour)
            {
                return currentHour >= StartHour || currentHour <= EndHour;
            }
            else
            {
                return true; // Trading is active all day
            }
        }

        private class TradeParams
        {
            public string SymbolName { get; set; }
            public TradeType TradeType { get; set; }
            public string Label { get; set; }
            public int StopLossPips { get; set; }
            public int TakeProfitPips { get; set; }
        }
    }
}


@qcwojt