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

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1  DeepSkyBlue
#property indicator_color2  LimeGreen
#property indicator_color3  Red
#property indicator_color4  Gold
#property indicator_width1  2
#property indicator_style4  STYLE_DOT
#property indicator_minimum 0
#property indicator_maximum 100

//
//
//
//
//

#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    RsxLength              = 14;
extern int    RsxPrice               =  0;
extern int    DzLookBackBars         = 70;
extern double DzStartBuyProbability  = 0.10;
extern double DzStartSellProbability = 0.10;

//
//
//
//
//

double rsx[];
double bli[];
double sli[];
double zli[];
double wrkBuffer[][13];
double Kg;
double Hg;

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

int init()
{
   SetIndexBuffer(0,rsx);
   SetIndexBuffer(1,bli);
   SetIndexBuffer(2,sli);
   SetIndexBuffer(3,zli);
   
   //
   //
   //
   //
   //
   
   Kg = 3.0/(2.0+RsxLength);
   Hg = 1.0-Kg;
   
   string PriceType;
      switch(RsxPrice)
      {
         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
      }      

   //
   //
   //
   //
   //
      
   IndicatorShortName("Dynamic zone RSX ("+RsxLength+","+PriceType+","+DzLookBackBars+","+DoubleToStr(DzStartBuyProbability,3)+","+DoubleToStr(DzStartSellProbability,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 = MathMin(Bars-counted_bars,Bars-1);
         if (ArrayRange(wrkBuffer,0) != Bars) ArrayResize(wrkBuffer,Bars);

   //
   //
   //
   //
   //
   
   for(i=limit, r=Bars-i-1; i>=0; i--, r++)
   {
      wrkBuffer[r][12] = iMA(NULL,0,1,0,MODE_SMA,RsxPrice,i);

         if (i==(Bars-1)) { for (int c=0; c<12; c++) wrkBuffer[r][c] = 0; continue; }  

      //
      //
      //
      //
      //
      
      double roc = wrkBuffer[r][12]-wrkBuffer[r-1][12];
      double roa = MathAbs(roc);
      for (int k=0; k<3; k++)
      {
         int kk = k*2;
            wrkBuffer[r][kk+0] = Kg*roc                + Hg*wrkBuffer[r-1][kk+0];
            wrkBuffer[r][kk+1] = Kg*wrkBuffer[r][kk+0] + Hg*wrkBuffer[r-1][kk+1]; roc = 1.5*wrkBuffer[r][kk+0] - 0.5 * wrkBuffer[r][kk+1];
            wrkBuffer[r][kk+6] = Kg*roa                + Hg*wrkBuffer[r-1][kk+6];
            wrkBuffer[r][kk+7] = Kg*wrkBuffer[r][kk+6] + Hg*wrkBuffer[r-1][kk+7]; roa = 1.5*wrkBuffer[r][kk+6] - 0.5 * wrkBuffer[r][kk+7];
      }
      if (roa != 0)
           rsx[i] = MathMax(MathMin((roc/roa+1.0)*50.0,100.00),0.00); 
      else rsx[i] = 50.0;

      //
      //
      //
      //
      //
      
      bli[i] = dzBuy (rsx, DzStartBuyProbability,  DzLookBackBars, Bars, i);
      sli[i] = dzSell(rsx, DzStartSellProbability, DzLookBackBars, Bars, i);
      zli[i] = dzSell(rsx, 0.5,                    DzLookBackBars, Bars, i);
   }
   
   //
   //
   //
   //
   //
   
   return(0);
}