//+------------------------------------------------------------------+
//|                                                 Wilder's DMI.mq4 |
//|                                                  coded by mladen |
//|                                                                  |
//| Directional movement index was developed by Welles Wilder        |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "www.forex-tsd,com"

#property indicator_separate_window
#property  indicator_buffers 7
#property indicator_color1   LimeGreen
#property indicator_color2   PaleVioletRed
#property indicator_color3   Green
#property indicator_color4   Tomato
#property indicator_color5   DimGray
#property indicator_color6   Orange
#property indicator_color7   DimGray
#property indicator_width5   2 
#property indicator_width6   2 
#property indicator_style7   STYLE_DOT

//
//
//
//
//

extern int  DMI.Length =    14;
extern bool ShowADX    =  true;
extern bool ShowADXR   = false;
extern int  Level      =    20;

//
//
//
//
//

double DIp[];
double DIm[];
double ADX[];
double ADXR[];
double ADXLevel[];
double dihp[];
double dihm[];


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//

int init()
{
   SetIndexBuffer(0,dihp);     SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(1,dihm);     SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(2,DIp);      SetIndexLabel(2,"DI+");
   SetIndexBuffer(3,DIm);      SetIndexLabel(3,"DI-");
   SetIndexBuffer(4,ADX);      SetIndexLabel(4,"ADX");
   SetIndexBuffer(5,ADXR);     SetIndexLabel(5,"ADXR");
   SetIndexBuffer(6,ADXLevel); SetIndexLabel(6,NULL);
      for (int i=0;i<8;i++) SetIndexEmptyValue(i,0.00);

   //
   //
   //
   //
   //

   IndicatorShortName("Wilder\'s DMI ("+DMI.Length+")");
   return(0);
}

int deinit()
{
   return(0);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

double work[][3];
#define _DIp 0
#define _DIm 1
#define _TR  2

int start()
{
   int i,r,counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-2);
           if (ArrayRange(work,0)!=Bars) ArrayResize(work,Bars);

   //
   //
   //
   //
   //
   
   double sf = (DMI.Length-1.0)/DMI.Length;
      for (i=limit, r=Bars-i-1;i>=0;i--,r++)
      {
         double currTR  = MathMax(High[i],Close[i+1])-MathMin(Low[i],Close[i+1]);
         double DeltaHi = High[i] - High[i+1];
	      double DeltaLo = Low[i+1] - Low[i];
         double plusDM  = 0.00;
         double minusDM = 0.00;
         
            if ((DeltaHi > DeltaLo) && (DeltaHi > 0)) plusDM  = DeltaHi;
            if ((DeltaLo > DeltaHi) && (DeltaLo > 0)) minusDM = DeltaLo;      
         
         //
         //
         //
         //
         //
         
            work[r][_DIp] = sf*work[r-1][_DIp] + plusDM;
            work[r][_DIm] = sf*work[r-1][_DIm] + minusDM;
            work[r][_TR]  = sf*work[r-1][_TR]  + currTR;
            ADXLevel[i]   = Level;

         //
         //
         //
         //
         //
                  
            DIp[i]  = 0;                   
            DIm[i]  = 0;                   
            dihp[i] = 0;
            dihp[i] = 0;
            if (work[r][_TR] > 0)
               {              
                  DIp[i] = 100.00 * work[r][_DIp]/work[r][_TR];
                  DIm[i] = 100.00 * work[r][_DIm]/work[r][_TR];
               }            
               if (DIp[i]>DIm[i]) dihp[i] = DIp[i]-DIm[i];
               if (DIp[i]<DIm[i]) dihm[i] = DIp[i]-DIm[i];
            if(ShowADX)
               {
                  double DX;
                  if((DIp[i] + DIm[i])>0) 
                       DX = 100*MathAbs(DIp[i] - DIm[i])/(DIp[i] + DIm[i]); 
                  else DX = 0.00;
                  ADX[i] = sf*ADX[i+1] + DX/DMI.Length; 
                  if(ShowADXR)
                         ADXR[i] = 0.5*(ADX[i] + ADX[i+DMI.Length]);
               }
      }   
   return(0);      
}