How to use custom indicator in EA backtesting?

 

Hi there. I've created a custom indi in MT5 which I would like to use in my EA via iCustom function. However when I try to backtest my EA, a strange thing happened. I select for instance a test period for entire February and run it...but while looking at the strategy tester window I notice my custom indi plots values for the time before testing period e.i. until 31. January ok, but then it keeps plotting the last value it calculated (a horizontal line), see right bottom corner on the picture. I did double check the code of indi and everything looks ok. Indi uses for instance iRSI and iMA, copies their value in buffers and calculates a kind of trend line which is plotted on canvas. I checked the values in rsi and ima buffers and they are the same for the entire period of testing, therefore my indi calculates same values. Has anyone noticed this behaviour? It is true, that there is no data feed during weekends but that should be the problem. I check close[i] values, they are ok, only iRSI and iMA values are not calculated. Any suggestion much welcome.EA Backtesting

 
arcull:

Hi there. I've created a custom indi in MT5 which I would like to use in my EA via iCustom function. However when I try to backtest my EA, a strange thing happened. I select for instance a test period for entire February and run it...but while looking at the strategy tester window I notice my custom indi plots values for the time before testing period e.i. until 31. January ok, but then it keeps plotting the last value it calculated (a horizontal line), see right bottom corner on the picture. I did double check the code of indi and everything looks ok. Indi uses for instance iRSI and iMA, copies their value in buffers and calculates a kind of trend line which is plotted on canvas. I checked the values in rsi and ima buffers and they are the same for the entire period of testing, therefore my indi calculates same values. Has anyone noticed this behaviour? It is true, that there is no data feed during weekends but that should be the problem. I check close[i] values, they are ok, only iRSI and iMA values are not calculated. Any suggestion much welcome.

Your indicator is bugged. Post the code if you need help.
 
angevoyageur:
Your indicator is bugged. Post the code if you need help.

I hope so, please point it out. Here is the relevant part of the indi a bit simplified.

int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,SMASlopeBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,LMASlopeBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,MACDSlopeBuffer,INDICATOR_DATA);
   
   ArrayResize(smaBuf,TrendPeriod);
   ArrayResize(lmaBuf,TrendPeriod);
   ArrayResize(macdBuf,TrendPeriod);
   
//---
   BufCopyFld = false;
   lmabufcpdlcl = smabufcpdlcl = macdbufcpdlcl = 0;   
   
   macdHandle = iMACD(Symbol(),0,12,26,9,AppliedPrice);
   smaHandle = iMA(Symbol(),0,ShortPeriod,0,MAMethod,AppliedPrice);
   lmaHandle = iMA(Symbol(),0,LongPeriod,0,MAMethod,AppliedPrice);
   rsiHandle = iRSI(Symbol(),0,3,AppliedPrice); 
   
   return(INIT_SUCCEEDED);
  }
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {     
      
   for(int i=prev_calculated;i<(rates_total) && !IsStopped();i++) { 
      ArrayInitialize(smaBuf,0);
      ArrayInitialize(lmaBuf,0);
      ArrayInitialize(macdBuf,0);          

      calculated = BarsCalculated(smaHandle);
      if(calculated < rates_total) {
         Print("Not all data of smaHandle is calculated (",calculated,"bars ). Error",GetLastError());
         return(0);      
      }    

      if (i >= (ShortPeriod)) {
         if(IsStopped()) return(0);
         //smabufcpdlcl=CopyBuffer(smaHandle,0,i - ShortPeriod,1,smaBuf);      
         smabufcpdlcl=CopyBuffer(rsiHandle,0,i - ShortPeriod,1,smaBuf);      
         
         if(smabufcpdlcl<0) 
           {
            BufCopyFld=true;
            Print("failed to copy smaBuffer");
            Print("Last error:"+IntegerToString(GetLastError()));
            return(false);            
           } else {  
            SMASlopeBuffer[i] = smaBuf[0];
           }
        }
   }

   return(rates_total);
  }
 
arcull:

I hope so, please point it out. Here is the relevant part of the indi a bit simplified.

You are lost in the indexing of your arrays.

Just an example, if i=rates_total-1 (most recent current candle), you are copying rsi value with index i-ShortPeriod, which is an old value in the past close to oldest one. Check CopyBuffer documentation, it should be

     smabufcpdlcl=CopyBuffer(rsiHandle,0,rates_total-i-1,1,smaBuf);         

An easier approach if you have difficulties with indexing, is to declare all your indicator's buffers as TimeSeries:

   ArraySetAsSeries(SMASlopeBuffer,true);
   ...
 
angevoyageur:

You are lost in the indexing of your arrays.

Just an example, if i=rates_total-1 (most recent current candle), you are copying rsi value with index i-ShortPeriod, which is an old value in the past close to oldest one. Check CopyBuffer documentation, it should be

An easier approach if you have difficulties with indexing, is to declare all your indicator's buffers as TimeSeries:

Yes you are right, thanks for help.