ADXWilder procedure in MT4

 

I already tried it myself and I got returns of zeros.

here is my attempt:

double SmoothedMA(const int position,const int period,const double prev_value,const double &price[])
  {
   double result=0.0;
   if(period>0)
     {
      if(position==period-1)
        {
         for(int i=0;i<period;i++) result+=price[position-i];
         result/=period;
        }
      if(position>=period)
         result=(prev_value*(period-1)+price[position])/period;
     }
   return(result);
  }
  
  
double iADXWilder(string symbol, int timeframe, int period, int applied_price, int mode, int shift)
{
   int i=0;

   double ExtADXWBuffer[600];
   double ExtPDIBuffer [600];
   double ExtNDIBuffer [600];
   double ExtPDSBuffer [600];
   double ExtNDSBuffer [600];
   double ExtPDBuffer  [600];
   double ExtNDBuffer  [600];
   double ExtTRBuffer  [600];
   double ExtATRBuffer [600];
   double ExtDXBuffer  [600];
   
   int period2=period;
   if(period>100) period2=100;
   if(period<0) period2=0;
   
   for(i=500;i>=0;i--) {
      
      double Hi    =iHigh(Symbol(), timeframe, i);
      double prevHi=iHigh(Symbol(), timeframe, i+1);
      double Lo    =iLow (Symbol(), timeframe, i);
      double prevLo=iLow (Symbol(), timeframe, i+1);
      double prevCl=iClose(Symbol(), timeframe, i+1);
      
      double dTmpP=Hi-prevHi;
      double dTmpN=prevLo-Lo;
      if(dTmpP<0.0) dTmpP=0.0;
      if(dTmpN<0.0) dTmpN=0.0;
      if(dTmpN==dTmpP)
        {
         dTmpN=0.0;
         dTmpP=0.0;
        }
      else
        {
         if(dTmpP<dTmpN) dTmpP=0.0;
         else            dTmpN=0.0;
        }
      ExtPDBuffer[i]=dTmpP;
      ExtNDBuffer[i]=dTmpN;
      double tr=MathMax(MathMax(MathAbs(Hi-Lo),MathAbs(Hi-prevCl)),MathAbs(Lo-prevCl));
      ExtTRBuffer[i]=tr;
      if(i<period2)
        {
         ExtATRBuffer[i]=0.0;
         ExtPDIBuffer[i]=0.0;
         ExtNDIBuffer[i]=0.0;
        }
      else
        {
         ExtATRBuffer[i]=SmoothedMA(i,period2,ExtATRBuffer[i+1],ExtTRBuffer);
         ExtPDSBuffer[i]=SmoothedMA(i,period2,ExtPDSBuffer[i+1],ExtPDBuffer);
         ExtNDSBuffer[i]=SmoothedMA(i,period2,ExtNDSBuffer[i+1],ExtNDBuffer);
        }
      if(ExtATRBuffer[i]!=0.0)
        {
         ExtPDIBuffer[i]=100.0*ExtPDSBuffer[i]/ExtATRBuffer[i];
         ExtNDIBuffer[i]=100.0*ExtNDSBuffer[i]/ExtATRBuffer[i];
        }
      else
        {
         ExtPDIBuffer[i]=0.0;
         ExtNDIBuffer[i]=0.0;
        }
      double dTmp=ExtPDIBuffer[i]+ExtNDIBuffer[i];
      if(dTmp!=0.0) dTmp=100.0*MathAbs((ExtPDIBuffer[i]-ExtNDIBuffer[i])/dTmp);
      else          dTmp=0.0;
      ExtDXBuffer[i]=dTmp;
      ExtADXWBuffer[i]=SmoothedMA(i,period2,ExtADXWBuffer[i+1],ExtDXBuffer);
   }
      
   switch(mode) {
   case 0: return ExtADXWBuffer[shift]; break;
   case 1: return ExtPDIBuffer[shift]; break;
   case 2: return ExtNDIBuffer[shift]; break;
   }   
}



void OnTick()
  {
   if(Bars<100 || IsTradeAllowed()==false)
      return;
   Alert("adx wilder=", iADXWilder(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE, MODE_MAIN, 0) );
   Alert("adx=",        iADX(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE, MODE_MAIN, 0) );
  }

