#property indicator_style6     STYLE_DOT//+------------------------------------------------------------------+  
//|                                                                  | 
//+------------------------------------------------------------------+ 
#property copyright "www.forex-tsd.com"
#property link      "www.forex-tsd.com"

#property indicator_separate_window
#property indicator_buffers    8
#property indicator_color1     clrDodgerBlue
#property indicator_color2     clrSandyBrown
#property indicator_color3     clrSandyBrown
#property indicator_color4     clrLimeGreen
#property indicator_color5     clrLimeGreen
#property indicator_color6     clrRed
#property indicator_color7     clrRed
#property indicator_color8     clrDimGray
#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 indicator_levelcolor clrDarkSlateGray

//
//
//
//
//

#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

//
//
//
//
//

enum enPrices
{
   pr_close,      // Close
   pr_open,       // Open
   pr_high,       // High
   pr_low,        // Low
   pr_median,     // Median
   pr_typical,    // Typical
   pr_weighted,   // Weighted
   pr_average,    // Average (high+low+open+close)/4
   pr_medianb,    // Average median body (open+close)/2
   pr_tbiased,    // Trend biased price
   pr_haclose,    // Heiken ashi close
   pr_haopen ,    // Heiken ashi open
   pr_hahigh,     // Heiken ashi high
   pr_halow,      // Heiken ashi low
   pr_hamedian,   // Heiken ashi median
   pr_hatypical,  // Heiken ashi typical
   pr_haweighted, // Heiken ashi weighted
   pr_haaverage,  // Heiken ashi average
   pr_hamedianb,  // Heiken ashi median body
   pr_hatbiased   // Heiken ashi trend biased price
};

extern ENUM_TIMEFRAMES TimeFrame               = PERIOD_CURRENT; // Time frame
extern enPrices        Price                   = pr_close;       // Price to use
extern int             SmoothLength            = 50;
extern double          SmoothPhase             = 0;
extern bool            SmoothDouble            = false;
extern double          fatlWeight              = 0.5;
extern double          rftlWeight              = 0.5;
extern double          satlWeight              = 0.5;
extern double          rstlWeight              = 1.0;
extern int             DzLookBackBars          = 70;
extern double          DzStartBuyProbability1  = 0.10;
extern double          DzStartBuyProbability2  = 0.25;
extern double          DzStartSellProbability1 = 0.10;
extern double          DzStartSellProbability2 = 0.25;
extern bool            alertsOn                = true;
extern bool            alertsOnCurrent         = false;
extern bool            alertsMessage           = true;
extern bool            alertsSound             = false;
extern bool            alertsEmail             = false;
extern bool            alertsNotify            = false;
extern bool            Interpolate             = true;


//
//
//
//
//

double score[];
double scoreDa[];
double scoreDb[];
double bl1[];
double bl2[];
double sl1[];
double sl2[];
double zl1[];
double prices[];
double values[][8];
double trend[];
double slope[];
double fatlFilter[];
int    fatlFilterSize;
double rftlFilter[];
int    rftlFilterSize;
double satlFilter[];
int    satlFilterSize;
double rstlFilter[];
int    rstlFilterSize;

//
//
//
//
//

string indicatorFileName;
bool   returnBars;


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

int init()
{
   IndicatorBuffers(11);
   SetIndexBuffer(0, score);
   SetIndexBuffer(1, scoreDa);
   SetIndexBuffer(2, scoreDb);
   SetIndexBuffer(3, bl1);
   SetIndexBuffer(4, bl2);
   SetIndexBuffer(5, sl2);
   SetIndexBuffer(6, sl1);
   SetIndexBuffer(7, zl1);
   SetIndexBuffer(8, prices);
   SetIndexBuffer(9, trend);
   SetIndexBuffer(10,slope);

   //
   //
   //
   //
   //

      fillFatl(fatlFilter,fatlFilterSize);
      fillRftl(rftlFilter,rftlFilterSize);
      fillSatl(satlFilter,satlFilterSize);
      fillRstl(rstlFilter,rstlFilterSize);
      indicatorFileName = WindowExpertName();
      returnBars        = (TimeFrame==-99);
      TimeFrame         = MathMax(TimeFrame,_Period);

        
   //
   //
   //
   //
   //
   
   IndicatorShortName(timeFrameToString(TimeFrame)+" ddz smoothed digital filters score");
   return(0); 
} 


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

