//+------------------------------------------------------------------+
//|                                                  Value chart.mq4 |
//|                                                                  |
//| Helweg/Stendahl value charts                                     |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_separate_window
#property indicator_buffers 7
#property indicator_color3 DeepSkyBlue
#property indicator_color4 DeepSkyBlue
#property indicator_color5 DimGray
#property indicator_color6 PaleVioletRed
#property indicator_color7 PaleVioletRed
#property indicator_style5 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 string objectsUniqueID         = "Value charts";
extern int    numberOfBars            = 10;
extern color  colorBarDown            = Red;
extern color  colorBarUp              = Green;
extern color  colorBarNeutral         = DimGray;
extern color  colorWickUp             = DimGray;
extern color  colorWickDown           = DimGray;
extern color  colorWickNeutral        = DimGray;
extern int    widthWick               = 1;
extern int    widthBody               = 3;
extern int    DzLookBackBars          = 70;
extern double DzStartBuyProbability1  = 0.05;
extern double DzStartBuyProbability2  = 0.25;
extern double DzStartSellProbability1 = 0.05;
extern double DzStartSellProbability2 = 0.25;

//
//
//
//
//

string name;
int    window;
double hiBuffer[];
double loBuffer[];
double prBuffer[];
double saBuffer[];
double sbBuffer[];
double baBuffer[];
double bbBuffer[];
double miBuffer[];

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

int init()
{
   IndicatorBuffers(8);
      SetIndexBuffer(0,hiBuffer); SetIndexStyle(0,DRAW_NONE);
      SetIndexBuffer(1,loBuffer); SetIndexStyle(1,DRAW_NONE);
      SetIndexBuffer(2,saBuffer); SetIndexDrawBegin(2,DzLookBackBars+1);
      SetIndexBuffer(3,sbBuffer); SetIndexDrawBegin(3,DzLookBackBars+1);
      SetIndexBuffer(4,miBuffer); SetIndexDrawBegin(4,DzLookBackBars+1);
      SetIndexBuffer(5,baBuffer); SetIndexDrawBegin(5,DzLookBackBars+1);
      SetIndexBuffer(6,bbBuffer); SetIndexDrawBegin(6,DzLookBackBars+1);
      SetIndexBuffer(7,prBuffer);
         DzStartBuyProbability1  = MathMax(DzStartBuyProbability1 ,0.001);
         DzStartBuyProbability2  = MathMax(DzStartBuyProbability2 ,0.001);
         DzStartSellProbability1 = MathMax(DzStartSellProbability1,0.001);
         DzStartSellProbability2 = MathMax(DzStartSellProbability2,0.001);

   //
   //
   //
   //
   //
   
   numberOfBars = MathMax(numberOfBars,5);
   name = objectsUniqueID+" "+numberOfBars;
      IndicatorShortName(name);
   return (0);
}

int deinit()
{
   string cName = objectsUniqueID+":";
   int    cLen  = StringLen(cName);
   for (int i = ObjectsTotal() - 1; i >= 0; i--)
   {
      string oName = ObjectName(i); if (StringSubstr(oName, 0, cLen) == cName) ObjectDelete(oName);
   }
   return (0);
}

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

double vaBuffer[];

