//------------------------------------------------------------------
#property copyright "www.forex-tsd.com"
#property link      "www.forex-tsd.com"
//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1  clrLimeGreen
#property indicator_color2  clrOrange
#property indicator_color3  clrOrange
#property indicator_color4  clrDeepSkyBlue
#property indicator_color5  clrDeepSkyBlue
#property indicator_color6  clrPaleVioletRed
#property indicator_color7  clrPaleVioletRed
#property indicator_color8  clrPeru
#property indicator_width1  2
#property indicator_width2  2
#property indicator_width3  2
#property indicator_style5  STYLE_DOT
#property indicator_style6  STYLE_DOT
#property indicator_style8  STYLE_DASH
#property strict

//
//
//
//
//

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

//
//
//
//
//

extern int                WprPeriod               = 21;         // Wpr period
extern double             T3Period                = 21;         // T3 smoothing period if > 1
extern double             T3Hot                   = 1.0;        // T3 smoothing filter hot
extern bool               T3Original              = false;      // T3 smoothing original Tim Tillson calculation?
extern int                MaPeriod                = 21;         // Ma period
extern ENUM_MA_METHOD     MaMethod                = MODE_SMA;   // Ma method
extern ENUM_APPLIED_PRICE MaPrice                 = PRICE_CLOSE;// Ma price
extern int                AtrLength               = 120;        // Average true range length
extern bool               ShowMiddleLine          = true;       // Show middle line?
extern int                DzLookBackBars          = 49;         // Dynamic zone look back
extern double             DzStartBuyProbability1  = 0.10;       // Dynamic zone buy probability 1
extern double             DzStartBuyProbability2  = 0.25;       // Dynamic zone buy probability 2
extern double             DzStartSellProbability1 = 0.10;       // Dynamic zone sell probability 1
extern double             DzStartSellProbability2 = 0.25;       // Dynamic zone sell probability 2


//
//
//
//
//

double buffer1[];
double buffer2[];
double buffer3[];
double bl1[];
double bl2[];
double sl1[];
double sl2[];
double zli[];
double slope[];

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

int init()
{
   IndicatorBuffers(9);
   SetIndexBuffer(0,buffer1);
   SetIndexBuffer(1,buffer2);
   SetIndexBuffer(2,buffer3);
   SetIndexBuffer(3,bl1);
   SetIndexBuffer(4,bl2);
   SetIndexBuffer(5,sl2);
   SetIndexBuffer(6,sl1);
   SetIndexBuffer(7,zli);
   SetIndexBuffer(8,slope);  

   IndicatorShortName("dz %r");
   return(0);
}
int deinit() { return(0); }

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

int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1);
      
   //
   //
   //
   //
   //
   
      if (slope[limit]==-1) CleanPoint(limit,buffer2,buffer3);
      for (int i=limit; i>=0; i--) 
      { 
          double maValue;
          double wpr;
          maValue   = iMA(NULL,0,MaPeriod,0,MaMethod,MaPrice,i);
          double hi = High[iHighest(NULL,0,MODE_HIGH,WprPeriod,i)];
          double lo =  Low[iLowest(NULL, 0,MODE_LOW, WprPeriod,i)];
          if (hi!=lo)      
               wpr = iT3(-100*(hi-Close[i])/(hi-lo),T3Period,T3Hot,T3Original,i,0);
          else wpr = iT3(0,                         T3Period,T3Hot,T3Original,i,0);
          double rng = iATR(NULL,0,AtrLength,i);
          buffer1[i] = maValue+(wpr+50)/100*rng;
          
          if (DzStartBuyProbability1 >0) bl1[i] = dzBuyP (buffer1, DzStartBuyProbability1,  DzLookBackBars, Bars, i, 0.0001);
          if (DzStartBuyProbability2 >0) bl2[i] = dzBuyP (buffer1, DzStartBuyProbability2,  DzLookBackBars, Bars, i, 0.0001);
          if (DzStartSellProbability1>0) sl1[i] = dzSellP(buffer1, DzStartSellProbability1, DzLookBackBars, Bars, i, 0.0001);
          if (DzStartSellProbability2>0) sl2[i] = dzSellP(buffer1, DzStartSellProbability2, DzLookBackBars, Bars, i, 0.0001);
          if (ShowMiddleLine)            zli[i] = dzSellP(buffer1, 0.5                    , DzLookBackBars, Bars, i, 0.0001);
          
          //
          //
          //
          //
          //
            
          buffer2[i] = EMPTY_VALUE;
          buffer3[i] = EMPTY_VALUE;
          slope[i] = (i<Bars-1) ? (buffer1[i]>buffer1[i+1]) ? 1 : (buffer1[i]<buffer1[i+1]) ? -1 : slope[i+1] : 0;
          if (slope[i] == -1) PlotPoint(i,buffer2,buffer3,buffer1);      
   }            