does anyone knwo how to fix it?

i even created a job in MQL5 freelance section but the guy that applied failed to deliver working procedure

Whoever post the fix that is working here as a first working solution response,

I will accept your offer there for 10 credits (i will wait if you need to register or something) and give you 5 star feedback in the freelancing section.

I am not a fraudster, please check my profile and product reviews:

https://www.mql5.com/en/users/angreeee

Here is te freelance job:

https://www.mql5.com/en/job/16155

 
ok someone already is doing that job. If he fails, i will post information about it
 
angreeee:

I already tried it myself and I got returns of zeros.

here is my attempt:

does anyone knwo how to fix it?

  1. Your main code is counting down. Zero is the latest.

    Your MA code is counting up. Zero is the oldest.

    Changes indicated

    double SmoothedMA(const int position,const int period,const int nBars,const double prev_value,const double &price[]) 
      {
       double result=0.0;
       if(period>0)
         {
          if(position == nBars - period)
            {
             for(int i=0;i<period;i++) result+=price[position+i];
             result/=period;
            }
          if(position < nBars - period)
             result=(prev_value*(period-1)+price[position])/period;
         }
       return(result);
      }
      
    :
       #define nBars 501
       double ExtADXWBuffer[nBars];
    :
       for(i=nBars - 1;i>=0;i--) {
    :
    
          if(i > nBars - period2)
            {
             ExtATRBuffer[i]=0.0;
             ExtPDIBuffer[i]=0.0;
             ExtNDIBuffer[i]=0.0;
            }
          else
            {
             ExtATRBuffer[i]=SmoothedMA(i,period2,nBars,ExtATRBuffer[i+1],ExtTRBuffer);
             ExtPDSBuffer[i]=SmoothedMA(i,period2,nBars,ExtPDSBuffer[i+1],ExtPDBuffer);
             ExtNDSBuffer[i]=SmoothedMA(i,period2,nBars,ExtNDSBuffer[i+1],ExtNDBuffer);
            }
    

  2. Why didn't you just take a working ADX such as Free download of the 'Average Directional Movement Index, ADX' indicator for MetaTrader 4 in the MQL5 Code Base and simply modify it?
    // for(i=0; i<=limit; i++)
    //    PlusDiBuffer[i]=iMAOnArray(PlusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
       for(i=limit; i>=0; i--)
          PlusDiBuffer[i]=SmoothedMA(i,ADXPeriod,Bars,PlusSdiBuffer[i+1],PlusSdiBuffer);
                                                                                           
    //---- apply EMA to -DI                                                                
    // for(i=0; i<=limit; i++)
    //    MinusDiBuffer[i]=iMAOnArray(MinusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
       for(i=limit; i>=0; i--)
          MinusDiBuffer[i]=SmoothedMA(i,ADXPeriod,Bars,MinusSdiBuffer[i+1],MinusSdiBuffer);
                                                                                           
    //---- 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);
       for(i=limit; i>=0; i--)
          ADXBuffer[i]=SmoothedMA(i,ADXPeriod,Bars,MinusSdiBuffer[i+1],MinusSdiBuffer);
    //----
    

  3. This is not stable in the presence of round off (magnifies errors)
    result=(prev_value*(period-1)+price[position])/period;
    Always use this form of EMA:
    result=prev_value + (price[position] - prev_value) / period;
 

I did not modify the indicator as i have problems understanding them (low experience levels with indicators) - converting very simple keltner channels to procedure took me 3 days.. (and i was doing it from the specification, not from the indicator code) And KC is not anywhere near the ADX Wilder. Thank You!

You are the only person that managed to solve my problems and as only one you did it for free and very fast.

I would like to pay You at least that 10 credits that i promised for completing th task, please apply for my job there:

https://www.mql5.com/en/job/16155 

i will accept your job and transfer you funds.

here is the end result of the EA(it is still off by some 0.04, but i think its because of the limited amount bars examined, ssma has no limit for the bars it calculates its value on, so the more bars i will use the more accurate the result):

It is still not perfect but i can work with it from here!

 

double SmoothedMA(const int position,const int period,const int nBars,const double prev_value,const double &price[]) 
  {
   double result=0.0;
   if(period>0)
     {
      if(position == nBars - period)
        {
         for(int i=0;i<period;i++) result+=price[position+i];
         result/=period;
        }
      if(position < nBars - period)
         result=prev_value + (price[position] - prev_value) / period;
     }
   return(result);
  }
  
  



        
double iADXWilder(string symbol, int timeframe, int period, int applied_price, int mode, int shift)
{
   int i=0;

   double ExtADXWBuffer[600];
   double ExtPDIBuffer [600];
   double ExtNDIBuffer [600];
   double ExtPDSBuffer [600];
   double ExtNDSBuffer [600];
   double ExtPDBuffer  [600];
   double ExtNDBuffer  [600];
   double ExtTRBuffer  [600];
   double ExtATRBuffer [600];
   double ExtDXBuffer  [600];
   #define nBars 501
   //double ExtADXWBuffer[nBars];

   int period2=period;
   if(period>100) period2=100;
   if(period<0) period2=0;
   
   for(i=nBars - 1;i>=0;i--) {   
      
      double Hi    =iHigh(Symbol(), timeframe, i);
      double prevHi=iHigh(Symbol(), timeframe, i+1);
      double Lo    =iLow (Symbol(), timeframe, i);
      double prevLo=iLow (Symbol(), timeframe, i+1);
      double prevCl=iClose(Symbol(), timeframe, i+1);
      
      double dTmpP=Hi-prevHi;
      double dTmpN=prevLo-Lo;
      if(dTmpP<0.0) dTmpP=0.0;
      if(dTmpN<0.0) dTmpN=0.0;
      if(dTmpN==dTmpP)
        {
         dTmpN=0.0;
         dTmpP=0.0;
        }
      else
        {
         if(dTmpP<dTmpN) dTmpP=0.0;
         else            dTmpN=0.0;
        }
      ExtPDBuffer[i]=dTmpP;
      ExtNDBuffer[i]=dTmpN;
      double tr=MathMax(MathMax(MathAbs(Hi-Lo),MathAbs(Hi-prevCl)),MathAbs(Lo-prevCl));
      ExtTRBuffer[i]=tr;

      if(i > nBars - period2)
        {
         ExtATRBuffer[i]=0.0;
         ExtPDIBuffer[i]=0.0;
         ExtNDIBuffer[i]=0.0;
        }
      else
        {
         ExtATRBuffer[i]=SmoothedMA(i,period2,nBars,ExtATRBuffer[i+1],ExtTRBuffer);
         ExtPDSBuffer[i]=SmoothedMA(i,period2,nBars,ExtPDSBuffer[i+1],ExtPDBuffer);
         ExtNDSBuffer[i]=SmoothedMA(i,period2,nBars,ExtNDSBuffer[i+1],ExtNDBuffer);
        }
      if(ExtATRBuffer[i]!=0.0)
        {
         ExtPDIBuffer[i]=100.0*ExtPDSBuffer[i]/ExtATRBuffer[i];
         ExtNDIBuffer[i]=100.0*ExtNDSBuffer[i]/ExtATRBuffer[i];
        }
      else
        {
         ExtPDIBuffer[i]=0.0;
         ExtNDIBuffer[i]=0.0;
        }
      double dTmp=ExtPDIBuffer[i]+ExtNDIBuffer[i];
      if(dTmp!=0.0) dTmp=100.0*MathAbs((ExtPDIBuffer[i]-ExtNDIBuffer[i])/dTmp);
      else          dTmp=0.0;
      ExtDXBuffer[i]=dTmp;
      ExtADXWBuffer[i]=SmoothedMA(i,period2,nBars,ExtADXWBuffer[i+1],ExtDXBuffer);
   }
      
   switch(mode) {
   case 0: return ExtADXWBuffer[shift]; break;
   case 1: return ExtPDIBuffer[shift]; break;
   case 2: return ExtNDIBuffer[shift]; break;
   }   
}



void OnTick()
  {
   if(Bars<100 || IsTradeAllowed()==false)
      return;
   Alert("adx wilder=", iADXWilder(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE, MODE_MAIN, 0) );
   Alert("adx=",        iADX(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE, MODE_MAIN, 0) );
  }