Here is my example usage:
double ahigh[]={30.20,30.28,30.45,29.35,29.35,29.29,28.83,28.73,28.67,28.85,28.64,27.68,27.21,26.87,27.41,26.94};
Print("\n adx = "+DoubleToStr(adx));
I am getting an ADX value of 105.92. But ADX is supposed to be between 0 and 100, inclusive.
I think I have hit something:
//+------------------------------------------------------------------+
//| iADXOnArray |
//+------------------------------------------------------------------+
/*
Calculate ADX on array.
Data Length has to 15 or more to calculate DX.
-1 will be the result if array has insufficient data.
*/
double iADXOnArray(double& aHigh[], double& aLow[], double& aClose[]){
double pdm=0,mdm=0,tr=0,pdm_sum=0,mdm_sum=0,tr_sum=0,plusDI=0,minusDI=0,DIdiff=0,DIsum=0;
double price_high,price_low,DX=0;
double previous_pdm_sum=0,previous_mdm_sum=0,previous_tr_sum=0;
int i=0,j=0,k=1,min=14;
int length=ArrayRange(aClose,0);
int ADXPeriod=length,dxlength=0,old_dxlength=0,adxlength=0,old_adxlength=0;
double ADXresult=-1;
double DXarr[],ADXarr[];
i=1;
while(i<length && length>1)
{
price_low=aLow[i];
price_high=aHigh[i];
//If High(i) - High(i-1) > 0 dm_plus(i) = High[(i) - High(i-1), otherwise dm_plus(i) = 0.
pdm=price_high-aHigh[i-1];
if(pdm <= 0)pdm=0;
//If Low(i-1) - Low(i) > 0 dm_minus(i) = Low(i-1) - Low(i), otherwise dm_minus(i) = 0.
mdm=aLow[i-1]-price_low;
if(mdm <= 0)mdm=0;
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-aClose[i-1]);
double num3=MathAbs(aClose[i-1]-price_low);
tr=MathMax(num1,num2);
tr=MathMax(tr,num3);
if(i<=min)
{
pdm_sum = pdm_sum + pdm;
mdm_sum = mdm_sum + mdm;
tr_sum= tr_sum + tr;
}
else if(i>min)
{
pdm_sum = (previous_pdm_sum - (previous_pdm_sum/14)) + pdm;
mdm_sum = (previous_mdm_sum - (previous_mdm_sum/14)) + mdm;
tr_sum = (previous_tr_sum - (previous_tr_sum/14)) + tr;
}
plusDI = (pdm_sum/tr_sum)*100;
minusDI = (mdm_sum/tr_sum)*100;
DIdiff = plusDI - minusDI;
DIdiff = MathAbs(DIdiff);
DIsum = plusDI + minusDI;
DX = (DIdiff/DIsum)*100;
if(i>=min)
{
old_dxlength = ArrayRange(DXarr,0);
dxlength= old_dxlength+1;
ArrayResize(DXarr, dxlength);
DXarr[old_dxlength] = DX;
previous_pdm_sum = pdm_sum;
previous_mdm_sum = mdm_sum;
previous_tr_sum = tr_sum;
}
//---- ADX is simple/exponential moving average on DX
if(dxlength == min)
{
ADXPeriod = (length-min);
old_adxlength = ArrayRange(ADXarr,0);
adxlength = old_adxlength + 1;
ArrayResize(ADXarr, adxlength);
ADXarr[0] = iMAOnArray(DXarr,0,dxlength,0,MODE_EMA,0);
}
else if(dxlength > min)
{
//ADXt= ( ( ADXt-1 * ( n - 1) ) + DXt ) / n
old_adxlength = ArrayRange(ADXarr,0);
adxlength = old_adxlength + 1;
ArrayResize(ADXarr, adxlength);
ADXarr[old_adxlength] = ( ( (ADXarr[old_adxlength-1] * 13) + DX) / 14 );
}
i++;
}
//----use ADX array size
if(adxlength > 0)
{
ADXresult = ADXarr[adxlength - 1];
}
else
{
ADXresult = -1;
}
//----
return(ADXresult);
}
//+------------------------------------------------------------------+
//| End of iADXOnArray |
//+------------------------------------------------------------------+
Now, I have read somewhere that the first ADX value is the simple average of DX over 14 periods. Is it Ok, if I use the exponential average of DX for the first ADX value: "ADXarr[0] = iMAOnArray(DXarr,0,dxlength,0,MODE_EMA,0);" instead of "ADXarr[0] = iMAOnArray(DXarr,0,dxlength,0,MODE_SMA,0);" ?
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Good day everyone. I am trying to calculate the ADX value for an entire array. Is there a way I can substitute in my custom array into the iADX that comes with MT4? If not, I am already attempting to build an iADXOnArray function that I would like to be as accurate as if I had used iADX. I would appreciate any help or clarification. This is what I have so far:
edited on 6.3.19
//+------------------------------------------------------------------+
//| iADXOnArray |
//+------------------------------------------------------------------+
/*
Calculate ADX on array.
Data Length has to 15 or more to calculate DX.
-1 will be the result if array has insufficient data.
*/
double iADXOnArray(double& aHigh[], double& aLow[], double& aClose[], int length){
double pdm=-1,mdm=-1,tr=-1,pdm_sum=-1,mdm_sum=-1,tr_sum=-1,plusDI=0,minusDI=0,DIdiff=0,DIsum=0;
double price_high,price_low,DX=-1;
int i=0,j=0,min=15;
int ADXPeriod=length;
//double ADXBuffer[];
double ADXresult=-1;
double DXarr[];
if(length >= 15)
{
ArrayResize(DXarr, length-min);
}
//----
i=1;
while(i<length && length>1)
{
price_low=aLow[i];
price_high=aHigh[i];
//----
pdm=price_high-aHigh[i-1];
mdm=aLow[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-aClose[i-1]);
double num3=MathAbs(aClose[i-1]-price_low);
tr=MathMax(num1,num2);
tr=MathMax(tr,num3);
Print("\n +DM = "+DoubleToStr(pdm));
//Print("\n -DM = "+DoubleToStr(mdm));
pdm_sum = pdm_sum + pdm;
mdm_sum = mdm_sum + mdm;
tr_sum= tr_sum + tr;
plusDI = (pdm_sum/tr_sum)*100;
minusDI = (mdm_sum/tr_sum)*100;
DIdiff = plusDI - minusDI;
DIdiff = MathAbs(DIdiff);
DIsum = plusDI + minusDI;
DX = (DIdiff/DIsum)*100;
if(i>=15)
{
DXarr[j] = DX;
j++;
}
i++;
}
//---- ADX is exponential moving average on DX
if(length >= 15)
{
ADXPeriod = (length-min);
ADXresult = iMAOnArray(DXarr,(length-min),ADXPeriod,0,MODE_EMA,0);
}
else
{
ADXresult = -1;
}
//----
return(ADXresult);
}
//+------------------------------------------------------------------+
//| End of iADXOnArray |
//+------------------------------------------------------------------+
Is this the right approach?