return(0);
} 

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

#define t3Instances 1
double workT3[][t3Instances*6];
double workT3Coeffs[][6];
#define _tperiod 0
#define _c1      1
#define _c2      2
#define _c3      3
#define _c4      4
#define _alpha   5

//
//
//
//
//

double iT3(double price, double period, double hot, bool original, int i, int tinstanceNo=0)
{
   if (ArrayRange(workT3,0) != Bars)                 ArrayResize(workT3,Bars);
   if (ArrayRange(workT3Coeffs,0) < (tinstanceNo+1)) ArrayResize(workT3Coeffs,tinstanceNo+1);

   if (workT3Coeffs[tinstanceNo][_tperiod] != period)
   {
     workT3Coeffs[tinstanceNo][_tperiod] = period;
        double a = hot;
            workT3Coeffs[tinstanceNo][_c1] = -a*a*a;
            workT3Coeffs[tinstanceNo][_c2] = 3*a*a+3*a*a*a;
            workT3Coeffs[tinstanceNo][_c3] = -6*a*a-3*a-3*a*a*a;
            workT3Coeffs[tinstanceNo][_c4] = 1+3*a+a*a*a+3*a*a;
            if (original)
                 workT3Coeffs[tinstanceNo][_alpha] = 2.0/(1.0 + period);
            else workT3Coeffs[tinstanceNo][_alpha] = 2.0/(2.0 + (period-1.0)/2.0);
   }
   
   //
   //
   //
   //
   //
   
   int instanceNo = tinstanceNo*6;
   int r = Bars-i-1;
   if (r == 0)
      {
         workT3[r][0+instanceNo] = price;
         workT3[r][1+instanceNo] = price;
         workT3[r][2+instanceNo] = price;
         workT3[r][3+instanceNo] = price;
         workT3[r][4+instanceNo] = price;
         workT3[r][5+instanceNo] = price;
      }
   else
      {
         workT3[r][0+instanceNo] = workT3[r-1][0+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(price                  -workT3[r-1][0+instanceNo]);
         workT3[r][1+instanceNo] = workT3[r-1][1+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][0+instanceNo]-workT3[r-1][1+instanceNo]);
         workT3[r][2+instanceNo] = workT3[r-1][2+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][1+instanceNo]-workT3[r-1][2+instanceNo]);
         workT3[r][3+instanceNo] = workT3[r-1][3+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][2+instanceNo]-workT3[r-1][3+instanceNo]);
         workT3[r][4+instanceNo] = workT3[r-1][4+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][3+instanceNo]-workT3[r-1][4+instanceNo]);
         workT3[r][5+instanceNo] = workT3[r-1][5+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][4+instanceNo]-workT3[r-1][5+instanceNo]);
      }

   //
   //
   //
   //
   //
   
   return(workT3Coeffs[tinstanceNo][_c1]*workT3[r][5+instanceNo] + 
          workT3Coeffs[tinstanceNo][_c2]*workT3[r][4+instanceNo] + 
          workT3Coeffs[tinstanceNo][_c3]*workT3[r][3+instanceNo] + 
          workT3Coeffs[tinstanceNo][_c4]*workT3[r][2+instanceNo]);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

void CleanPoint(int i,double& first[],double& second[])
{
   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
        second[i+1] = EMPTY_VALUE;
   else
      if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
          first[i+1] = EMPTY_VALUE;
}
void PlotPoint(int i,double& first[],double& second[],double& from[])
{
   if (first[i+1] == EMPTY_VALUE)
         if (first[i+2] == EMPTY_VALUE) 
              { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
         else { second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }
   else       { first[i]  = from[i];                          second[i] = EMPTY_VALUE; }
}

        
   