MQL4 - Indicator working normally in live trading but in backtesting returning '2147483647'

 

This is not my indicator, I downloaded it. Essentially it draws structural points on the chart which which it does perfectly. When I call this indicator in live trading it returns the correct value, however, during backtesting in the strategy tester it returns  2147483647,  I have spent countless hours every day for the past couple of weeks staring at this code, tweaking everything, understanding the code and searching forum posts with this issue and to no avail; still have not been able to fix it. I'm pretty sure the problem lays within the lookback and the limit part of the code however I am honestly lost as to what the fix is. I will add the adjustments I have tried after the main indicator code.



#property copyright "Copyright 2016, Jay Davis"
#property link      "https://www.tidyneat.com"
#property version   "1.1"
#property strict
#property indicator_chart_window
#property indicator_buffers 5



extern int MajorSwingSize=3;
extern int PeriodsInMajorSwing=13;


extern int MinorSwingSize=1;
extern int PeriodsInMinorSwing=5;

extern ENUM_MA_METHOD MovingAveragMethod=MODE_EMA;
extern int MovingAveragePeriods= 55;


color fiftyPercentLineColor=clrAliceBlue;
color MajorSwingColor=clrLemonChiffon;
color MinorSwingColor=clrCornflowerBlue;
int lookBack=PeriodsInMajorSwing*2;
color MovingAvergeColor = clrDarkGoldenrod;

double majorSwingHigh[];
double minorSwingHigh[];
double majorSwingLow[];
double minorSwingLow[];
double EMA[];

double mshIndex[];
double mslIndex[];

int x = 0;
int y = 0;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,majorSwingHigh);  //associates array with buffer
   SetIndexStyle(0,DRAW_ARROW,EMPTY,MajorSwingSize,MajorSwingColor);
   SetIndexArrow(0,108); // drawing wingding 108
   SetIndexLabel(0,"Major Swing High");

   SetIndexBuffer(1,majorSwingLow);  //associates array with buffer
   SetIndexStyle(1,DRAW_ARROW,EMPTY,MajorSwingSize,MajorSwingColor);
   SetIndexArrow(1,108); // drawing wingding 108
   SetIndexLabel(1,"Minor Swing Low");
   
   SetIndexBuffer(2,mshIndex);
   SetIndexLabel(2,"Major Swing High Index");
   
   SetIndexBuffer(3,mslIndex);
   SetIndexLabel(3,"Major Swing Low Index");
   
   
   /*
   //SetIndexBuffer(2,minorSwingLow);  //associates array with buffer
   //SetIndexStyle(2,DRAW_ARROW,EMPTY,MajorSwingSize,MajorSwingColor);
   //SetIndexArrow(2,108); // drawing wingding 108
   //SetIndexLabel(2,"Major Swing Low");

   //SetIndexBuffer(3,minorSwingLow);  //associates array with buffer
   //SetIndexStyle(3,DRAW_ARROW,EMPTY,MinorSwingSize,MinorSwingColor);
   //SetIndexArrow(3,108); // drawing wingding 108
   //SetIndexLabel(3,"Minor Swing Low");
   */
    
   SetIndexBuffer(4,EMA);  //associates array with buffer
   SetIndexStyle(4,DRAW_LINE,STYLE_SOLID,EMPTY,MovingAvergeColor);
   SetIndexLabel(4,"Moving Average");


//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {

   int limit;
   int counted_bars=IndicatorCounted();
//---- check for possible errors 
   if(counted_bars<0) return(-1);
//---- the last counted bar will be recounted 
   if(counted_bars>0) counted_bars--; 
   limit=Bars-counted_bars;
//---- main loop 
// First Run Through Rule
   if(counted_bars==0)
     {
      if(lookBack>=MovingAveragePeriods)
        {
         limit-=lookBack;
        }
      else
        {
         limit-=MovingAveragePeriods;
        }
     }
    

