How to backtest EA based on multiple timeframes

Hi, I am trying to generate a trading strategy based on RSIs across different timeframes, however, there seems to be some issues when I backtest it. The EA doesn’t seem to interact properly with the RSIs from different timeframes. For example, when I select “H1” and “M30” in “Period” in Strategy Tester, it returns completely different backtest results (different numbers of trades, different pnl, etc) for the data during the same time period (e.g. from July 2018 to August 2018), and when I look at the historical records, the trades were placed not according to my trade logic. Can someone help me fix this issue? Thanks very much!
Below is the code, please let me know how I should revise it so that I can properly backtest it:

//+------------------------------------------------------------------+

input bool   OpenBUY=True;

input bool   OpenSELL=True;

input bool   CloseBySignal=True;

input double StopLoss=0;

input double TakeProfit=0;

input double TrailingStop=0;

input int    RSIperiod=14;

input double BuyLevel=30;

input double SellLevel=70;

input bool   AutoLot=True;

input double Risk=10;

input double ManualLots=0.1;

input int    MagicNumber=123;

input string Koment="RSIea";

input int    Slippage=10;

//---

int OrderBuy,OrderSell;

int ticket;

int LotDigits;

double Trail,iTrailingStop;

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int init()

  {

   return(0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

int deinit()

  {

   return(0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

int start()

  {

   double stoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);

   OrderBuy=0;

   OrderSell=0;

   for(int cnt=0; cnt<OrdersTotal(); cnt++)

     {

      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))

         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderComment()==Koment)

           {

            if(OrderType()==OP_BUY) OrderBuy++;

            if(OrderType()==OP_SELL) OrderSell++;

            if(TrailingStop>0)

              {

               iTrailingStop=TrailingStop;

               if(TrailingStop<stoplevel) iTrailingStop=stoplevel;

               Trail=iTrailingStop*Point;

               double tsbuy=NormalizeDouble(Bid-Trail,Digits);

               double tssell=NormalizeDouble(Ask+Trail,Digits);

               if(OrderType()==OP_BUY && Bid-OrderOpenPrice()>Trail && Bid-OrderStopLoss()>Trail)

                 {

                  ticket=OrderModify(OrderTicket(),OrderOpenPrice(),tsbuy,OrderTakeProfit(),0,Blue);

                 }

               if(OrderType()==OP_SELL && OrderOpenPrice()-Ask>Trail && (OrderStopLoss()-Ask>Trail || OrderStopLoss()==0))

                 {

                  ticket=OrderModify(OrderTicket(),OrderOpenPrice(),tssell,OrderTakeProfit(),0,Blue);

                 }

              }

           }

     }


   double rsim30=iRSI(Symbol(),30,RSIperiod,PRICE_CLOSE,0);

   double rsim60=iRSI(Symbol(),60,RSIperiod,PRICE_CLOSE,0);

   double rsid1=iRSI(Symbol(),1440,RSIperiod,PRICE_CLOSE,0);



//--- open position

   if(OpenSELL && OrderSell<1 && rsim30>=SellLevel && rsim60>=SellLevel && rsid1<50) OPSELL();

   if(OpenBUY && OrderBuy<1 && rsim30<=BuyLevel && rsim60<=BuyLevel && rsid1>50) OPBUY();

//--- close position by signal

   if(CloseBySignal)

     {

      if(OrderBuy>0 && rsim30>=SellLevel && rsim60>=SellLevel) CloseBuy();

      if(OrderSell>0 && rsim30<=BuyLevel && rsim60<=BuyLevel) CloseSell();

     }

//---

   return(0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void OPBUY()

  {

   double StopLossLevel;

   double TakeProfitLevel;

   if(StopLoss>0) StopLossLevel=Bid-StopLoss*Point; else StopLossLevel=0.0;

   if(TakeProfit>0) TakeProfitLevel=Ask+TakeProfit*Point; else TakeProfitLevel=0.0;



   ticket=OrderSend(Symbol(),OP_BUY,LOT(),Ask,Slippage,StopLossLevel,TakeProfitLevel,Koment,MagicNumber,0,DodgerBlue);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void OPSELL()

  {

   double StopLossLevel;

   double TakeProfitLevel;

   if(StopLoss>0) StopLossLevel=Ask+StopLoss*Point; else StopLossLevel=0.0;

   if(TakeProfit>0) TakeProfitLevel=Bid-TakeProfit*Point; else TakeProfitLevel=0.0;

//---

   ticket=OrderSend(Symbol(),OP_SELL,LOT(),Bid,Slippage,StopLossLevel,TakeProfitLevel,Koment,MagicNumber,0,DeepPink);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void CloseSell()

  {

   int  total=OrdersTotal();

   for(int y=OrdersTotal()-1; y>=0; y--)

     {

      if(OrderSelect(y,SELECT_BY_POS,MODE_TRADES))

         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL && OrderMagicNumber()==MagicNumber)

           {

            ticket=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),5,Black);

           }

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void CloseBuy()

  {

   int  total=OrdersTotal();

   for(int y=OrdersTotal()-1; y>=0; y--)

     {

      if(OrderSelect(y,SELECT_BY_POS,MODE_TRADES))

         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY && OrderMagicNumber()==MagicNumber)

           {

            ticket=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),5,Black);

           }

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double LOT()

  {

   double lotsi;

   double ilot_max =MarketInfo(Symbol(),MODE_MAXLOT);

   double ilot_min =MarketInfo(Symbol(),MODE_MINLOT);

   double tick=MarketInfo(Symbol(),MODE_TICKVALUE);

//---

   double  myAccount=AccountBalance();

//---

   if(ilot_min==0.01) LotDigits=2;

   if(ilot_min==0.1) LotDigits=1;

   if(ilot_min==1) LotDigits=0;

//---

   if(AutoLot)

     {

      lotsi=NormalizeDouble((myAccount*Risk)/10000,LotDigits);

        } else { lotsi=ManualLots;

     }

//---

   if(lotsi>=ilot_max) { lotsi=ilot_max; }

//---

   return(lotsi);

  }

//+------------------------------------------------------------------+

Please don’t post your whole code, just the relevant section.

 double rsim30=iRSI(Symbol(),30,RSIperiod,PRICE_CLOSE,0);

   double rsim60=iRSI(Symbol(),60,RSIperiod,PRICE_CLOSE,0);

   double rsid1=iRSI(Symbol(),1440,RSIperiod,PRICE_CLOSE,0);



//--- open position

   if(OpenSELL && OrderSell<1 && rsim30>=SellLevel && rsim60>=SellLevel && rsid1<50) OPSELL();

   if(OpenBUY && OrderBuy<1 && rsim30<=BuyLevel && rsim60<=BuyLevel && rsid1>50) OPBUY();

You are using values from open bars so when you look back over a chart, the closing values will almost certainly be different. It looks like trades have been taken where they shouldn’t have.

Sorry about the whole code part, will take note next time. I would like my trading strategy to base on real-time RSI values as the live data would display. Do you mean that I should add a shift in the code for the RSI? Like:

   double rsim30=iRSI(Symbol(),30,RSIperiod,PRICE_CLOSE,1);

   double rsim60=iRSI(Symbol(),60,RSIperiod,PRICE_CLOSE,1);

   double rsid1=iRSI(Symbol(),1440,RSIperiod,PRICE_CLOSE,1);

Or was it something else you are referring to, sir? Thanks!

If you want to look back on the charts to check, then you can only use shift 1 as values will change before the bar is closed.

Thanks so much, Keith, that clarifies a lot of things for me! You are great!