//+------------------------------------------------------------------+
//|                                         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  4
#property indicator_width2  4
#property indicator_minimum -150
#property indicator_maximum 150

//
//
//
//
//

#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    Length              = 21;
extern double Speed               = 8.0;
extern bool   Adaptive            = true;
extern int    SmoothLength        = 5;
extern bool   SmoothAdaptive      = true;
extern double SmoothSpeed         = 8.0;
extern int    DzLookBackBars      = 35;
extern double DzStartProbability  = 0.75;

//
//
//
//
//



double dmx[];
double sli[];
double stored[][28];

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

int init()
{
   
   SetIndexBuffer(0,dmx ); SetIndexLabel(0,"Dmx");
   SetIndexBuffer(1,sli);
      
   SmoothLength = MathMax(SmoothLength,1);
   
   IndicatorShortName ("Dynamic zone dmx oma ("+Length+","+Speed+","+Adaptive+","+SmoothLength+","+SmoothAdaptive+","+SmoothSpeed+","+DzLookBackBars+","+DoubleToStr(DzStartProbability,3)+")");
   return(0);
}
int deinit()
{
   return(0);
}

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

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

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   if (ArrayRange(stored,0) != Bars) ArrayResize(stored,Bars);

   //
   //
   //
   //
   //
   
   for(i=limit, r=Bars-limit-1; i>=0; i--,r++)
   {
      double currTR  = iAverage(MathMax(High[i],Close[i+1])-MathMin(Low[i],Close[i+1]),Length,Speed,Adaptive,r,0);
      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;      
         
         double DIp = 0.00;
         double DIm = 0.00;

            if (currTR > 0.00)
            {
               DIp = 100.0*iAverage(plusDM ,Length,Speed,false,r,7)/currTR;
               DIm = 100.0*iAverage(minusDM,Length,Speed,false,r,14)/currTR;
            }
            if ((DIp+DIm) != 0)
                  dmx[i] = 100.00*iAverage((DIp-DIm)/(DIp+DIm),SmoothLength,SmoothSpeed,SmoothAdaptive,r,21);
            else  dmx[i] = 100.00*iAverage(0                  ,SmoothLength,SmoothSpeed,SmoothAdaptive,r,21);
                        
         sli[i] = dzSell(dmx,DzStartProbability, DzLookBackBars, Bars, i);
      }
   return(0);
}



#define E1  0
#define E2  1
#define E3  2
#define E4  3
#define E5  4
#define E6  5
#define res 6

//
//
//
//
//

double iAverage(double price, double averagePeriod, double const1, bool adaptive, int r, int ashift=0)
{
   double e1=stored[r-1][E1+ashift];  double e2=stored[r-1][E2+ashift];
   double e3=stored[r-1][E3+ashift];  double e4=stored[r-1][E4+ashift];
   double e5=stored[r-1][E5+ashift];  double e6=stored[r-1][E6+ashift];

   //
   //
   //
   //
   //

      if (adaptive && (averagePeriod > 1))
      {
         double minPeriod = averagePeriod/2.0;
         double maxPeriod = minPeriod*5.0;
         int    endPeriod = MathCeil(maxPeriod);
         double signal    = MathAbs((price-stored[r-endPeriod][res]));
         double noise     = 0.00000000001;

            for(int k=1; k<endPeriod; k++) noise=noise+MathAbs(price-stored[r-k][res]);

         averagePeriod = ((signal/noise)*(maxPeriod-minPeriod))+minPeriod;
      }
      
      //
      //
      //
      //
      //
      
      double alpha = (2.0+const1)/(1.0+const1+averagePeriod);

      e1 = e1 + alpha*(price-e1); e2 = e2 + alpha*(e1-e2); double v1 = 1.5 * e1 - 0.5 * e2;
      e3 = e3 + alpha*(v1   -e3); e4 = e4 + alpha*(e3-e4); double v2 = 1.5 * e3 - 0.5 * e4;
      e5 = e5 + alpha*(v2   -e5); e6 = e6 + alpha*(e5-e6); double v3 = 1.5 * e5 - 0.5 * e6;

   //
   //
   //
   //
   //

   stored[r][E1+ashift]  = e1;  stored[r][E2+ashift] = e2;
   stored[r][E3+ashift]  = e3;  stored[r][E4+ashift] = e4;
   stored[r][E5+ashift]  = e5;  stored[r][E6+ashift] = e6;
   stored[r][res+ashift] = price;
   return(v3);
}