Back testing and cross is detected

Created at 24 Jul 2024, 17:43
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!
CT

ctid5962378

Joined 22.05.2023

Back testing and cross is detected
24 Jul 2024, 17:43


Good day 

I'm building a bot and using the EMA 50 and EMA 200 as indicators and the bot is meant to execute a buy and sell trade in each of these instances but for some reason its not doing this at each cross over . I added some tolerances to it but I still get the same result, see log

 29/06/2023 00:00:00.000 | Info | CBot instance [The Black Bull Bot 2, EURUSD, h1] started.
29/06/2023 00:00:00.000 | Info | Bot started
29/06/2023 01:00:00.000 | Info | Short MA: 1.0928706820259801, Long MA: 1.0931338494975544
29/06/2023 01:00:00.000 | Info | Previous Short MA: 1.0929600976188774, Previous Long MA: 1.0931585113015498
29/06/2023 01:00:00.000 | Info | No crossover detected
29/06/2023 02:00:00.000 | Info | Short MA: 1.09278132040866, Long MA: 1.093108542512628
29/06/2023 02:00:00.000 | Info | Previous Short MA: 1.0928687212416666, Previous Long MA: 1.0931333519851165

see copy of code 

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

namespace cAlgo.Robots
{
   [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
   public class MovingAverageCrossoverBot : Robot
   {
       [Parameter("Short Period", DefaultValue = 50)]
       public int ShortPeriod { get; set; }

       [Parameter("Long Period", DefaultValue = 200)]
       public int LongPeriod { get; set; }

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

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

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

       [Parameter("Crossover Tolerance", DefaultValue = 0.0001, MinValue = 0.00001)]
       public double CrossoverTolerance { get; set; }

       private MovingAverage shortMA;
       private MovingAverage longMA;

       protected override void OnStart()
       {
           shortMA = Indicators.MovingAverage(Bars.ClosePrices, ShortPeriod, MovingAverageType.Exponential);
           longMA = Indicators.MovingAverage(Bars.ClosePrices, LongPeriod, MovingAverageType.Exponential);
           Print("Bot started");
       }

       protected override void OnBar()
       {
           // Skip execution on Fridays
           if (Server.Time.DayOfWeek == DayOfWeek.Friday)
           {
               Print("Skipping trades on Friday");
               return;
           }

           int lastIndex = Bars.ClosePrices.Count - 1;
           if (lastIndex < 1)
           {
               Print("Not enough data points");
               return; // Ensure we have enough data points
           }

           double shortMAValue = shortMA.Result[lastIndex];
           double longMAValue = longMA.Result[lastIndex];
           double prevShortMAValue = shortMA.Result[lastIndex - 1];
           double prevLongMAValue = longMA.Result[lastIndex - 1];

           Print("Short MA: {0}, Long MA: {1}", shortMAValue, longMAValue);
           Print("Previous Short MA: {0}, Previous Long MA: {1}", prevShortMAValue, prevLongMAValue);

           // Check for crossover with tolerance
           if (prevShortMAValue <= prevLongMAValue - CrossoverTolerance && shortMAValue > longMAValue + CrossoverTolerance)
           {
               // Buy signal
               Print("Buy signal detected at {0}", Bars[lastIndex].Close);
               ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, "MovingAverageCrossoverBot", StopLoss, TakeProfit);
           }
           else if (prevShortMAValue >= prevLongMAValue + CrossoverTolerance && shortMAValue < longMAValue - CrossoverTolerance)
           {
               // Sell signal
               Print("Sell signal detected at {0}", Bars[lastIndex].Close);
               ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, "MovingAverageCrossoverBot", StopLoss, TakeProfit);
           }
           else
           {
               Print("No crossover detected");
           }
       }

       protected override void OnStop()
       {
           Print("Bot stopped");
       }
   }
}


@ctid5962378
Replies

PanagiotisCharalampous
25 Jul 2024, 05:39

Hi there,

An obvious problem in your code is that you are using the current open bar's value for your checks. This value can change by the time the bar closes therefore this can lead to false or missing signals. You should only check closed bar values. Try the below instead

           double shortMAValue = shortMA.Result[lastIndex - 1];
           double longMAValue = longMA.Result[lastIndex - 1];
           double prevShortMAValue = shortMA.Result[lastIndex - 2];
           double prevLongMAValue = longMA.Result[lastIndex - 2];

Best regards,

Panagiotis


@PanagiotisCharalampous