#define _fatl      0
#define _rftl      1
#define _satl      2
#define _rstl      3
#define _fatlTrend 4
#define _rftlTrend 5
#define _satlTrend 6
#define _rstlTrend 7

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

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit = MathMin(Bars-counted_bars,Bars-1);
         if (returnBars) { score[0] = limit+1; return(0); }

   //
   //
   //
   //
   //

   if (TimeFrame == Period())
   {
      if (ArrayRange(values,0)!=Bars) ArrayResize(values,Bars);
      if (slope[limit]==-1) CleanPoint(limit,scoreDa,scoreDb);
      for(i=limit,r=Bars-i-1; i>=0; i--,r++)
      {
         prices[i] = getPrice(Price,Open,Close,High,Low,i);
         values[r][_fatl] = 0;  for(j=0; j<fatlFilterSize; j++)  values[r][_fatl] += fatlFilter[j]*prices[i+j];
         values[r][_rftl] = 0;  for(j=0; j<rftlFilterSize; j++)  values[r][_rftl] += rftlFilter[j]*prices[i+j];
         values[r][_satl] = 0;  for(j=0; j<satlFilterSize; j++)  values[r][_satl] += satlFilter[j]*prices[i+j];
         values[r][_rstl] = 0;  for(j=0; j<rstlFilterSize; j++)  values[r][_rstl] += rstlFilter[j]*prices[i+j];
         
         //
         //
         //
         //
         //
         
         values[r][_fatlTrend] = values[r-1][_fatlTrend];
               if (values[r][_fatl]>values[r-1][_fatl]) values[r][_fatlTrend] =  1;
               if (values[r][_fatl]<values[r-1][_fatl]) values[r][_fatlTrend] = -1;
         values[r][_rftlTrend] = values[r-1][_rftlTrend];
               if (values[r][_rftl]>values[r-1][_rftl]) values[r][_rftlTrend] =  1;
               if (values[r][_rftl]<values[r-1][_rftl]) values[r][_rftlTrend] = -1;
         values[r][_satlTrend] = values[r-1][_satlTrend];
               if (values[r][_satl]>values[r-1][_satl]) values[r][_satlTrend] =  1;
               if (values[r][_satl]<values[r-1][_satl]) values[r][_satlTrend] = -1;
         values[r][_rstlTrend] = values[r-1][_rstlTrend];
               if (values[r][_rstl]>values[r-1][_rstl]) values[r][_rstlTrend] =  1;
               if (values[r][_rstl]<values[r-1][_rstl]) values[r][_rstlTrend] = -1;

         //
         //
         //
         //
         //
         
         score[i] =  iDSmooth(values[r][_fatlTrend]*fatlWeight+
                              values[r][_rftlTrend]*rftlWeight+
                              values[r][_satlTrend]*satlWeight+
                              values[r][_rstlTrend]*rstlWeight,SmoothLength,SmoothPhase,SmoothDouble,i);
                              
        if (DzStartBuyProbability1  > 0) bl1[i] = dzBuyP (score, DzStartBuyProbability1,  DzLookBackBars, Bars, i, 0.0001);
        if (DzStartBuyProbability2  > 0) bl2[i] = dzBuyP (score, DzStartBuyProbability2,  DzLookBackBars, Bars, i, 0.0001);
        if (DzStartSellProbability1 > 0) sl1[i] = dzSellP(score, DzStartSellProbability1, DzLookBackBars, Bars, i, 0.0001);
        if (DzStartSellProbability2 > 0) sl2[i] = dzSellP(score, DzStartSellProbability2, DzLookBackBars, Bars, i, 0.0001);
                                         zl1[i] = dzSellP(score, 0.5                    , DzLookBackBars, Bars, i, 0.0001);
                                         
                                         //
                                         //
                                         //
                                         //
                                         //
                                         
                                         scoreDa[i] = EMPTY_VALUE;
                                         scoreDb[i] = EMPTY_VALUE;
                                         trend[i] = trend[i+1];
                                         slope[i] = slope[i+1];
                                         if (score[i] > sl2[i] && score[i+1] <= sl2[i]) trend[i] = 1;
                                         if (score[i] < bl2[i] && score[i+1] >= bl2[i]) trend[i] =-1;
                                         if (score[i] > score[i+1])                     slope[i] = 1;
                                         if (score[i] < score[i+1])                     slope[i] =-1;
                                         if (slope[i] == -1) PlotPoint(i,scoreDa,scoreDb,score);
      }
      manageAlerts();
      return(0); 
   }      

   //
   //
   //
   //
   //
   
   limit = (int)MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/Period()));
   if (slope[limit]==-1) CleanPoint(limit,scoreDa,scoreDb);
   for (i=limit; i>=0; i--)
   {
      int y = iBarShift(NULL,TimeFrame,Time[i]);
         score[i]   = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,0, y);
         bl1[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,3, y);
         bl2[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,4, y);
         sl2[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,5, y);
         sl1[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,6, y);
         zl1[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,7, y);
         slope[i]   = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Price,SmoothLength,SmoothPhase,SmoothDouble,fatlWeight,rftlWeight,satlWeight,rstlWeight,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify,10,y);
         scoreDa[i] = EMPTY_VALUE;
         scoreDb[i] = EMPTY_VALUE;
         
         //
         //
         //
         //
         //
      
            if (y==iBarShift(NULL,TimeFrame,Time[i-1]) || !Interpolate) continue;

         //
         //
         //
         //
         //

         datetime time = iTime(NULL,TimeFrame,y);
            for(int n = 1; i+n < Bars && Time[i+n] >= time; n++) continue;	
            for(int k = 1; k < n; k++)
            {
               score[i+k] = score[i] + (score[i+n]- score[i]) * k/n;
               bl1[i+k]   = bl1[i]   + (bl1[i+n]  - bl1[i])   * k/n;
               bl2[i+k]   = bl2[i]   + (bl2[i+n]  - bl2[i])   * k/n;
               sl2[i+k]   = sl2[i]   + (sl2[i+n]  - sl2[i])   * k/n;
               sl1[i+k]   = sl1[i]   + (sl1[i+n]  - sl1[i])   * k/n;
               zl1[i+k]   = zl1[i]   + (zl1[i+n]  - zl1[i])   * k/n;
           }
   }
   for (i=limit;i>=0;i--) if (slope[i]==-1) PlotPoint(i,scoreDa,scoreDb,score);
