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

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1  DeepSkyBlue
#property indicator_color2  Red
#property indicator_color3  LimeGreen
#property indicator_color4  Red
#property indicator_color5  Gold
#property indicator_width1  2
#property indicator_style2  STYLE_DOT
#property indicator_style5  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                StoKPeriod             = 14;
extern int                StoDPeriod             =  3;
extern int                StoSlowingPeriod       =  3;
extern ENUM_MA_METHOD     StoMaMethod            = MODE_SMA;
extern ENUM_APPLIED_PRICE StochasticHighPrice    = PRICE_HIGH;
extern ENUM_APPLIED_PRICE StochasticLowPrice     = PRICE_LOW;
extern ENUM_APPLIED_PRICE StochasticClosePrice   = PRICE_CLOSE;
extern int                DzLookBackBars         = 70;
extern double             DzStartBuyProbability  = 0.10;
extern double             DzStartSellProbability = 0.10;

//
//
//
//
//

double sto[];
double sig[];
double bli[];
double sli[];
double zli[];

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

int init()
{
   SetIndexBuffer(0,sto);
   SetIndexBuffer(1,sig);
   SetIndexBuffer(2,bli);
   SetIndexBuffer(3,sli);
   SetIndexBuffer(4,zli);
   
   //
   //
   //
   //
   //
      
   IndicatorShortName("Dynamic zone stochastic ("+StoKPeriod+","+StoDPeriod+","+StoSlowingPeriod+","+DzLookBackBars+","+DoubleToStr(DzStartBuyProbability,3)+","+DoubleToStr(DzStartSellProbability,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);

   //
   //
   //
   //
   //
   
   for(i=limit; i>=0; i--) sto[i] = iStoch(iMA(NULL,0,1,0,MODE_SMA,StochasticClosePrice,i),
                                           iMA(NULL,0,1,0,MODE_SMA,StochasticHighPrice ,i),
                                           iMA(NULL,0,1,0,MODE_SMA,StochasticLowPrice  ,i),StoKPeriod,StoSlowingPeriod,i);
   for(i=limit; i>=0; i--)
   {
      sig[i] = iMAOnArray(sto,0,StoDPeriod,0,StoMaMethod,i);
      bli[i] = dzBuy (sto, DzStartBuyProbability,  DzLookBackBars, Bars, i);
      sli[i] = dzSell(sto, DzStartSellProbability, DzLookBackBars, Bars, i);
      zli[i] = dzSell(sto, 0.5,                    DzLookBackBars, Bars, i);
   }
   return(0);
}

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

double workSto[][5];
#define _hi 0
#define _lo 1
#define _re 2
#define _ma 3
#define _mi 4
double iStoch(double priceR, double priceH, double priceL, int period, int slowing, int i, int instanceNo=0)
{
   if (ArrayRange(workSto,0)!=Bars) ArrayResize(workSto,Bars); i = Bars-i-1; instanceNo *= 5;
   
   //
   //
   //
   //
   //
   
   workSto[i][_hi+instanceNo] = priceH;
   workSto[i][_lo+instanceNo] = priceL;
   workSto[i][_re+instanceNo] = priceR;
   workSto[i][_ma+instanceNo] = priceH;
   workSto[i][_mi+instanceNo] = priceL;
      for (int k=1; k<period && (i-k)>=0; k++)
      {
         workSto[i][_mi+instanceNo] = MathMin(workSto[i][_mi+instanceNo],workSto[i-k][_lo+instanceNo]);
         workSto[i][_ma+instanceNo] = MathMax(workSto[i][_ma+instanceNo],workSto[i-k][_hi+instanceNo]);
      }                   
      double sumlow  = 0.0;
      double sumhigh = 0.0;
      for(k=0; k<slowing; k++)
      {
         sumlow  += workSto[i-k][_re+instanceNo]-workSto[i-k][_mi+instanceNo];
         sumhigh += workSto[i-k][_ma+instanceNo]-workSto[i-k][_mi+instanceNo];
      }

   //
   //
   //
   //
   //
   
   if(sumhigh!=0.0) 
         return(100.0*sumlow/sumhigh);
   else  return(0);    
}