//+------------------------------------------------------------------+
//|                                         dynamic zone wilders ADX |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  DeepSkyBlue
#property indicator_color2  LimeGreen
#property indicator_width1  2
#property indicator_minimum 0

//
//
//
//
//

#import "dynamicZone.dll"
   double dzBuy(double& sourceArray[],double probabiltyValue, int lookBack, int bars, int i );
   double dzSell(double& sourceArray[],double probabiltyValue, int lookBack, int bars, int i );
#import

//
//
//
//
//

extern int    AdxLength           = 14;
extern int    AdxPrice            = PRICE_CLOSE;
extern int    DzLookBackBars      = 35;
extern double DzStartProbability  = 0.12;

//
//
//
//
//

double adx[];
double sli[];
double DIp[];
double DIm[];
double averageDIp[];
double averageDIm[];
double averageTR[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(7);
   SetIndexBuffer(0,adx); SetIndexLabel(0,"ADX");
   SetIndexBuffer(1,sli);
   SetIndexBuffer(2,DIp);
   SetIndexBuffer(3,DIm);
   SetIndexBuffer(4,averageDIp);
   SetIndexBuffer(5,averageDIm);
   SetIndexBuffer(6,averageTR);

   //
   //
   //
   //
   //
   
   string PriceType;
      switch(AdxPrice)
      {
         case PRICE_CLOSE:    PriceType = "Close";    break;  // 0
         case PRICE_OPEN:     PriceType = "Open";     break;  // 1
         case PRICE_HIGH:     PriceType = "High";     break;  // 2
         case PRICE_LOW:      PriceType = "Low";      break;  // 3
         case PRICE_MEDIAN:   PriceType = "Median";   break;  // 4
         case PRICE_TYPICAL:  PriceType = "Typical";  break;  // 5
         case PRICE_WEIGHTED: PriceType = "Weighted"; break;  // 6
      }      

   //
   //
   //
   //
   //

   AdxLength = MathMax(AdxLength ,1);
   IndicatorShortName ("Dynamic zone Wilder\'s ADX ("+AdxLength+","+PriceType+","+DzLookBackBars+","+DoubleToStr(DzStartProbability,3)+")");
   return(0);
}
int deinit()
{
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
   int i,limit;

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit = MathMin(Bars-counted_bars,Bars-1);

   //
   //
   //
   //
   //
   //

   double sf = 1.0/AdxLength;
      for(i=limit; i >= 0; i--)
      {
         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;      
         
         //
         //
         //
         //
         //
         
            averageDIp[i] = averageDIp[i+1] + sf*(plusDM  - averageDIp[i+1]);
            averageDIm[i] = averageDIm[i+1] + sf*(minusDM - averageDIm[i+1]);
            averageTR[i]  = averageTR[i+1]  + sf*(currTR  - averageTR[i+1]);

         //
         //
         //
         //
         //
                  
            DIp[i] = 0.00;                   
            DIm[i] = 0.00;                   
            if (averageTR[i] > 0)
               {              
                  DIp[i] = 100.00 * averageDIp[i]/averageTR[i];
                  DIm[i] = 100.00 * averageDIm[i]/averageTR[i];
               }            

               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] = adx[i+1] + sf*(DX - adx[i+1]); 
               
         //
         //
         //
         //
         //
                        
         sli[i] = dzSell(adx,DzStartProbability, DzLookBackBars, Bars, i);
      }
   return(0);
}

