Indicator lines don't update in backtester

 

I'm having an issue where I've written an indicator and am now using it to backtest a strategy.  I start my backtester in visual mode and then drop my indicator onto the chart.  When I do that, the lines in the indicator don't ever update from that point forward, they just stay at the same value, even though the indicator buffers are updating just fine (I'm printing them in the chart window and can see them update as expected).  In the image below I've drawn a green arrow where I dropped the indicator on the chart, and you can see in the upper left what the values of the lines should be at the time I stopped the backtester, but the lines and histograms in the indicator window just don't change.  Any idea why that might be?  Also, when I run the indicator on a live chart everything updates just fine.



 
Try adding
#property indicator_type1       DRAW_LINE
 
whroeder1:
Try adding

Thank you, but that is already there.  Here's my source code in case you might see some glaring issue:


#property copyright "Copyright 2017, John Turner"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   5

//--- plot ADXOneHigher
#property indicator_label1  "ADXOneHigher"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot ADXTwoHigher
#property indicator_label2  "ADXTwoHigher"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrFuchsia
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot ADXThreeHigher
#property indicator_label3  "ADXThreeHigher"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGold
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//--- plot ADXSumTwo
#property indicator_label4  "ADXSumTwo"
#property indicator_type4   DRAW_HISTOGRAM
#property indicator_color4  clrLime
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
//--- plot ADXSumThree
#property indicator_label5  "ADXSumThree"
#property indicator_type5   DRAW_HISTOGRAM
#property indicator_color5  clrBlue
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1
//--- indicator buffers
double         ADXOneHigherBuffer[];
double         ADXTwoHigherBuffer[];
double         ADXThreeHigherBuffer[];
double         ADXSumTwoBuffer[];
double         ADXSumThreeBuffer[];
//--- indicator parameters
input int ADXPeriodNow = 14;
input int ADXPeriodOneUp = 14;
input int ADXPeriodTwoUp = 14;
input int ADXPeriodThreeUp = 14;

double ADX_Signal;    // ADX Signal Line
double ADX_DPlus;     // ADX DI+
double ADX_DMinus;    // ADX DI-
double ADX_Signal_Higher;
double ADX_DPlus_Higher;
double ADX_DMinus_Higher;
double ADX_Signal_TwoHigher;
double ADX_DPlus_TwoHigher;
double ADX_DMinus_TwoHigher;
double ADX_Signal_ThreeHigher;
double ADX_DPlus_ThreeHigher;
double ADX_DMinus_ThreeHigher;

double ADXNow;

string str1;
string str2;
string str3;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ADXOneHigherBuffer);
   SetIndexBuffer(1,ADXTwoHigherBuffer);
   SetIndexBuffer(2,ADXThreeHigherBuffer);
   SetIndexBuffer(3,ADXSumTwoBuffer);
   SetIndexBuffer(4,ADXSumThreeBuffer);
   
//---
   SetIndexLabel(0,"ADX One Timeframe Up");
   SetIndexLabel(1,"ADX Two Timeframes Up");
   SetIndexLabel(2,"ADX Three Timeframes Up");
   SetIndexLabel(3,"ADX Sum Next Two");
   SetIndexLabel(4,"ADX Sum Next Three");
   
   str1 = "ADXMult Loaded";
   str2 = "";// = StringFormat("TwoUp = %.5fr\n", ADX_Signal_TwoHigher[1]);
   str3 = "";// = StringFormat("ThreeUp = %.5f\r\n", ADX_Signal_ThreeHigher[1]);
   writeComments(str1, str2, str3);//*/
    
   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[])
  {
//---
   static int i,limit;
   
   if(rates_total <= ADXPeriodNow)
      return 0; 
        
   //--- last counted bar will be recounted
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;   
      
   for(i=0; i<limit; i++)
   {

      getADXMultTimeFrames(i);
      
      
      if(ADX_DPlus >= ADX_DMinus)   // Upward trend
         ADXNow = ADX_Signal;
      else ADXNow = ADX_Signal * -1;    // Downward trend
      
      if(ADX_DPlus_Higher >= ADX_DMinus_Higher)   // Upward trend
         ADXOneHigherBuffer[i] = ADX_Signal_Higher;
      else ADXOneHigherBuffer[i] = ADX_Signal_Higher * -1;    // Downward trend
      
      if(ADX_DPlus_TwoHigher >= ADX_DMinus_TwoHigher)   // Upward trend
         ADXTwoHigherBuffer[i] = ADX_Signal_TwoHigher;
      else ADXTwoHigherBuffer[i] = ADX_Signal_TwoHigher * -1;    // Downward trend
      
      if(ADX_DPlus_ThreeHigher >= ADX_DMinus_ThreeHigher)   // Upward trend
         ADXThreeHigherBuffer[i] = ADX_Signal_ThreeHigher;
      else ADXThreeHigherBuffer[i] = ADX_Signal_ThreeHigher * -1;    // Downward trend
      
      ADXSumTwoBuffer[i] = ADXOneHigherBuffer[i] + ADXTwoHigherBuffer[i];
      ADXSumThreeBuffer[i] = ADXSumTwoBuffer[i] + ADXThreeHigherBuffer[i];
      
   }   
   
   //str1 = StringFormat("ADXNow = %.3f\r\n", ADXNow);
   //str2 = StringFormat("M%d = %.1f   M%d = %.1f   M%d = %.1f\r\n",oneTimeFrameUp(), ADXOneHigherBuffer[0],twoTimeFramesUp(), ADXTwoHigherBuffer[0],threeTimeFramesUp(), ADXThreeHigherBuffer[0]);
   //str3 = StringFormat("Sum2 = %.1f   Sum3 = %.1f\r\n", ADXSumTwoBuffer[0], ADXSumThreeBuffer[0]);
   //writeComments(str1, str2, str3);//*/
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+

void getADXMultTimeFrames(int barIndex)
{
   int barOneUp;
   int barTwoUp;
   int barThreeUp;
   datetime baseBarTime;

   baseBarTime = iTime(NULL, PERIOD_CURRENT, barIndex);

   if(barIndex == 0)
   {
      barOneUp = 0;
      barTwoUp = 0;
      barThreeUp = 0;
   }
   else
   {
      barOneUp = iBarShift(NULL, oneTimeFrameUp(), baseBarTime, false);
      barTwoUp = iBarShift(NULL, twoTimeFramesUp(), baseBarTime, false);
      barThreeUp = iBarShift(NULL, threeTimeFramesUp(), baseBarTime, false);
   }

   ADX_Signal = iADX(NULL, 0, ADXPeriodNow, PRICE_CLOSE, MODE_MAIN, barIndex);    // ADX Signal Line
   ADX_DPlus = iADX(NULL, 0, ADXPeriodNow, PRICE_CLOSE, MODE_PLUSDI, barIndex);    // ADX DI+
   ADX_DMinus = iADX(NULL, 0, ADXPeriodNow, PRICE_CLOSE, MODE_MINUSDI, barIndex);    // ADX DI-
   ADX_Signal_Higher = iADX(NULL, oneTimeFrameUp(), ADXPeriodOneUp, PRICE_CLOSE, MODE_MAIN, barOneUp);    // ADX Signal Line
   ADX_DPlus_Higher = iADX(NULL, oneTimeFrameUp(), ADXPeriodOneUp, PRICE_CLOSE, MODE_PLUSDI, barOneUp);    // ADX DI+
   ADX_DMinus_Higher = iADX(NULL, oneTimeFrameUp(), ADXPeriodOneUp, PRICE_CLOSE, MODE_MINUSDI, barOneUp);    // ADX DI-
   ADX_Signal_TwoHigher = iADX(NULL, twoTimeFramesUp(), ADXPeriodTwoUp, PRICE_CLOSE, MODE_MAIN, barTwoUp);    // ADX Signal Line
   ADX_DPlus_TwoHigher = iADX(NULL, twoTimeFramesUp(), ADXPeriodTwoUp, PRICE_CLOSE, MODE_PLUSDI, barTwoUp);    // ADX DI+
   ADX_DMinus_TwoHigher = iADX(NULL, twoTimeFramesUp(), ADXPeriodTwoUp, PRICE_CLOSE, MODE_MINUSDI, barTwoUp);    // ADX DI-
   ADX_Signal_ThreeHigher = iADX(NULL, threeTimeFramesUp(), ADXPeriodThreeUp, PRICE_CLOSE, MODE_MAIN, barThreeUp);    // ADX Signal Line
   ADX_DPlus_ThreeHigher = iADX(NULL, threeTimeFramesUp(), ADXPeriodThreeUp, PRICE_CLOSE, MODE_PLUSDI, barThreeUp);    // ADX DI+
   ADX_DMinus_ThreeHigher = iADX(NULL, threeTimeFramesUp(), ADXPeriodThreeUp, PRICE_CLOSE, MODE_MINUSDI, barThreeUp);    // ADX DI-

}


//Returns the next time frame up or down
int oneTimeFrameUp(void)
{
   int currentTimeFrame = _Period;
   switch(currentTimeFrame)
   {
      case 1:
         return 5;
         break;
      case 5:
         return 15;
         break;
      case 15:
         return 30;
         break;
      case 30:
         return 60;
         break;
      case 60:
         return 240;
         break;
      case 240:
         return 1440;
         break;
      case 1440:
         return 10080;
         break;
      case 10080:
         return 43200;
         break;
      default:
         return currentTimeFrame;
         break; 
   }
}


int twoTimeFramesUp()
{
   int currentTimeFrame = _Period;

   switch(currentTimeFrame)
   {
      case 1:
         return 15;
         break;
      case 5:
         return 30;
         break;
      case 15:
         return 60;
         break;
      case 30:
         return 240;
         break;
      case 60:
         return 1440;
         break;
      case 240:
         return 10080;
         break;
      case 1440:
         return 43200;
         break;
      default:
         return currentTimeFrame;
         break; 
   }
}

int threeTimeFramesUp()
{
   int currentTimeFrame = _Period;

   switch(currentTimeFrame)
   {
      case 1:
         return 30;
         break;
      case 5:
         return 60;
         break;
      case 15:
         return 240;
         break;
      case 30:
         return 1440;
         break;
      case 60:
         return 10080;
         break;
      case 240:
         return 43200;
         break;
      default:
         return currentTimeFrame;
         break; 
   }
}


void writeComments(string s1, string s2, string s3)
{
   string outputString;
   string tempString;

   tempString=s1;
   StringAdd(outputString,tempString);
   tempString=s2;
   StringAdd(outputString,tempString);
   tempString=s3;
   StringAdd(outputString,tempString);
   
   Comment(outputString);
   return;
}
 

That is MT4

You can not do visual back tests in mt4 for multi time frame indicators (first couple of builds when build 600 started were doing that perfectly, then they changed it and never reverted to the way it was working when it was working good)

 
Mladen Rakic:

That is MT4

You can not do visual back tests in mt4 for multi time frame indicators (first couple of builds when build 600 started were doing that perfectly, then they changed it and never reverted to the way it was working when it was working good)


Bummer.  Is it only the lines in the indicator window that don't work?  When I print the values of the lines in the terminal window those do seem to be accurate during a visual backtest.  Can I assume that things are working OK with the exception of the lines?

 
Mladen Rakic:

That is MT4

You can not do visual back tests in mt4 for multi time frame indicators (first couple of builds when build 600 started were doing that perfectly, then they changed it and never reverted to the way it was working when it was working good)

If the OP has the source code then the code in this thread may be able to resolve the issue with little effort.

https://www.mql5.com/en/forum/160249/page3

problem with ibarshift getting values from higher timeframes in strategy tester
problem with ibarshift getting values from higher timeframes in strategy tester
  • 2016.10.07
  • www.mql5.com
hi guys, first i need to say that i use a separate folder for back-testing, in my "mt4/history/" is a folder "backtest", the full path is "Program...
 
Mladen Rakic #:

That is MT4

You can not do visual back tests in mt4 for multi time frame indicators (first couple of builds when build 600 started were doing that perfectly, then they changed it and never reverted to the way it was working when it was working good)

Hi, does the MT4 strategy tester work well with a multicurrencies indicator?  That is, which calculates its value from the closure of other symbols?

I have the same problem to draw indicator on strategy tester…  🤨

I’ll try MT5 🤞
Reason: