//+------------------------------------------------------------------+
//|                                               Wilder DMI_MOD.mq4 |
//|                                      Copyright © 2015, Ghoul007. |
//|                             http://www.forexfactory.com/ghoul007 |
//+------------------------------------------------------------------+
#property copyright "Ghoul007"
#property link      "http://www.forexfactory.com/ghoul007"
#property strict
#property version "1.000"
#property description "A clone of the Wilder Directonal Movement Index (DMI) indicator"
#property description "MOD indicating that it modifies in Real Time, ie on every tick."

#property indicator_separate_window
#property indicator_buffers   7
#property indicator_minimum 0
#property indicator_maximum 1
#property indicator_color1    Lime
#property indicator_width1    7
#property indicator_color2    Gray
#property indicator_width2    7
#property indicator_color3    Red
#property indicator_width3    7
//#property indicator_color4    Orange
//#property indicator_width4    2
//#property indicator_level1    20
//---- input parameters
extern int       MA_Length=1; // Period of additional smoothing 
extern int       DMI_Length  =14; // Period of DMI
extern int       ADX_Length  =14; // Period of ADX
extern int       ADXR_Length =14; // Period of ADXR
extern int       UseADX     =1; // Use ADX: 0-off,1-on
extern int       UseADXR    =1; // Use ADXR: 0-off,1-on
//---- buffers
double Buy[];
double Wait[];
double Sell[];
double ADX[];
double PDI[];
double MDI[];
double ADXR[];
double sPDI[];
double sMDI[];
double STR[];
double DX[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(11);
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,Buy);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(1,Wait);
   SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(2,Sell);
//SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(3,ADX);
//SetIndexStyle(4,DRAW_LINE);
   SetIndexBuffer(4,PDI);
//SetIndexStyle(5,DRAW_LINE);
   SetIndexBuffer(5,MDI);
//SetIndexStyle(6,DRAW_LINE);
   SetIndexBuffer(6,ADXR);
   SetIndexBuffer(7,sPDI);
   SetIndexBuffer(8,sMDI);
   SetIndexBuffer(9,STR);
   SetIndexBuffer(10,DX);
//---- name for DataWindow and indicator subwindow label
   string short_name="DMI_MOD("+MA_Length+","+DMI_Length+","+ADX_Length+","+ADXR_Length+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,"Buy");
   SetIndexLabel(1,"Wait");
   SetIndexLabel(2,"Sell");
   SetIndexLabel(3,"ADX");
   SetIndexLabel(4,"+DI");
   SetIndexLabel(5,"-DI");
   SetIndexLabel(6,"ADXR");
//----
   SetIndexDrawBegin(3,DMI_Length+MA_Length);
   SetIndexDrawBegin(4,DMI_Length+MA_Length);
   SetIndexDrawBegin(5,DMI_Length+MA_Length);
   SetIndexDrawBegin(6,DMI_Length+MA_Length);
   SetIndexShift(6,2);
   SetIndexShift(3,0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int      shift,limit,counted_bars=IndicatorCounted();
   double alfa1=1.0/DMI_Length;
   double alfa2=1.0/ADX_Length;
//---- 
   if(counted_bars < 0) return(-1);
   if(counted_bars<1)
      for(shift=1;shift<=MA_Length+DMI_Length;shift++)
        {
         PDI[Bars-shift]=0.0;MDI[Bars-shift]=0.0;ADX[Bars-shift]=0.0;
         sPDI[Bars-shift]=0.0;sMDI[Bars-shift]=0.0;DX[Bars-shift]=0.0;
         STR[Bars-shift]=0.0;ADXR[Bars-shift]=0.0;
        }
   shift=Bars-MA_Length-DMI_Length-1;
   if(counted_bars>=DMI_Length+MA_Length) shift=Bars-counted_bars-1;
   while(shift>=0)
     {
      double AvgHigh =iMA(NULL,0,MA_Length,0,1,PRICE_HIGH,shift);
      double AvgHigh1=iMA(NULL,0,MA_Length,0,1,PRICE_HIGH,shift+1);
      double AvgLow  =iMA(NULL,0,MA_Length,0,1,PRICE_LOW,shift);
      double AvgLow1 =iMA(NULL,0,MA_Length,0,1,PRICE_LOW,shift+1);
      double AvgClose1=iMA(NULL,0,MA_Length,0,1,PRICE_CLOSE,shift+1);
      //----
      double Bulls=0.5*(MathAbs(AvgHigh-AvgHigh1)+(AvgHigh-AvgHigh1));
      double Bears=0.5*(MathAbs(AvgLow1-AvgLow)+(AvgLow1-AvgLow));
      if(Bulls>Bears) Bears=0;
      else
         if(Bulls<Bears) Bulls=0;
      else
      if(Bulls==Bears) {Bulls=0;Bears=0;}
      //----            
      sPDI[shift]=sPDI[shift+1] + alfa1 * (Bulls - sPDI[shift+1]);
      sMDI[shift]=sMDI[shift+1] + alfa1 * (Bears - sMDI[shift+1]);
      //----      
      double   TR=MathMax(AvgHigh-AvgLow,AvgHigh-AvgClose1);
      STR[shift] =STR[shift+1] + alfa1 * (TR - STR[shift+1]);
      if(STR[shift]>0)
        {
         PDI[shift]=100*sPDI[shift]/STR[shift];
         MDI[shift]=100*sMDI[shift]/STR[shift];
        }
      if(UseADX>0)
        {
         if((PDI[shift]+MDI[shift])>0)
            DX[shift]=100*MathAbs(PDI[shift]-MDI[shift])/(PDI[shift]+MDI[shift]);
         else DX[shift]=0;
         //----
         ADX[shift]=ADX[shift+1]+alfa2 *(DX[shift]-ADX[shift+1]);
         if(UseADXR>0) ADXR[shift]=0.5*(ADX[shift]+ADX[shift+ADXR_Length]);
        }
      shift--;
     }
//----
   int s,l,c=IndicatorCounted();

   if( c < 0 ) return(-1);
   if(c==0)
      l=Bars;
   if(c>0)
      l=Bars-counted_bars;
   l--;

   for(s=l; s>=0; s--)
     {
      if(PDI[s]>20 && MDI[s]<20 && ADX[s]>20 && ADX[s]<PDI[s] && ADXR[s+2]>20)
        {
         Buy[s]=1;
         Sell[s]=0;
         Wait[s]=0;
        }
      if(PDI[s]<20 && MDI[s]>20 && ADX[s]>20 && ADX[s]<MDI[s] && ADXR[s+2]>20)
        {
         Buy[s]=0;
         Sell[s]=1;
         Wait[s]=0;
        }
      if(Buy[s]+Sell[s]>1)
        {
         Buy[s]=0;
         Sell[s]=0;
         Wait[s]=1;
        }
     }
   return(0);
  }
//+------------------------------------------------------------------+