return(0);
}

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

double wrk[][20];

#define bsmax  5
#define bsmin  6
#define volty  7
#define vsum   8
#define avolty 9

//
//
//
//
//

double iDSmooth(double price, double length, double phase, bool isDouble, int i, int s=0)
{
   if (isDouble)
         return (iSmooth(iSmooth(price,MathSqrt(length),phase,i,s),MathSqrt(length),phase,i,s+10));
   else  return (iSmooth(price,length,phase,i,s));
}

//
//
//
//
//

double iSmooth(double price, double length, double phase, int i, int s=0)
{
   if (length <=1) return(price);
   if (ArrayRange(wrk,0) != Bars) ArrayResize(wrk,Bars);
   
   int r = Bars-i-1; 
      if (r==0) { for(int k=0; k<7; k++) wrk[r][k+s]=price; for(; k<10; k++) wrk[r][k+s]=0; return(price); }

   //
   //
   //
   //
   //
   
      double len1   = MathMax(MathLog(MathSqrt(0.5*(length-1)))/MathLog(2.0)+2.0,0);
      double pow1   = MathMax(len1-2.0,0.5);
      double del1   = price - wrk[r-1][bsmax+s];
      double del2   = price - wrk[r-1][bsmin+s];
      double div    = 1.0/(10.0+10.0*(MathMin(MathMax(length-10,0),100))/100);
      int    forBar = MathMin(r,10);
	
         wrk[r][volty+s] = 0;
               if(MathAbs(del1) > MathAbs(del2)) wrk[r][volty+s] = MathAbs(del1); 
               if(MathAbs(del1) < MathAbs(del2)) wrk[r][volty+s] = MathAbs(del2); 
         wrk[r][vsum+s] =	wrk[r-1][vsum+s] + (wrk[r][volty+s]-wrk[r-forBar][volty+s])*div;
         
         //
         //
         //
         //
         //
   
         wrk[r][avolty+s] = wrk[r-1][avolty+s]+(2.0/(MathMax(4.0*length,30)+1.0))*(wrk[r][vsum+s]-wrk[r-1][avolty+s]);
            if (wrk[r][avolty+s] > 0)
               double dVolty = wrk[r][volty+s]/wrk[r][avolty+s]; else dVolty = 0;   
	               if (dVolty > MathPow(len1,1.0/pow1)) dVolty = MathPow(len1,1.0/pow1);
                  if (dVolty < 1)                      dVolty = 1.0;

      //
      //
      //
      //
      //
	        
   	double pow2 = MathPow(dVolty, pow1);
      double len2 = MathSqrt(0.5*(length-1))*len1;
      double Kv   = MathPow(len2/(len2+1), MathSqrt(pow2));

         if (del1 > 0) wrk[r][bsmax+s] = price; else wrk[r][bsmax+s] = price - Kv*del1;
         if (del2 < 0) wrk[r][bsmin+s] = price; else wrk[r][bsmin+s] = price - Kv*del2;
	
   //
   //
   //
   //
   //
      
      double R     = MathMax(MathMin(phase,100),-100)/100.0 + 1.5;
      double beta  = 0.45*(length-1)/(0.45*(length-1)+2);
      double alpha = MathPow(beta,pow2);

         wrk[r][0+s] = price + alpha*(wrk[r-1][0+s]-price);
         wrk[r][1+s] = (price - wrk[r][0+s])*(1-beta) + beta*wrk[r-1][1+s];
         wrk[r][2+s] = (wrk[r][0+s] + R*wrk[r][1+s]);
         wrk[r][3+s] = (wrk[r][2+s] - wrk[r-1][4+s])*MathPow((1-alpha),2) + MathPow(alpha,2)*wrk[r-1][3+s];
         wrk[r][4+s] = (wrk[r-1][4+s] + wrk[r][3+s]); 

   //
   //
   //
   //
   //

   return(wrk[r][4+s]);
}

//
//
//
//
//

void manageAlerts()
{
   if (alertsOn)
   {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1; 
      if (trend[whichBar] != trend[whichBar+1])
      {
         if (trend[whichBar]   == 1) doAlert(whichBar," reached / crossed up");
         if (trend[whichBar]   ==-1) doAlert(whichBar," reached / crossed down");
      }         
   }
}

//
//
//
//
//

void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];

       //
       //
       //
       //
       //

       message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," ",timeFrameToString(_Period)," dz digital filters score level ",doWhat);
          if (alertsMessage) Alert(message);
          if (alertsEmail)   SendMail(StringConcatenate(Symbol()," dz digital filters score "),message);
          if (alertsNotify)  SendNotification(message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}


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

void fillFatl(double& array[], int& size)
{
   size = 39;
   ArrayResize(array,size);
      array[ 0] = +0.4360392246; array[ 1] = +0.3658678660; array[ 2] = +0.2460451052; array[ 3] = +0.1104516027; array[ 4] = -0.0054023158;
      array[ 5] = -0.0760358291; array[ 6] = -0.0933055008; array[ 7] = -0.0670117473; array[ 8] = -0.0190807171; array[ 9] = +0.0259599784;
      array[10] = +0.0502040720; array[11] = +0.0477820398; array[12] = +0.0249261523; array[13] = -0.0047695503; array[14] = -0.0272425079;
      array[15] = -0.0338916063; array[16] = -0.0244149695; array[17] = -0.0055783815; array[18] = +0.0128142457; array[19] = +0.0226517983;
      array[20] = +0.0208782158; array[21] = +0.0100306129; array[22] = -0.0036762908; array[23] = -0.0136739537; array[24] = -0.0160483888;
      array[25] = -0.0108602627; array[26] = -0.0016069184; array[27] = +0.0069474613; array[28] = +0.0110571907; array[29] = +0.0095715934;
      array[30] = +0.0040450130; array[31] = -0.0023819606; array[32] = -0.0067092445; array[33] = -0.0072000560; array[34] = -0.0047729647;
      array[35] = +0.0005556585; array[36] = +0.0007839957; array[37] = +0.0130102968; array[38] = +0.0040410425;

}

//
//
//
//
//
   
void fillSatl(double& array[], int& size)
{
   size = 65;
   ArrayResize(array,size);
      array[ 0] = +0.0982914968; array[ 1] = +0.0975734782; array[ 2] = +0.0961453702; array[ 3] = +0.0940284799; array[ 4] = +0.0912491201;
      array[ 5] = +0.0878446115; array[ 6] = +0.0838599824; array[ 7] = +0.0793462193; array[ 8] = +0.0743626146; array[ 9] = +0.0689724471;
      array[10] = +0.0632438243; array[11] = +0.0572485969; array[12] = +0.0510590362; array[13] = +0.0447524857; array[14] = +0.0384014162;
      array[15] = +0.0320788522; array[16] = +0.0258588591; array[17] = +0.0198052896; array[18] = +0.0139852899; array[19] = +0.0084553106;
      array[20] = +0.0032675186; array[21] = -0.0015319201; array[22] = -0.0059034430; array[23] = -0.0098170830; array[24] = -0.0132494238;
      array[25] = -0.0161868549; array[26] = -0.0186163816; array[27] = -0.0205453419; array[28] = -0.0219751066; array[29] = -0.0229225089;
      array[30] = -0.0234106677; array[31] = -0.0234597715; array[32] = -0.0231055463; array[33] = -0.0223841389; array[34] = -0.0213348833;
      array[35] = -0.0199977823; array[36] = -0.0184183252; array[37] = -0.0166438570; array[38] = -0.0147201173; array[39] = -0.0126861210;
      array[40] = -0.0106002368; array[41] = -0.0084800087; array[42] = -0.0063906493; array[43] = -0.0043529032; array[44] = -0.0024016281;
      array[45] = -0.0005592474; array[46] = +0.0011366688; array[47] = +0.0026794401; array[48] = +0.0040424396; array[49] = +0.0052338017;
      array[50] = +0.0062156364; array[51] = +0.0070307929; array[52] = +0.0076234960; array[53] = +0.0080354940; array[54] = +0.0083018972;
      array[55] = +0.0083678562; array[56] = +0.0082888626; array[57] = +0.0080733795; array[58] = +0.0077539545; array[59] = +0.0073259318;
      array[60] = +0.0068163840; array[61] = +0.0062328194; array[62] = +0.0056082863; array[63] = +0.0049522510; array[64] = +0.0161442562;
}

//
//
//
//
//

void fillRftl(double& array[], int& size)
{
   size = 44;
   ArrayResize(array,size);
      array[ 0] = -0.0025092021; array[ 1] = +0.0513012200; array[ 2] = +0.1142800445; array[ 3] = +0.1699338663; array[ 4] = +0.2025262073;
      array[ 5] = +0.2025262073; array[ 6] = +0.1699338663; array[ 7] = +0.1142800445; array[ 8] = +0.0513012200; array[ 9] = -0.0025092021;
      array[10] = -0.0353161991; array[11] = -0.0433374067; array[12] = -0.0311248031; array[13] = -0.0088623799; array[14] = +0.0120575757;
      array[15] = +0.0233181781; array[16] = +0.0221932220; array[17] = +0.0115773967; array[18] = -0.0022153029; array[19] = -0.0126532694;
      array[20] = -0.0157415620; array[21] = -0.0113399687; array[22] = -0.0025909790; array[23] = +0.0059518053; array[24] = +0.0105210324;
      array[25] = +0.0096972603; array[26] = +0.0046588974; array[27] = -0.0017075189; array[28] = -0.0063511121; array[29] = -0.0074539609;
      array[30] = -0.0050442430; array[31] = -0.0007463619; array[32] = +0.0032268725; array[33] = +0.0051357097; array[34] = +0.0044456975;
      array[35] = +0.0018787786; array[36] = -0.0011063441; array[37] = -0.0031162284; array[38] = -0.0033441946; array[39] = -0.0022168887;
      array[40] = +0.0002580855; array[41] = +0.0003641408; array[42] = +0.0060428648; array[43] = +0.0018769344;
}

//
//
//
//
//

void fillRstl(double& array[], int& size)
{
   size = 91;
   ArrayResize(array,size);
      array[ 0] = -0.0074144779; array[ 1] = -0.0060689714; array[ 2] = -0.0044967689; array[ 3] = -0.0027041045; array[ 4] = -0.0007017044;
      array[ 5] = +0.0014967048; array[ 6] = +0.0038730015; array[ 7] = +0.0064060389; array[ 8] = +0.0090719218; array[ 9] = +0.0118447926;
      array[10] = +0.0146938946; array[11] = +0.0175899798; array[12] = +0.0204991221; array[13] = +0.0233878722; array[14] = +0.0262230345;
      array[15] = +0.0289691814; array[16] = +0.0315932085; array[17] = +0.0340622044; array[18] = +0.0363449720; array[19] = +0.0384125260;
      array[20] = +0.0402377072; array[21] = +0.0417971611; array[22] = +0.0430702622; array[23] = +0.0440399154; array[24] = +0.0446940681;
      array[25] = +0.0450229605; array[26] = +0.0450229605; array[27] = +0.0446940681; array[28] = +0.0440399154; array[29] = +0.0430702622;
      array[30] = +0.0417971611; array[31] = +0.0402377072; array[32] = +0.0384125260; array[33] = +0.0363449720; array[34] = +0.0340622044;
      array[35] = +0.0315932085; array[36] = +0.0289691814; array[37] = +0.0262230345; array[38] = +0.0233878722; array[39] = +0.0204991221;
      array[40] = +0.0175899798; array[41] = +0.0146938946; array[42] = +0.0118447926; array[43] = +0.0090719218; array[44] = +0.0064060389;
      array[45] = +0.0038730015; array[46] = +0.0014967048; array[47] = -0.0007017044; array[48] = -0.0027041045; array[49] = -0.0044967689;
      array[50] = -0.0060689714; array[51] = -0.0074144779; array[52] = -0.0085273360; array[53] = -0.0094109068; array[54] = -0.0100658184;
      array[55] = -0.0104997812; array[56] = -0.0107233850; array[57] = -0.0107458773; array[58] = -0.0105836225; array[59] = -0.0102531779;
      array[60] = -0.0097725606; array[61] = -0.0091600941; array[62] = -0.0084366151; array[63] = -0.0076238102; array[64] = -0.0067426306;
      array[65] = -0.0058109474; array[66] = -0.0048554967; array[67] = -0.0038843146; array[68] = -0.0029272721; array[69] = -0.0019938713;
      array[70] = -0.0011000790; array[71] = -0.0002561664; array[72] = +0.0005206574; array[73] = +0.0012273323; array[74] = +0.0018516617;
      array[75] = +0.0023973716; array[76] = +0.0028471064; array[77] = +0.0032204933; array[78] = +0.0034919843; array[79] = +0.0036807022;
      array[80] = +0.0038027296; array[81] = +0.0038329425; array[82] = +0.0037967591; array[83] = +0.0036980559; array[84] = +0.0035517415;
      array[85] = +0.0033556833; array[86] = +0.0031222822; array[87] = +0.0028549772; array[88] = +0.0025689064; array[89] = +0.0022684058;
      array[90] = +0.0073949653;
}

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

string sTfTable[] = {"M1","M5","M10","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,10,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

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

double workHa[][4];
double getPrice(int price, const double& open[], const double& close[], const double& high[], const double& low[], int i, int instanceNo=0)
{
  if (price>=pr_haclose && price<=pr_hatbiased)
   {
      if (ArrayRange(workHa,0)!= Bars) ArrayResize(workHa,Bars);
         int r = Bars-i-1;
         
         //
         //
         //
         //
         //
         
         double haOpen;
         if (r>0)
                haOpen  = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0;
         else   haOpen  = (open[i]+close[i])/2;
         double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
         double haHigh  = MathMax(high[i], MathMax(haOpen,haClose));
         double haLow   = MathMin(low[i] , MathMin(haOpen,haClose));

         if(haOpen  <haClose) { workHa[r][instanceNo+0] = haLow;  workHa[r][instanceNo+1] = haHigh; } 
         else                 { workHa[r][instanceNo+0] = haHigh; workHa[r][instanceNo+1] = haLow;  } 
                                workHa[r][instanceNo+2] = haOpen;
                                workHa[r][instanceNo+3] = haClose;
         //
         //
         //
         //
         //
         
         switch (price)
         {
            case pr_haclose:     return(haClose);
            case pr_haopen:      return(haOpen);
            case pr_hahigh:      return(haHigh);
            case pr_halow:       return(haLow);
            case pr_hamedian:    return((haHigh+haLow)/2.0);
            case pr_hamedianb:   return((haOpen+haClose)/2.0);
            case pr_hatypical:   return((haHigh+haLow+haClose)/3.0);
            case pr_haweighted:  return((haHigh+haLow+haClose+haClose)/4.0);
            case pr_haaverage:   return((haHigh+haLow+haClose+haOpen)/4.0);
            case pr_hatbiased:
               if (haClose>haOpen)
                     return((haHigh+haClose)/2.0);
               else  return((haLow+haClose)/2.0);        
         }
   }
   
   //
   //
   //
   //
   //
   
   switch (price)
   {
      case pr_close:     return(close[i]);
      case pr_open:      return(open[i]);
      case pr_high:      return(high[i]);
      case pr_low:       return(low[i]);
      case pr_median:    return((high[i]+low[i])/2.0);
      case pr_medianb:   return((open[i]+close[i])/2.0);
      case pr_typical:   return((high[i]+low[i]+close[i])/3.0);
      case pr_weighted:  return((high[i]+low[i]+close[i]+close[i])/4.0);
      case pr_average:   return((high[i]+low[i]+close[i]+open[i])/4.0);
      case pr_tbiased:   
               if (close[i]>open[i])
                     return((high[i]+close[i])/2.0);
               else  return((low[i]+close[i])/2.0);        
   }
   return(0);
}

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

void CleanPoint(int i,double& first[],double& second[])
{
   if (i>=Bars-3) return;
   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 (i>=Bars-2) return;
   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; }
}
