Please Help: I modified MT4's DMI+ADX indicator but one line is not displayed

 

Hi everyone

I modified MT4's official DMI+ADX indicator(https://www.mql5.com/en/code/7955) to make it same as other other platforms.

The change is, MT4 calculates the EMA of (±DM/TrueRange) for ±DI while my version is to calculate EMA of ±DM and TrueRange separately then divide them. The ADX part is untouched.

- MT4's original version: ±DI = 100 * EMA(±DM/TrueRange)

- My version: ±DI = 100 * EMA(±DM) / EMA(TrueRange)

Well the ±DI part went well and displayed correctly in MT4.


However, the problem is the ADX line somehow disappeared mysteriously. Related code is even not changed! I tried a lot but still can't figure out what's happening. Can anyone help to find out the reason?

Thank you very much.

//+------------------------------------------------------------------+
//|                                                          ADX.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_separate_window
#property indicator_buffers 3 //Plot
#property indicator_color1 Olive
#property indicator_color2 MediumSeaGreen
#property indicator_color3 Crimson


//---- input parameters
extern int ADXPeriod=20;
//---- buffers
double ADXBuffer[];
double PlusDiBuffer[];
double MinusDiBuffer[];

double PdmBuffer[];
double MdmBuffer[];
double TrBuffer[];
double TempBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- Some additional buffers are used for counting.
   IndicatorBuffers(11);
//---- indicator buffers
   SetIndexBuffer(0,ADXBuffer);
   SetIndexBuffer(1,PlusDiBuffer);
   SetIndexBuffer(2,MinusDiBuffer);
   SetIndexBuffer(5,PdmBuffer);
   SetIndexBuffer(6,MdmBuffer);
   SetIndexBuffer(7,TrBuffer);
   SetIndexBuffer(8,TempBuffer);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("ADX("+ADXPeriod+")");
   SetIndexLabel(0,"ADX");
   SetIndexLabel(1,"+DI");
   SetIndexLabel(2,"-DI");
   
//----
   SetIndexDrawBegin(0,ADXPeriod);
   SetIndexDrawBegin(1,ADXPeriod);
   SetIndexDrawBegin(2,ADXPeriod);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Average Directional Movement Index                               |
//+------------------------------------------------------------------+
int start()
  {
   double pdm,mdm,tr;
   double price_high,price_low;
   int    starti,i,counted_bars=IndicatorCounted();
//----
   i=Bars-2;
   PdmBuffer[i+1]=0;
   MdmBuffer[i+1]=0;
   if(counted_bars>=i) i=Bars-counted_bars-1;
   starti=i;
//----
   while(i>=0)
     {
      price_low=Low[i];
      price_high=High[i];
      //----
      pdm=price_high-High[i+1];
      mdm=Low[i+1]-price_low;
      if(pdm<0) pdm=0;  // +DM
      if(mdm<0) mdm=0;  // -DM
      if(pdm==mdm) { pdm=0; mdm=0; }
      else if(pdm<mdm) pdm=0;
           else if(mdm<pdm) mdm=0;
      //----
      double num1=MathAbs(price_high-price_low);
      double num2=MathAbs(price_high-Close[i+1]);
      double num3=MathAbs(price_low-Close[i+1]);
      tr=MathMax(num1,num2);
      tr=MathMax(tr,num3);
      //---- counting plus/minus direction
      if(tr==0) { PdmBuffer[i]=0; MdmBuffer[i]=0; TrBuffer[i]=0; }
      else      { PdmBuffer[i]=pdm; MdmBuffer[i]=mdm; TrBuffer[i]=tr; }
      //----
      i--;
     }
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
//---- apply EMA to ±DI
   for(i=0; i<=limit; i++)
   {  //iMAOnArray
      PlusDiBuffer[i]=100 * iMAOnArray(PdmBuffer,Bars,ADXPeriod,0,MODE_EMA,i) / iMAOnArray(TrBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
      MinusDiBuffer[i]=100 * iMAOnArray(MdmBuffer,Bars,ADXPeriod,0,MODE_EMA,i) / iMAOnArray(TrBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
   }   
      
//---- Directional Movement (DX)
   i=Bars-2;
   TempBuffer[i+1]=0;
   i=starti;
   while(i>=0)
     {
      double div=MathAbs(PlusDiBuffer[i]+MinusDiBuffer[i]);
      if(div==0.00) TempBuffer[i]=0;
      else TempBuffer[i]=100*(MathAbs(PlusDiBuffer[i]-MinusDiBuffer[i])/div);
      i--;
     }
//---- ADX is exponential moving average on DX
   for(i=0; i<limit; i++)
      ADXBuffer[i]=iMAOnArray(TempBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
//----
   return(0);
  }
//+------------------------------------------------------------------+--------------+
Average Directional Movement Index, ADX
Average Directional Movement Index, ADX
  • www.mql5.com
Average Directional Movement Index Technical Indicator (ADX) helps to determine if there is a price trend. It was developed and described in detail by Welles Wilder in his book "New concepts in technical trading systems". The simplest trading method based on the system of directional movement implies comparison of two direction indicators: the...
 
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;

An "Array out of Range" error occurs because when "counted_bars" is 0, "limit" is equal to "Bars" 

 
Nagisa Unada:

An "Array out of Range" error occurs because when "counted_bars" is 0, "limit" is equal to "Bars" 

Tried but still note fixed.

I'm rewriting the whole code based on some other approach now so might solve it eventually.

Thank you very much. 

 
yum1573:

Tried but still note fixed.

I've not fixed your program, I'm just pointing out where it's causing the trouble.  Don't you understand that?

 
Nagisa Unada:

I've not fixed your program, I'm just pointing out where it's causing the trouble.  Don't you understand that?

I think I understood. I checked & modified where you mentioned as well as other possible miscounting places but seems to be not that problem.

Thanks anyway:)