Multiple Timeframe ADX Indicator

 

I am trying to put together an indicator that would show the signal line from the ADX indicator from the next three higher timeframes all on one indicator, the only variation being that if -DI is above +DI it will show as a negative value.  I've got three lines displaying on the indicator, but they do not match what the ADX signal line looks like when I run the ADX indicator on the next three higher time frames.  Here is the OnCalculate() function in my indicator.  Can anyone see any glaring errors here?


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 <= ADXPeriod)
      return 0; 
        
   //--- last counted bar will be recounted
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;   
      
   for(i=0; i<limit; i++)
   {

      ADX_Signal = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MAIN, i);    // ADX Signal Line
      ADX_DPlus = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, i);    // ADX DI+
      ADX_DMinus = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, i);    // ADX DI-
      ADX_Signal_Higher = iADX(NULL, oneTimeFrameUp(), ADXPeriod, PRICE_CLOSE, MODE_MAIN, i);    // ADX Signal Line
      ADX_DPlus_Higher = iADX(NULL, oneTimeFrameUp(), ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, i);    // ADX DI+
      ADX_DMinus_Higher = iADX(NULL, oneTimeFrameUp(), ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, i);    // ADX DI-
      ADX_Signal_TwoHigher = iADX(NULL, twoTimeFramesUp(), ADXPeriod, PRICE_CLOSE, MODE_MAIN, i);    // ADX Signal Line
      ADX_DPlus_TwoHigher = iADX(NULL, twoTimeFramesUp(), ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, i);    // ADX DI+
      ADX_DMinus_TwoHigher = iADX(NULL, twoTimeFramesUp(), ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, i);    // ADX DI-
      ADX_Signal_ThreeHigher = iADX(NULL, threeTimeFramesUp(), ADXPeriod, PRICE_CLOSE, MODE_MAIN, i);    // ADX Signal Line
      ADX_DPlus_ThreeHigher = iADX(NULL, threeTimeFramesUp(), ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, i);    // ADX DI+
      ADX_DMinus_ThreeHigher = iADX(NULL, threeTimeFramesUp(), ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, i);    // ADX DI-
      
      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("OneUp = %.3f   TwoUp = %.3f   ThreeUp = %.3f\r\n", ADXOneHigherBuffer[0], ADXTwoHigherBuffer[0], ADXThreeHigherBuffer[0]);
   str3 = StringFormat("limit = %d\r\n", limit);
   writeComments(str1, str2, str3);//*/
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
jt27:

Can anyone see any glaring errors here?

It depends exactly what you are trying to achieve, but one probable error goes as follows:

  • Let's say that the base timeframe is M1, and oneTimeFrameUp() is M5.
  • And let's say that the current time is 10:52
  • When i == 1...
  • You are getting ADX on the current M1 timeframe for 10:51 (to 10:51:59)
  • You are getting ADX on M5 for 10:45 (to 10:49:59). Bar #1 on M5 covers a completely different time period to bar #1 on M1.
 
JC:

It depends exactly what you are trying to achieve, but one probable error goes as follows: [...]

A little less elliptically...

Rather than using a shift value of i on the higher timeframes, you almost certainly want to adjust it to the corresponding shift for the equivalent period on the higher timeframe. Something along the lines of:

iBarShift(Symbol(), oneTimeFrameUp(), Time[i], false)

Digressing a little, what this doesn't solve is the fundamental weakness of almost any MTF indicator. Take the following scenario:

  • Current time is 10:53
  • You are plotting values for an M1 chart, looking also at the higher M5 timeframe
  • You are looking at bar #5 on M1: 10:47:00 to 10:47:59
  • You adjust this shift to M5, giving you a value of 1, and ask MT4 to give you the ADX for bar #1 on M5.
  • What MT4 gives you is the final ADX value for that bar, covering the period 10:45:00 to 10:49:59, not the interim as-at value for the partial M5 bar from 10:45:00 to 10:47:59
  • On the M1 chart, you therefore plot an M5 value from 10:49 against the bar for 10:47.

In essence, almost any MTF indicator ever written for MT4 can, historically, see into the future. People tend to like MTF indicators because they seem extraordinarily better at picking out future movements when going back over historic charts... but that's precisely because they're looking into the future.

Solving this problem, and showing the true interim intra-bar values on the higher timeframe(s) is always possible, but is always somewhere between very and extremely difficult.

 
for(i=0; i<limit; i++){
      ADX_Signal = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MAIN, i); 
  1. You are mixing apples and oranges.
  2. One bar on the higher TF is multiple bars on the lower. If you want the stair step effect from the HTF, you have to fix your limit. See How to do your lookbacks correctly.
 

Thank you both for your help, that gives me some things to chew on.

Reason: