//+------------------------------------------------------------------+
//|                                                          RVI.mq4 |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "www.forex-tsd.com"
#property link      "www.forex-tsd.com"

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1  Green
#property indicator_color2  OrangeRed
#property indicator_color3  DimGray
#property indicator_color4  LimeGreen
#property indicator_color5  Red
#property indicator_style3  STYLE_DOT

//
//
//
//
//

#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    RVIPeriod              = 10;
extern bool   ShowRviLine            = true;
extern bool   ShowSignalLine         = true;
extern bool   DzOnSignalLine         = false;
extern int    DzLookBackBars         = 70;
extern double DzStartBuyProbability  = 0.16;
extern double DzStartSellProbability = 0.16;

//
//
//
//
//

double RVIBuffer[];
double RVISignalBuffer[];
double zli[];
double bli[];
double sli[];

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

int init()
{
   SetIndexBuffer(0,RVIBuffer);       SetIndexLabel(0,"RVI"); 
   SetIndexBuffer(1,RVISignalBuffer); SetIndexLabel(1,"RVI Signal");
   SetIndexBuffer(2,zli);
   SetIndexBuffer(3,bli);
   SetIndexBuffer(4,sli);
      if (ShowRviLine)
            SetIndexStyle(0,DRAW_LINE);
      else  SetIndexStyle(0,DRAW_NONE);
      if (ShowSignalLine)
            SetIndexStyle(1,DRAW_LINE);
      else  SetIndexStyle(1,DRAW_NONE);
   
   //
   //
   //
   //
   //
   
   IndicatorShortName("RVI ("+RVIPeriod+")");
   return(0);
}

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

double work[][2];
#define _co 0
#define _hl 1
#define _precision 0.0001
//
//
//
//
//

int start()
{
   int i,r,limit,counted_bars=IndicatorCounted();
   
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=MathMin(Bars-counted_bars,Bars-1);
           if (ArrayRange(work,0) != Bars) ArrayResize(work,Bars);

   //
   //
   //
   //
   //
   
   for(i=limit, r=Bars-i-1; i>=0; i--,r++)
   {
      work[r][_co] = ((Close[i]-Open[i])+2.0*(Close[i+1]-Open[i+1])+2.0*(Close[i+2]-Open[i+2])+(Close[i+3]-Open[i+3]))/6.0;
      work[r][_hl] = ((High[i]-Low[i])  +2.0*(High[i+1]-Low[i+1])  +2.0*(High[i+2]-Low[i+2])  +(High[i+3]-Low[i+3])  )/6.0;
      
      //
      //
      //
      //
      //
      
      double sumco = 0.0; 
      double sumhl = 0.0;
         for(int k=0; k<RVIPeriod && (r-k)>=0; k++)
         {
            sumco += work[r-k][_co];
            sumhl += work[r-k][_hl];
         }
         if(sumhl!=0.0)
               RVIBuffer[i] = sumco/sumhl;
         else  RVIBuffer[i] = 0.0;
         RVISignalBuffer[i] = (RVIBuffer[i]+2.0*RVIBuffer[i+1]+2.0*RVIBuffer[i+2]+RVIBuffer[i+3])/6.0;
         
         //
         //
         //
         //
         //
         
         if (DzOnSignalLine)
         {
            bli[i] = dzBuyP (RVISignalBuffer, DzStartBuyProbability,  DzLookBackBars, Bars, i, _precision);
            sli[i] = dzSellP(RVISignalBuffer, DzStartSellProbability, DzLookBackBars, Bars, i, _precision);
            zli[i] = dzSellP(RVISignalBuffer, 0.5,                    DzLookBackBars, Bars, i, _precision);
         }
         else
         {
            bli[i] = dzBuyP (RVIBuffer, DzStartBuyProbability,  DzLookBackBars, Bars, i, _precision);
            sli[i] = dzSellP(RVIBuffer, DzStartSellProbability, DzLookBackBars, Bars, i, _precision);
            zli[i] = dzSellP(RVIBuffer, 0.5,                    DzLookBackBars, Bars, i, _precision);
         }            
   }

   //
   //
   //
   //
   //
      
   return(0);
}