//
//
//
//
//

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

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit  = MathMin(Bars-counted_bars,Bars-2);
         window = WindowFind(name);
            if (ArraySize(vaBuffer) != Bars) ArrayResize(vaBuffer,Bars);

   //
   //
   //
   //
   //

      int    nVarP = MathRound(numberOfBars/5.0);
      double nVar0,nVarA,nVarB,nVarC,nVarD,nVarE;
      double nVarR1,nVarR2,nVarR3,nVarR4,nVarR5;
      double nLRange;
      for (i=limit,r=Bars-i-1; i>=0; i--,r++)
      {
         //
         //
         //
         //
         //
         
         if (numberOfBars<7)
         {            
               if (MathAbs(Close[i]-Close[i+1]) >= (High[i]-Low[i]))
                     nVarA = MathAbs(Close[i]-Close[i+1]);
               else  nVarA = (High[i]-Low[i]);
               vaBuffer[r] = nVarA;
               
               //
               //
               //
               //
               //
               
               double average=0;
               for (k=0; k<5; k++) average += vaBuffer[r-k];
                                   average /= 5;
               nLRange = average*0.2;
         }
         else
         {            
            nVarA = iHighesti(nVarP,i)-iLowesti(nVarP,i);
                        if  (nVarA == 0 && nVarP == 1)
                             nVarR1 = MathAbs(Close[i]-Close[i+nVarP]);
                        else nVarR1 = nVarA;                      
                     
            nVarB = iHighesti(nVarP,i+nVarP+1)-iLowesti(nVarP,i+nVarP);
                        if (nVarB == 0 && nVarP == 1)
                             nVarR2 = MathAbs(Close[i+nVarP]-Close[i+nVarP*2]);
                        else nVarR2 = nVarB;

            nVarC = iHighesti(nVarP,i+nVarP*2)-iLowesti(nVarP,i+nVarP*2);
                        if (nVarC == 0 && nVarP == 1)
                             nVarR3 = MathAbs(Close[i+nVarP*2]-Close[i+nVarP*3]);
                        else nVarR3 = nVarC;

            nVarD = iHighesti(nVarP,i+nVarP*3)-iLowesti(nVarP,i+nVarP*3);
                        if (nVarD == 0 && nVarP == 1)
                             nVarR4 = MathAbs(Close[i+nVarP*3]-Close[i+nVarP*4]);
                        else nVarR4 = nVarD;

            nVarE = iHighesti(nVarP,i+nVarP*4)-iLowesti(nVarP,i+nVarP*4);
                        if (nVarE == 0 && nVarP == 1)
                             nVarR5 = MathAbs(Close[i+nVarP*4]-Close[i+nVarP*5]);
                        else nVarR5 = nVarE;

            nLRange = ((nVarR1+nVarR2+nVarR3+nVarR4+nVarR5)/5.0)*0.2;
         }   	         

         //
         //
         //
         //
         //
               	         
	         if ( nLRange <= 0 ) continue;
            double hlAverage = 0;
               for (k=0; k<numberOfBars; k++) hlAverage += (High[i+k]+Low[i+k])/2.0;
                                              hlAverage /= numberOfBars;
            
               double nOpen  = (Open[i]  - hlAverage) / nLRange;
               double nHigh  = (High[i]  - hlAverage) / nLRange; hiBuffer[i] = nHigh;
	            double nLow   = (Low[i]   - hlAverage) / nLRange; loBuffer[i] = nLow;
	            double nClose = (Close[i] - hlAverage) / nLRange;	

            //
            //
            //
            //
            //	         

            color  theBarColor  = colorBarNeutral;
            color  theWickColor = colorWickNeutral;
               if (nClose<nOpen) { theBarColor = colorBarDown; theWickColor = colorWickDown; }
               if (nClose>nOpen) { theBarColor = colorBarUp;   theWickColor = colorWickUp;   }
               
               drawBar(Time[i],nHigh,nLow,nOpen,nClose,theBarColor,theWickColor);
               prBuffer[i] = (nHigh+nLow)/2.0;
               saBuffer[i] = dzSellP(hiBuffer,DzStartSellProbability1 ,DzLookBackBars,Bars,i,0.0001);
               sbBuffer[i] = dzSellP(hiBuffer,DzStartSellProbability2 ,DzLookBackBars,Bars,i,0.0001);
               baBuffer[i] = dzBuyP (loBuffer,DzStartBuyProbability1  ,DzLookBackBars,Bars,i,0.0001);
               bbBuffer[i] = dzBuyP (loBuffer,DzStartBuyProbability2  ,DzLookBackBars,Bars,i,0.0001);
               miBuffer[i] = dzBuyP (prBuffer,0.5                     ,DzLookBackBars,Bars,i,0.0001);
      }
      
   //
   //
   //
   //
   //
   
   return(0);
}



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

double iHighesti(int period, int i)
{
   if (i>=Bars) return(0);
   double max  = High[i];
         for (int k=1;(i+k)<Bars && k<period; k++) if (max<High[i+k]) max = High[i+k];
   return(max);
}
double iLowesti(int period, int i)
{
   if (i>=Bars) return(0);
   double min  = Low[i];
         for (int k=1;(i+k)<Bars && k<period; k++) if (min>Low[i+k]) min = Low[i+k];
   return(min);
}

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

void drawBar(int bTime, double prHigh, double prLow, double prOpen, double prClose, color barColor, color wickColor)
{
   string oName;
          oName = objectsUniqueID+":"+bTime+"w";
            if (ObjectFind(oName) < 0) ObjectCreate(oName,OBJ_TREND,window,bTime,0,bTime,0);
                 ObjectSet(oName, OBJPROP_PRICE1, prHigh);
                 ObjectSet(oName, OBJPROP_PRICE2, prLow);
                 ObjectSet(oName, OBJPROP_COLOR, wickColor);
                 ObjectSet(oName, OBJPROP_WIDTH, widthWick);
                 ObjectSet(oName, OBJPROP_RAY, false);
                 ObjectSet(oName, OBJPROP_BACK, true);
           
         oName = objectsUniqueID+":"+bTime+"b";
            if (ObjectFind(oName) < 0)ObjectCreate(oName,OBJ_TREND,window,bTime,0,bTime,0);
                 ObjectSet(oName, OBJPROP_PRICE1, prOpen);
                 ObjectSet(oName, OBJPROP_PRICE2, prClose);
                 ObjectSet(oName, OBJPROP_COLOR, barColor);
                 ObjectSet(oName, OBJPROP_WIDTH, widthBody);
                 ObjectSet(oName, OBJPROP_RAY, false);
                 ObjectSet(oName, OBJPROP_BACK, true);
}