//---
   for(int i=1; i<limit; i++)
     {
      // Draw Moving Average
      EMA[i]=iMA(NULL,0,MovingAveragePeriods,0,MovingAveragMethod,PRICE_CLOSE,i);
      
      /*
      Minor Swing High Logic
      if(iHighest(NULL,0,MODE_HIGH,PeriodsInMinorSwing*2,i)==i+PeriodsInMinorSwing)
        {
         minorSwingHigh[i+PeriodsInMinorSwing]=High[i+PeriodsInMinorSwing];
        }
      */

      // Major Swing High Logic
      if(iHighest(NULL,0,MODE_HIGH,PeriodsInMajorSwing*2,i)==i+PeriodsInMajorSwing)
        {
         majorSwingHigh[i+PeriodsInMajorSwing]=High[i+PeriodsInMajorSwing];
         
         
         mshIndex[x]= High[i+PeriodsInMajorSwing];
         x++;
         //Filling the major swing high Index with the major swing point value then increments the array size by 1
         
        }
      
      /*
      Minor Swing Low Logic
      if(iLowest(NULL,0,MODE_LOW,PeriodsInMinorSwing*2,i)==i+PeriodsInMinorSwing)
        {
          minorSwingLow[i+PeriodsInMinorSwing]=Low[i+PeriodsInMinorSwing];
        }
      */

      // Major Swing Low Logic
      if(iLowest(NULL,0,MODE_LOW,PeriodsInMajorSwing*2,i)==i+PeriodsInMajorSwing)
        {
         majorSwingLow[i+PeriodsInMajorSwing]=Low[i+PeriodsInMajorSwing];
         
         mslIndex[y] = Low[i+PeriodsInMajorSwing];
         y++;
         //Filling the major swing low Index with the major swing point value then increments the array size by 1
        }
      
        
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

I changed this part of the code: 

  int limit;
   int counted_bars=IndicatorCounted();
//---- check for possible errors 
   if(counted_bars<0) return(-1);
//---- the last counted bar will be recounted 
   if(counted_bars>0) counted_bars--; 
   limit=Bars-counted_bars;
//---- main loop 
// First Run Through Rule
   if(counted_bars==0)
     {
      if(lookBack>=MovingAveragePeriods)
        {
         limit-=lookBack;
        }
      else
        {
         limit-=MovingAveragePeriods;
        }
     }

to this:

int limit;
   int counted_bars=IndicatorCounted();
   //Alert(counted_bars);
//---- check for possible errors 
   //if(counted_bars<0) return(-1);
//---- the last counted bar will be recounted 
   //if(counted_bars>0) counted_bars--; 
  
   int lookback = MovingAveragePeriods;
   
   limit= Bars - 1 - MathMax(lookback, counted_bars);


//---
   for(int i = Bars - 1 - MathMax(MovingAveragePeriods, counted_bars); i >= 0; i--)
     {

which has still not fixed the issue. Don't mind the random commented out line, that was just me tweaking the code.


Words cannot describe how much I would appreciate help and a solution. This has been like an itch in my brain I cannot scratch.


Thanks in advance. 

 
MKThePlug: . When I call this indicator in live trading it returns the correct value, however, during backtesting in the strategy tester it returns  2147483647,  
  1. That is EMPTY_VALUE.

  2. Indicators do not return anything. It is your iCustom code that has the problem.

  3. You should stop using the old event handlers and IndicatorCounted() and start using new event handlers.
              Event Handling Functions - MQL4 Reference
              How to do your lookbacks correctly - MQL4 programming forum #9-14 & #19 (2016)

 
William Roeder #:
  1. That is EMPTY_VALUE.

  2. Indicators do not return anything. It is your iCustom code that has the problem.

  3. You should stop using the old event handlers and IndicatorCounted() and start using new event handlers.
              Event Handling Functions - MQL4 Reference
              How to do your lookbacks correctly - MQL4 programming forum #9-14 & #19 (2016)




    Thank you for your reply. I analyzed the links and don't quite seem to understand what outdated event handlers I am using, can you elaborate please? Also when you say the iCustom code is the issue, are you referring to the indicator being called with iCustom? If so I don't see the error in the iCustom call. This is the indicator being called:

    double strucVal = iCustom(NULL,0,"StructureIndicatorV1Delta",3,13,1,5,MODE_EMA,55,2,0);
        Alert(strucVal);



    Many thanks for your time and help, also I'm sorry for any dumb questions!

     
    1. int x = 0;
      int y = 0;
      ⋮
            EMA[i]=iMA(NULL,0,MovingAveragePeriods,0,MovingAveragMethod,PRICE_CLOSE,i);
      ⋮
               mshIndex[x]= High[i+PeriodsInMajorSwing];          x++; 

      The first run, you store the newest high in bar zero. Next previous in bar one, etc.

      After that you will update only higher indexes and when a new bar starts, bar zero will only have EMPTY_VALUE.

      Delete x and y and store in index i.


    2.    for(int i=1; i<limit; i++)

      You are reading bar zero but never process it.

    3. Do your lookbacks correctly #9#14 & #19

      .
     
    William Roeder #:
    1. The first run, you store the newest high in bar zero. Next previous in bar one, etc.

      After that you will update only higher indexes and when a new bar starts, bar zero will only have EMPTY_VALUE.

      Delete x and y and store in index i.


    2. You are reading bar zero but never process it.

    3. Do your lookbacks correctly #9#14 & #19

      .

    Hey, sorry for the late reply.


    I looked through the linked pages and took your advice and ergo changed the code to this:

    #define LAST 1 
    
       for(int i = Bars - 1 - MathMax(lookback, prev_calculated); i >= LAST; --i)
         {	
    	if(iHighest(NULL,0,MODE_HIGH,PeriodsInMajorSwing*2,i)==i+PeriodsInMajorSwing)
            {
             majorSwingHigh[i+PeriodsInMajorSwing]=High[i+PeriodsInMajorSwing];
             
             
             mshIndex[i]= High[i+PeriodsInMajorSwing];
             //x++;
    
    
    
    
    	if(iLowest(NULL,0,MODE_LOW,PeriodsInMajorSwing*2,i)==i+PeriodsInMajorSwing)
            {
             majorSwingLow[i+PeriodsInMajorSwing]=Low[i+PeriodsInMajorSwing];
             
             mslIndex[i] = Low[i+PeriodsInMajorSwing];
             //y++;
             //Filling the major swing low Index with the major swing point value then increments the array size by 1
            }
             //Filling the major swing high Index with the major swing point value then increments the array size by 1
             
            }
         }
    return (rates_total-MathMax(1,LAST));
    
    
    
    
    

    which hasn't solved the issue. When I call the indicator with this:

    double strucVal = iCustom(NULL,0,"StructureIndicatorV1Delta",3,13,1,5,MODE_EMA,55,2,0);
        Alert(strucVal);

    I still receive an empty value (2147483647). 

     
    You are processing all bars down to one (LAST). You are reading bar zero. Why does your result surprise you?
     
    William Roeder #:
    You are processing all bars down to one (LAST). You are reading bar zero. Why does your result surprise you?

    Even when I read bar one:

    double strucVal = iCustom(NULL,0,"StructureIndicatorV1Delta",3,13,1,5,MODE_EMA,55,2,1);
    Alert(strucVal);

    Or any other bar, I still receive an empty value instead of the actual values that are desired. Previously when I had separate x and y variables for the msh and msl buffers, the EA in strategy tester would read and alert the correct value for 3-4 times and then would alert an empty value which I cannot understand as to why. The msh and msl lists/arrays were created to store values that were being stored in the majorSwingHigh/Low lists/arrays, in a list that was the same size as the amount of elements in it if that makes sense. E.g the code snippet above should be alerting the second element (index 1) that is stored in the msh buffer which should be the second most recent value that was stored in the majorSwingHigh. I hope that makes sense. I have been playing around with ArraySetAsSeries for the msh/msl arrays however nothing has managed to fix it. 

    Reason: