

 
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Red
#property indicator_width1 2
#property indicator_color2 DodgerBlue
#property indicator_width2 2
#property indicator_color3 White
#property indicator_width3 2
#property indicator_color4 White
#property indicator_width4 2
#property indicator_color5 Gray
#property indicator_width5 2
#property indicator_color6 Gray
#property indicator_width6 2

//---- input parameters
input int h_left=6;  // left (past) h-value
input int h_right=24;   // right (future) h-value

 
//---- buffers
double ExtUpFractalsBuffer[];
double ExtDownFractalsBuffer[];
double ResolvedBufferUp[];
double ResolvedBufferDn[];
double Up[];
double Dn[];




//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicator buffers mapping
    SetIndexBuffer(0,ExtUpFractalsBuffer);
    SetIndexBuffer(1,ExtDownFractalsBuffer);   
    SetIndexBuffer(2,ResolvedBufferUp);  
    SetIndexBuffer(3,ResolvedBufferDn);
    SetIndexBuffer(4,Up);  
    SetIndexBuffer(5,Dn);

//---- drawing settings
    SetIndexStyle(0,DRAW_ARROW);
    SetIndexArrow(0,217);
    SetIndexStyle(1,DRAW_ARROW);
    SetIndexArrow(1,218);
    SetIndexStyle(2,DRAW_ARROW);
    SetIndexArrow(2,217);
    SetIndexStyle(3,DRAW_ARROW);
    SetIndexArrow(3,218);
//    SetIndexStyle(4,DRAW_LINE);
//    SetIndexStyle(5,DRAW_LINE);
  
//----
    SetIndexEmptyValue(0,0.0);
    SetIndexEmptyValue(1,0.0);
    SetIndexEmptyValue(2,0.0);
    SetIndexEmptyValue(3,0.0);
//---- name for DataWindow
    SetIndexLabel(0,"Transient zone UP");
    SetIndexLabel(1,"Transient zone DOWN");
    SetIndexLabel(2,"Resolved possible transient zone UP");  
    SetIndexLabel(3,"Resolved possible transient zone DN");      
//---- initialization done   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
Comment("");   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    i,countproblembars,countresolvedproblembars,totalnumofbars=0,limit;
   int    counttrans, countrestrans, countfract, countresfract;
   double prevmin,prevmax,futuremin,futuremax;
   double d, dmin, dmax, dsum;
   double frmin, frmax, frsum;
   int frzeros=0, frones=0, frtwos=0;
   double trmin, trmax, trsum;
   int trzeros=0, trones=0, trtwos=0;   
   
   
   limit=Bars-h_left;  
   i=limit;
    dmin=88888888;dmax=0;dsum=0;    
    trmin=88888888;trmax=0;trsum=0;  
    frmin=88888888;frmax=0;frsum=0; 
    
//----Up and Down Fractals
   while(i>=1)
     {

         prevmax=max(i,h_left);
         prevmin=min(i,h_left);
         if (i>h_left) futuremax=max(i,-h_right);
         if (i>h_left) futuremin=min(i,-h_right);  
                
         if (High[i]>prevmax) 
            {
            if (Close[i]>prevmax) //possible transient zone towards up
               {
               counttrans++;
               if ((futuremin<=prevmax)&&(futuremax>=High[i])) 
                     {countresolvedproblembars++; countrestrans++; ResolvedBufferUp[i]=High[i];} //fully resolved; a recurrence zone
                  else 
                  {
                  d=MathMax(futuremin-prevmax,High[i]-futuremax);    //not fully resolved, there is a transient zone
                  dsum+=d; trsum+=d;
                  if (d<dmin) dmin=d; if (d<trmin) trmin=d;
                  if (d>dmax) dmax=d; if (d>trmax) trmax=d;
                  ExtUpFractalsBuffer[i]=High[i];
                  }
               }
               
            if (Close[i]<=prevmax)  //possible up fractal
               {
               countfract++;
               if (futuremax>=High[i]) 
                     {countresolvedproblembars++; countresfract++; ResolvedBufferUp[i]=High[i];} //fully resolved, not a fractal at <h-i,h+i>
                  else
                  {                 
                  d=MathMin(High[i]-futuremax,High[i]-prevmax);  //not fully resolved - a fractal at <h-i,h+i>
                  dsum+=d; frsum+=d;
                  if (d<dmin) dmin=d; if (d<frmin) frmin=d;
                  if (d>dmax) dmax=d; if (d>frmax) frmax=d;
                  ExtUpFractalsBuffer[i]=High[i];
                  }
               }   
            //ObjectCreate("rect1", OBJ_RECTANGLE, 0, Time[i+h_left],Close[i],Time[i-h_left],prevmax);      
             }
         if (Low[i]<prevmin) 
            {             
            if (Close[i]<prevmin)  //possible transient zone towards down
               {
               counttrans++;
               if ((futuremax>=prevmin)&&(futuremin<=Low[i])) 
                     {countresolvedproblembars++; countrestrans++; ResolvedBufferDn[i]=Low[i];} //fully resolved
                  else 
                  {
                  d=MathMax(prevmin-futuremax,futuremin-Low[i]);  //transient zone presesnt
                  dsum+=d; trsum+=d;
                  if (d<dmin) dmin=d; if (d<trmin) trmin=d;
                  if (d>dmax) dmax=d; if (d>trmax) trmax=d;
                  ExtDownFractalsBuffer[i]=Low[i];
                  }
               }
               
            if (Close[i]>prevmin)  //possible down fractal
               {
               countfract++;
               if (futuremin<=Low[i]) 
                     {countresolvedproblembars++; countresfract++; ResolvedBufferDn[i]=Low[i];} //fully resolved
                  else
                  {                 
                  d=MathMin(futuremin-Low[i],prevmin-Low[i]);  //true down fractal at <h-i,h+i>
                  dsum+=d; frsum+=d;
                  if (d<dmin) dmin=d; if (d<frmin) frmin=d;
                  if (d>dmax) dmax=d; if (d>frmax) frmax=d;
                  ExtDownFractalsBuffer[i]=Low[i];
                  }
               }                
               
               
               //ObjectCreate("rect2", OBJ_RECTANGLE, 0, Time[i+h_left],prevmin,Time[i-h_left],Close[i]);                      
            }   
     totalnumofbars++;         
     i--;
     }
     
     countproblembars=counttrans+countfract;
     
     int trueproblembars=countproblembars-countresolvedproblembars;     
     double meand=dsum/double(trueproblembars);
   
     i=limit;
      while(i>=1)
     {

         prevmax=max(i,h_left);
         Up[i]=prevmax;
         prevmin=min(i,h_left);
         Dn[i]=prevmin;
         if (i>h_left) futuremax=max(i,-h_left);
         if (i>h_left) futuremin=min(i,-h_left);  
                
         if (High[i]>prevmax) 
            {
            if (Close[i]>prevmax) //possible transient zone towards up
               {

               if ((futuremin<=prevmax)&&(futuremax>=High[i])) {trzeros++;} // resolved, d=0
                  else 
                  {
                  d=MathMax(futuremin-prevmax,High[i]-futuremax);
                  if (d<meand)   //statistics of finite d
                     trzeros++;
                     else if (d<2*meand) 
                     trones++;
                     else if (d<3*meand)  
                     trtwos++;
                  }
               }
               
            if (Close[i]<=prevmax)  //possible up fractal
               {
               if (futuremax>=High[i]) {frzeros++;} //confirmed up fractal, d=0
                  else
                  {                 
                  d=MathMin(High[i]-futuremax,High[i]-prevmax);
                  if (d<meand)   //statistics of finite d
                     frzeros++;
                     else if (d<2*meand) 
                     frones++;
                     else if (d<3*meand)  
                     frtwos++;
                  }
               }   
            //ObjectCreate("rect1", OBJ_RECTANGLE, 0, Time[i+h_left],Close[i],Time[i-h_left],prevmax);      
             }
         if (Low[i]<prevmin) 
            {
             
            if (Close[i]<prevmin)  //possible transient zone towards down
               {

               if ((futuremax>=prevmin)&&(futuremin<=Low[i])) {trzeros++;} //fully resolved, d=0
                  else 
                  {
                  d=MathMax(prevmin-futuremax,futuremin-Low[i]);
                  if (d<meand)    //statistics of finite d
                     trzeros++;
                     else if (d<2*meand) 
                     trones++;
                     else if (d<3*meand)  
                     trtwos++;
                  }
               }
               
            if (Close[i]>prevmin)  //possible down fractal
               {
               if (futuremin<=Low[i]) {frzeros++;}  //fully resolved, d=0
                  else
                  {                 
                  d=MathMin(futuremin-Low[i],prevmin-Low[i]);
                  if (d<meand) //statistics of finite d
                     frzeros++;
                     else if (d<2*meand) 
                     frones++;
                     else if (d<3*meand)  
                     frtwos++;
                  }
               }                
               
               
               //ObjectCreate("rect2", OBJ_RECTANGLE, 0, Time[i+h_left],prevmin,Time[i-h_left],Close[i]);                      
            }           
     i--;
     }
     
     

   string temp0 = StringConcatenate("\n","h_left = ",h_left, ", h_right = ", h_right);
   string temp05 = "\n---------------------------------------";   
   string temp1 = StringConcatenate("\n","Number of bars: ",totalnumofbars);  
   string temp2 = StringConcatenate("\n","Problem bars: ",trueproblembars);
   string temp3 = StringConcatenate("\n","Fully resolved bars: ",countresolvedproblembars);     
   string temp4 = StringConcatenate("\n","Frequency of true problem bars: ",100*double(trueproblembars)/double(totalnumofbars)," %");    
   string temp5 = StringConcatenate("\n","Frequency of possible problem bars: ",100*double(countproblembars)/double(totalnumofbars)," %");
   string temp6 = StringConcatenate("\n","Probability of full resolving: ",100*double(countresolvedproblembars)/double(countproblembars)," %");
   string temp7 = StringConcatenate("\n","Mean width of the problem zone <k> : ",dsum/double(trueproblembars));
   string temp8 = StringConcatenate("\n","Max width of the problem zone : ",dmax);
   string temp9 = "\n---------------------------------------";
   string temp10 = StringConcatenate("\n","Frequency of true transient bars: ",100*double(counttrans-countrestrans)/double(totalnumofbars)," %");   
   string temp11 = StringConcatenate("\n","Frequency of possible transient bars: ",100*double(counttrans)/double(totalnumofbars)," %");
   string temp12 = StringConcatenate("\n","Probability of fully resolving possible transient bars: ",100*double(countrestrans)/double(counttrans)," %"); 
   string temp125 = StringConcatenate("\n","Mean width of trans. problem zone <k> : ",trsum/double(counttrans-countrestrans)); 
   string temp126 = StringConcatenate("\n","Max width of trans. problem zone: ",trmax);    
   string temp127 = StringConcatenate("\n","Probability of trans. zone width k=[0,  <k>> : ",100*(double(trzeros)/double(counttrans))," %");
   string temp128 = StringConcatenate("\n","Probability of trans. zone width k=[0, 2<k>> : ",100*(double(trzeros+trones)/double(counttrans))," %");
   string temp129 = StringConcatenate("\n","Probability of trans. zone width k=[0, 3<k>> : ",100*(double(trzeros+trones+trtwos)/double(counttrans))," %");   
   string temp13 = "\n---------------------------------------";
   string temp14 = StringConcatenate("\n","Frequency of true fractal bars: ",100*double(countfract-countresfract)/double(totalnumofbars)," %");   
   string temp15 = StringConcatenate("\n","Frequency of possible fractal bars: ",100*double(countfract)/double(totalnumofbars)," %");
   string temp16 = StringConcatenate("\n","Probability of fully resolving possible fractal bars: ",100*double(countresfract)/double(countfract)," %");
   string temp165 = StringConcatenate("\n","Mean width of fract. problem zone <k> : ",frsum/double(countfract-countresfract)); 
   string temp166 = StringConcatenate("\n","Max width of fract. problem zone: ",frmax); 
   string temp167 = StringConcatenate("\n","Probability of fract. zone width k=[0,  <k>> : ",100*(double(frzeros)/double(countfract))," %");
   string temp168 = StringConcatenate("\n","Probability of fract. zone width k=[0, 2<k>> : ",100*(double(frzeros+frones)/double(countfract))," %");
   string temp169 = StringConcatenate("\n","Probability of fract. zone width k=[0, 3<k>> : ",100*(double(frzeros+frones+frtwos)/double(countfract))," %");        

   
   Comment(temp0+temp05+temp1+temp2+temp3+temp4+temp5+temp6+temp7+temp8+temp9+temp10+temp11+temp12+temp125+temp126+temp127+temp128+temp129+temp13+temp14+temp15+temp16+temp165+temp166+temp167+temp168+temp169);
         
//----
   return(0);
  }

//+------------------------------------------------------------------+

double max(int index,int shift)
{
if (shift<0) {index=index+shift-1; shift=-shift;}  
double mx=-8888888;
for(int ind=index+1;ind<=index+shift;ind++) if (High[ind]>mx) mx=High[ind];
return mx;
}   

double min(int index,int shift)
{
if (shift<0) {index=index+shift-1; shift=-shift;} 
double mn=8888888;
for(int ind=index+1;ind<=index+shift;ind++) if (Low[ind]<mn) mn=Low[ind];
return mn;
}  
