Patterns_By_Correlation_ZZ

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Patterns_By_Correlation_ZZ
ÿþ

#property version   "1.00"

#property strict

#property indicator_chart_window



#property indicator_buffers 3

#property indicator_color1  clrWhite

#property indicator_width1  1

#property indicator_color2  clrBlue

#property indicator_width2  2

#property indicator_color3  clrOrange

#property indicator_width3  2





//--- input parameters

 bool Use_Close=true; //Based on close price

extern int ZZDepth=5;     // ZZ Depth, bars (indicator setting)

 int InpDeviation=5;  // Deviation

 int InpBackstep=3;   // Backstep



extern int Nodes=10;              // Pattern nodes

extern int Nodes_Forecast=30;     // Forecast nodes

extern double min_corr_ZZ=0.9;    // Min correlation for ZZ mode

input bool     Recomend=true;     //Give buy/sell integral

extern int     DaysBackZZ=4444;   //History to check for ZZ mode, days

input bool     ShowBestFit=true;  //Show BestFit forecast

input int      Max_linesBF=50;    //Max. number of forecast lines (calculation)

input bool     ShowBestCor=false; //Show BestCorrelation forecast

input int      Max_linesBC=1;     //Max. number of forecast lines (draw)

input bool     ShowOneDayTP=true; //Show one-day-forward TP

input string   cap0="";           //....... Decoration

input int      fs=14;             //Buttons font size (buttons scale)

input int      fsf=20;            //BestFit font size

input int      fsc=15;            //BestCorrelation font size

input color    CLf=clrOrchid;     //BestFit line color

input color    CLc=clrWheat;      //BestCorrelation font size

input int      LWf=4;             //BestFit line width

//---- indicator buffers

double ExtZigzagBuffer[];

double ExtHighBuffer[];

double ExtLowBuffer[];

double up[],dn[];



int    ExtLevel=3; // recounting's depth of extremums



string obj_pref ="Patt_";

string obj_pref2="pObj_";



struct CORR

{

 datetime time;

 int      shift_bar;

 double   shift_price;

 double   corr;

 double   scale;

 double   fit;

};



CORR bars[];



bool first_push,first_push_move,first_push_move_in;



double buy,sell;



bool ZZ_filled;

datetime Filled_Time;



int TimeMove,TimeStart;



double line1[],line2[];

 

int Storage[][2];



double maxTP,minTP;



int OnInit()

  {

   Butt2(5,"Area (nodes)" ,clrGray  ,fs,true);

   Butt2(4,"Area (period)",clrGray  ,fs,true);

   Butt2(3,"Del.Rect."    ,clrRed   ,fs,true);

   Butt2(2,"One Click"    ,clrGray  ,fs,true);

   Butt2(1,"ZZ"           ,clrGray  ,fs,true);

   Butt2(0,"Del. lines"   ,clrRed   ,fs,true);

   

   if(InpBackstep>=ZZDepth) ZZDepth=InpBackstep+1;

   

   ArrayResize(line1,Nodes_Forecast/2);

   ArrayResize(line2,Nodes_Forecast/2);

   ArraySetAsSeries(line1,true);

   ArraySetAsSeries(line2,true);



//--- 2 additional buffers

   IndicatorBuffers(5);

   SetIndexStyle (0,DRAW_NONE);

   SetIndexBuffer(0,ExtZigzagBuffer);

   SetIndexBuffer(1,dn);

   SetIndexBuffer(2,up);



   SetIndexStyle(1,DRAW_ARROW);

   SetIndexArrow(1,159);

   SetIndexStyle(2,DRAW_ARROW);

   SetIndexArrow(2,159);

   

   SetIndexBuffer(3,ExtHighBuffer);

   SetIndexBuffer(4,ExtLowBuffer);



   SetIndexEmptyValue(0,0.0);



   return(INIT_SUCCEEDED);

  }



void OnDeinit(const int reason)

{

 Comment("");

 ObjectsDeleteAll(0,obj_pref);

 ObjectsDeleteAll(0,obj_pref2);

}



//for compiler

int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

  {

   return(rates_total);

  }

  

//+------------------------------------------------------------------+

//| ChartEvent function                                              |

//+------------------------------------------------------------------+

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

  {

  

    //Count ZZ forecast

    if(!ObjectGetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE))

     {

      ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrWhite);

      ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrBlack);

      if(sparam=="")

       {

        if(!first_push) {first_push=true;return;}

        double price1;

        datetime Time1;

        int tmp;

        ChartXYToTimePrice(0,(int)lparam,(int)dparam,tmp,Time1,price1);

        Time1=MathMin(Time1,Time[1]);

        int pos=iBarShift(NULL,0,Time1);

        ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);

        ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);

        ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);



        string Name=obj_pref2+"ClicZZ"+IntegerToString(pos);

        if(ObjectCreate(0,Name,OBJ_TREND,0,Time1,0,Time1,High[pos]*2))

        {

         ObjectSetInteger(0,Name,OBJPROP_WIDTH,1);

         ObjectSetInteger(0,Name,OBJPROP_STYLE,STYLE_DASHDOTDOT);

         ObjectSetInteger(0,Name,OBJPROP_RAY_RIGHT,false);

         ObjectSetInteger(0,Name,OBJPROP_COLOR,CountZZ(pos,Nodes)?clrDarkTurquoise:clrRed);

         ObjectSetInteger(0,Name,OBJPROP_HIDDEN,true);

         ObjectSetInteger(0,Name,OBJPROP_SELECTABLE,false);

         ObjectSetInteger(0,Name,OBJPROP_BACK,false);

        }

        first_push=false;

        

       }

      }

     else 

      {

       ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);

       ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);

       first_push=false;

      }

      

      

    //Draw ZZ

    if(!ObjectGetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE))

     {

      ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrWhite);

      ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrBlack);

      SetIndexStyle(0,DRAW_SECTION);

      SetIndexStyle(3,DRAW_SECTION);

      SetIndexStyle(1,DRAW_ARROW);

      SetIndexStyle(2,DRAW_ARROW);

      if(!ZZ_filled) FillArrayZZ(ZZDepth);

     }

    else 

     {

      ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrBlack);

      ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrGray);

      SetIndexStyle(0,DRAW_NONE);

      SetIndexStyle(3,DRAW_NONE);

      SetIndexStyle(1,DRAW_NONE);

      SetIndexStyle(2,DRAW_NONE);

     }



  

    //Delete lines

    if(!ObjectGetInteger(0,obj_pref+"_B2_0_",OBJPROP_STATE))

     {

      ObjectSetInteger(0,obj_pref+"_B2_0_",OBJPROP_STATE,true);

      ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE,true);

      ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);

      ObjectsDeleteAll(0,obj_pref2);

      //Alert("Cleaned ",_Symbol," ",StringSubstr(EnumToString(ENUM_TIMEFRAMES(_Period)),7));

     }

     

     //Delete rectangles

     if(!ObjectGetInteger(0,obj_pref+"_B2_3_",OBJPROP_STATE))

     {

      ObjectSetInteger(0,obj_pref+"_B2_3_",OBJPROP_STATE,true);

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_STATE,true);

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_BGCOLOR,clrBlack);

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_COLOR,clrGray);

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_STATE,true);

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_BGCOLOR,clrBlack);

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_COLOR,clrGray);

      ObjectsDeleteAll(0,"Rect");

     }

   

   //Area (fixed ZZ period)

   if(ObjectGetInteger(0,obj_pref+"_B2_4_",OBJPROP_STATE))

     {

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_BGCOLOR,clrBlack);

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_COLOR,clrGray);

     }

    else

     {

      if(sparam==obj_pref+"_B2_4_")

       {

        ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_STATE,true);

       }

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_BGCOLOR,clrWhite);

      ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_COLOR,clrBlack);

      if(StringFind(sparam,"Rect")==0)

       {

        datetime Start =(datetime)MathMin(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2));

        datetime Finish=(datetime)MathMin(Time[1],

                                  MathMax(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2)));



        FillArrayZZ(ZZDepth);

        int count_nodes=0;

        for(int i=iBarShift(_Symbol,0,Finish);i<iBarShift(_Symbol,0,Start);i++)

          if(ExtZigzagBuffer[i]!=0) count_nodes++;

        

        if(count_nodes<4) Alert("Area contains only ",count_nodes," nodes! Try another method.");

        else Print("Found ",count_nodes," nodes within this Area");



        ObjectSetInteger(0,sparam,OBJPROP_BACK,false);

        ObjectSetInteger(0,sparam,OBJPROP_WIDTH,4);

        ObjectSetInteger(0,sparam,OBJPROP_COLOR,count_nodes>3 && CountZZ(iBarShift(_Symbol,0,Finish),count_nodes)?clrWhite:clrRed);

        

        ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_STATE,true);

        ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_BGCOLOR,clrBlack);

        ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_COLOR,clrGray);

       }

     }

     

   //Area (fixed nodes)

   if(ObjectGetInteger(0,obj_pref+"_B2_5_",OBJPROP_STATE))

     {

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_BGCOLOR,clrBlack);

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_COLOR,clrGray);

     }

    else

     {

      if(sparam==obj_pref+"_B2_5_")

       {

        ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_STATE,true);

       }

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_BGCOLOR,clrWhite);

      ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_COLOR,clrBlack);

      if(StringFind(sparam,"Rect")==0)

       {

        datetime Start =(datetime)MathMin(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2));

        datetime Finish=(datetime)MathMin(Time[1],

                                  MathMax(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2)));

        int count_nodes=0,

            curr_period=4;

        for(curr_period=4;curr_period<(iBarShift(_Symbol,0,Start)-iBarShift(_Symbol,0,Finish));curr_period++)

        {

        count_nodes=0;

        FillArrayZZ(curr_period);//,iBarShift(_Symbol,0,Start)-curr_period*20,iBarShift(_Symbol,0,Finish));

        for(int i=iBarShift(_Symbol,0,Finish);i<iBarShift(_Symbol,0,Start);i++)

          if(ExtZigzagBuffer[i]!=0) count_nodes++;

        if(count_nodes<Nodes) break;

        }

        

        curr_period=MathMax(curr_period-1,4);

        count_nodes=0;

        FillArrayZZ(curr_period);

        for(int i=iBarShift(_Symbol,0,Finish);i<iBarShift(_Symbol,0,Start);i++)

          if(ExtZigzagBuffer[i]!=0) count_nodes++;

        

        Print("With ZZ period ",curr_period," area contains ",count_nodes," nodes.");



        ObjectSetInteger(0,sparam,OBJPROP_BACK,false);

        ObjectSetInteger(0,sparam,OBJPROP_WIDTH,4);

        ObjectSetInteger(0,sparam,OBJPROP_COLOR,count_nodes>3 && CountZZ(iBarShift(_Symbol,0,Finish),count_nodes)?clrWhite:clrRed);

        

        ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_STATE,true);

        ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_BGCOLOR,clrBlack);

        ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_COLOR,clrGray);

       }

     }



  }





void Text(int time, double price, string text="",color CLR=clrSalmon,int anch=ANCHOR_LEFT_LOWER,int FS=10)

{

   string name=obj_pref2+"_T1_"+IntegerToString(time)+"_"+DoubleToString(price,_Digits);

   if(ObjectCreate(name,OBJ_TEXT,0,0,0))

   {

    ObjectSetInteger(0,name,OBJPROP_ANCHOR,anch);

    ObjectSetInteger(0,name,OBJPROP_TIME1,time>0?Time[time]:(Time[0]-_Period*60*time));

    ObjectSetDouble (0,name,OBJPROP_PRICE1,price);

    ObjectSetString (0,name,OBJPROP_TEXT,text);

    ObjectSetInteger(0,name,OBJPROP_FONTSIZE,FS);

    ObjectSetString (0,name,OBJPROP_FONT,"Arial");

    ObjectSetInteger(0,name,OBJPROP_COLOR,CLR);

    ObjectSetInteger(0,name,OBJPROP_BACK,false);

    ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

    ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);

   }

}



void Butt2(int row,string text="",color CLR=0,int FS=10,bool state=true,color BG=clrBlack)

{

   string name=obj_pref+"_B2_"+IntegerToString(row)+"_";

   if(ObjectFind(name)<0) 

   {

   ObjectCreate(name,OBJ_BUTTON,0,0,0);

   ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_RIGHT_LOWER);

   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,FS*9); 

   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,row*16*FS/10+30); 

   ObjectSetInteger(0,name,OBJPROP_XSIZE,FS*9); 

   ObjectSetInteger(0,name,OBJPROP_YSIZE,16*FS/10);

   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

   ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);

   ObjectSetInteger(0,name,OBJPROP_ALIGN,ALIGN_LEFT);

   ObjectSetString (0,name,OBJPROP_FONT,"Arial");

   ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,clrBlack);

   ObjectSetInteger(0,name,OBJPROP_BACK,false); 

   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,FS);

   ObjectSetInteger(0,name,OBJPROP_ZORDER,10);

   }

   ObjectSetInteger(0,name,OBJPROP_BGCOLOR,BG);

   ObjectSetInteger(0,name,OBJPROP_STATE,state);

   ObjectSetString (0,name,OBJPROP_TEXT,text);

   ObjectSetInteger(0,name,OBJPROP_COLOR,CLR); 

   

}



double CorrelationV(double &arr1[], double &arr2[])

{

   int period=ArraySize(arr1);

   

   if(period!=ArraySize(arr2)) {Alert("Arrays are not equal!! ",period,"!=",ArraySize(arr2));return(0);}



   int i;

   double D1, D2;

   double S1=0;

   double S2=0;

   double S3=0;

   double M1=0;//iMAOnArray(arr1,0,period,0,MODE_SMA,shift);

   double M2=0;//iMAOnArray(arr2,0,period,0,MODE_SMA,shift);

   

   for(i=0;i<period;i++)

   {

    M1+=arr1[i];

    M2+=arr2[i];

   }

   M1/=period;

   M2/=period;

   

   for(i=0;i<period;i++)

   {

      D1=arr1[i]-M1;

      D2=arr2[i]-M2;

      S1+=D1*D2;

      S2+=D1*D1;

      S3+=D2*D2;

   }



   if(S2*S3!=0)

   return(S1/(MathSqrt(S2*S3)));



   return(0);

}





bool CountZZ(int click,int NODES)

  {

   

   uint begin=GetTickCount();

   

   int i;

  

   if(click<iBarShift(NULL,0,Filled_Time)) FillArrayZZ(ZZDepth);



   double arr[][3];

   ArraySetAsSeries(arr,true);

   ArrayResize(arr,Bars);



   int first_node=click,ud=0;

   for(first_node=click;first_node<Bars-2;first_node++)

    {

     if(up[first_node]!=0) {ud=+1;break;}

     if(dn[first_node]!=0) {ud=-1;break;}

    }



   for(i=first_node;i<Bars-2;i++)

     if((ExtZigzagBuffer[i]!=0 && ExtZigzagBuffer[i]==ExtHighBuffer[i] && ud==-1) ||

        (ExtZigzagBuffer[i]!=0 && ExtZigzagBuffer[i]==ExtLowBuffer [i] && ud==+1)) break;



   first_node=i;

 

   int cntr=0,day=0;

   for(i=first_node;i<Bars-2 && day<DaysBackZZ;i++)

    {

     if(TimeDay(Time[i])!=TimeDay(Time[i+1])) day++;

     if(ExtZigzagBuffer[i]!=0)

      {

       arr[cntr][0]=ExtZigzagBuffer[i];

       arr[cntr][1]=i;

       arr[cntr][2]=ExtZigzagBuffer[i]==ExtHighBuffer[i]?+1:-1;

       cntr++;

      }

    }

   int finish_bar=int(arr[0][1]);

   

   double Curr[],

          Temp[];

   ArrayResize(Curr,NODES);

   ArrayResize(Temp,NODES);

   ArraySetAsSeries(Curr,true);

   ArraySetAsSeries(Temp,true);



   for(int j=0;j<NODES;j++)

    Curr[j]=arr[j][0];



  double volatility=(Curr[ArrayMaximum(Curr)]-Curr[ArrayMinimum(Curr)]);

  

  ArrayFree(bars);

  ArrayResize(bars,cntr);



  int corr_found=0;

  double best_corr=0;

  for(i=1;i<cntr-NODES && !IsStopped();i++)

   {

    for(int j=0;j<NODES;j++)

     Temp[j]=arr[j+i][0];

    

    bars[i].corr=CorrelationV(Curr,Temp);

    best_corr=MathMax(best_corr,fabs(bars[i].corr));

    if(fabs(bars[i].corr)<min_corr_ZZ) {bars[i].corr=0;continue;}

    

    if(ShowBestFit)

     {

      ArrayResize(Storage,corr_found+1);

       Storage[corr_found][0]=i;

     }

    

//    bars[i].time=Time[int(arr[i][1])];

//    bars[i].shift_bar=i;

    bars[i].shift_price=Temp[0]-Curr[0];

    if((Temp[ArrayMaximum(Temp)]-Temp[ArrayMinimum(Temp)])==0) {continue;}//Alert(Time[i]);return(false);}

    bars[i].scale=volatility/(Temp[ArrayMaximum(Temp)]-Temp[ArrayMinimum(Temp)]);

    

    corr_found++;

   }



  if(corr_found<1) {Alert("Found nothing with correlation higher then ",min_corr_ZZ,". Best result was ",DoubleToString(best_corr,3));return(false);}

  //else Alert("Found ", corr_found);

  

  //Print(ArrayRange(Storage,0)," - ",corr_found);



 // Print("Initial detection done: ",DoubleToString((GetTickCount()-begin)/1000.0,1)," sec");

 // uint begin2=GetTickCount();

  

  int timer[];

  

  ArrayResize(timer,Nodes_Forecast);

  ArraySetAsSeries(timer,true);

  

  int steps_cnt=0;

  

  buy=sell=0;

  if(ShowBestFit)

    {

      if(corr_found>Max_linesBF)

       {

        for(int k=0;k<corr_found-Max_linesBF;k++)

        {

         int worst=0;

         for(int j=0;j<cntr-NODES;j++)

          if(bars[j].corr!=0) {worst=j; break;}

         int good_cntr=0;

         for(int j=worst+1;j<cntr-NODES && !IsStopped();j++)

          if(fabs(bars[j].corr)>min_corr_ZZ)

           {

            if(fabs(bars[j].corr)<fabs(bars[worst].corr)) worst=j;

            else //if have more good nodes -> can delete this one, no need to surch for even worse

             {

              good_cntr++;

              if(good_cntr>Max_linesBF) break;

             }

           }

         bars[worst].corr=0;

        }

       }

        

   //    Print("Cleaned useless ",corr_found-Max_linesBF-1," nodes: ",DoubleToString((GetTickCount()-begin2)/1000.0,1)," sec");

   //    begin2=GetTickCount();

      

      

      ArrayResize(Temp,NODES);

      for(int c=0;c<corr_found;c++)

       {

        int curr_time=Storage[c][0];

        

        if(bars[curr_time].corr==0) continue;

        

        Storage[c][1]=0;

        

        for(int j=0;j<NODES;j++)

         Curr[j]=arr[j+curr_time][0];

         

        for(int k=0;k<corr_found;k++)

         {

          if(k==c || bars[Storage[k][0]].corr==0) continue;

          for(int j=0;j<NODES;j++)

           Temp[j]=arr[j+Storage[k][0]][0];

          Storage[c][1]+=int(fabs(1000*CorrelationV(Curr,Temp)));

          steps_cnt++;

         }

       }

       

       int best_index=0,best_value=0;

       for(int c=0;c<corr_found;c++)

        if(Storage[c][1]>best_value) {best_index=Storage[c][0];best_value=Storage[c][1];}



       ArrayResize(Temp,Nodes_Forecast);

       for(int j=0;j<Nodes_Forecast;j++)

       if(best_index-j>0)

        { 

         Temp [j]=    arr[best_index-j][0];

         timer[j]=int(arr[best_index-j][1]);

        }

       DrawZZForecast("best"+IntegerToString(best_value),bars[best_index].corr<0,Temp,timer,bars[best_index].scale,bars[best_index].shift_price,finish_bar,click,

                      LWf,CLf);

      //Alert(corr_found," ",best_value*0.001/corr_found);

    



     if(Recomend)

     {

     Text(finish_bar,High[click],"Best Fit: "+

       (buy>-sell?"Buy "+DoubleToString(buy/(buy-sell)*100,0)+"%":("Sell "+DoubleToString(-sell/(buy-sell)*100,0)+"%")),

        buy>-sell?clrLightBlue:clrYellow,ANCHOR_RIGHT_LOWER,fsf);

 /*    if(ShowOneDayTP)

      {

       if(buy >0) DrawLineZZ("maxTP"+IntegerToString(finish_bar),finish_bar,finish_bar-PERIOD_D1/_Period,maxTP,maxTP,clrBlue,0);

       if(sell<0) DrawLineZZ("minTP"+IntegerToString(finish_bar),finish_bar,finish_bar-PERIOD_D1/_Period,minTP,minTP,clrYellow,0);

      }*/

     }

   }



 // Print("Finished BestFit forecast ",steps_cnt," steps: ",DoubleToString((GetTickCount()-begin2)/1000.0,1)," sec");

 // begin2=GetTickCount();



  ArrayResize(Temp,Nodes_Forecast);



  buy=sell=0;

  if(ShowBestCor)

  for(i=0;i<MathMax(1,Max_linesBC);i++)

   {

    int best_day=0;

    for(int j=1;j<cntr-NODES && !IsStopped();j++)

      if(fabs(bars[j].corr)>fabs(bars[best_day].corr)) best_day=j;

    

    if(fabs(bars[best_day].corr)>=min_corr_ZZ)

     {

      for(int j=0;j<Nodes_Forecast;j++)

       if(best_day-j>0)

        { 

         Temp [j]=    arr[best_day-j][0];

         timer[j]=int(arr[best_day-j][1]);

        }

      DrawZZForecast(DoubleToString(bars[best_day].corr*1000,3),bars[best_day].corr<0,Temp,timer,bars[best_day].scale,bars[best_day].shift_price,finish_bar,click,

                     MathMax(3-i,1),CLc);

      //Print(best_day, " - ",bars[best_day].corr, " - ",arr[best_day][0], " - ",bars[best_day].scale);

      bars[best_day].corr=0;

     }

    else break;

   }



   if(Recomend && ShowBestCor)

   Text(finish_bar,Low[click],"Highest Corr.: "+

       (buy>-sell?"Buy "+DoubleToString(buy/(buy-sell)*100,0)+"%":("Sell "+DoubleToString(-sell/(buy-sell)*100,0)+"%")),

        buy>-sell?clrLightBlue:clrYellow,ANCHOR_RIGHT_UPPER,fsc);



   ArrayFree(bars);

   

 //  Print("Finished best corr.: ",DoubleToString((GetTickCount()-begin2)/1000.0,1)," sec");

 //  Print("Processing time: ",DoubleToString((GetTickCount()-begin)/1000.0,1)," sec");



   return(true);

  }





void DrawZZForecast(string pos,bool reverse,double &array[],int &time_arr[], double scale,double shift,int finish_bar,int click, int width, color Color)

{

 double zero =array   [0]-shift;

 int    zerot=time_arr[0];



 maxTP=0;

 minTP=99999999;



 if(StringSubstr(pos,4)=="best" || (StringSubstr(pos,4)!="best" && Max_linesBC<2))

  {

   ArrayInitialize(line1,0);

   ArrayInitialize(line2,0);

  }

 

 if(reverse)

  for(int i=0; i<Nodes_Forecast-1;i++)

   {

    DrawLineZZ("ZZ"+pos+"_",finish_bar-(zerot-time_arr[i]),finish_bar-(zerot-time_arr[i+1]),zero-(array[i+1]-shift-zero)*scale,zero-(array[i]-shift-zero)*scale,Color,width);

    if(StringSubstr(pos,4)=="best" || (StringSubstr(pos,4)!="best" && Max_linesBC<2))

     {

      if(i%2==0) line1[ i   /2]=zero-(array[i]-shift-zero)*scale;

      else       line2[(i-1)/2]=zero-(array[i]-shift-zero)*scale;

     }

    if(Recomend)

     {

      double ud=zero-(array[i]-shift-zero)*scale-Close[click];

      if(ud>0) buy +=ud;

      else     sell+=ud;

 /*     if(ShowOneDayTP && ((finish_bar-(zerot-time_arr[i]))-finish_bar)*_Period*60<PeriodSeconds(PERIOD_D1))

       {

        maxTP=MathMax(maxTP,zero-(array[i]-shift-zero)*scale);

        minTP=MathMin(minTP,zero-(array[i]-shift-zero)*scale);

       }*/

     }

   }

 else

  for(int i=0; i<Nodes_Forecast-1;i++)

   {

    DrawLineZZ("ZZ"+pos+"_",finish_bar-(zerot-time_arr[i]),finish_bar-(zerot-time_arr[i+1]),zero+(array[i+1]-shift-zero)*scale,zero+(array[i]-shift-zero)*scale,Color,width);

    if(pos=="best" || (pos!="best" && Max_linesBC<2))

    {

     if(i%2==0) line1[ i   /2]=zero+(array[i]-shift-zero)*scale;

     else       line2[(i-1)/2]=zero+(array[i]-shift-zero)*scale;

    }

    if(Recomend)

     {

      double ud=zero+(array[i]-shift-zero)*scale-Close[click];

      if(ud>0) buy +=ud;

      else     sell+=ud;

 /*     if(ShowOneDayTP && ((finish_bar-(zerot-time_arr[i]))-finish_bar)*_Period*60<PeriodSeconds(PERIOD_D1))

       {

        maxTP=MathMax(maxTP,zero-(array[i]-shift-zero)*scale);

        minTP=MathMin(minTP,zero-(array[i]-shift-zero)*scale);

       }*/

     }

   }

   

  if(Recomend && Nodes_Forecast>3 && (StringSubstr(pos,4)=="best" || (StringSubstr(pos,4)!="best" && Max_linesBC<2)))

  {

  double mid1=iMAOnArray(line1,0,Nodes_Forecast/2,0,MODE_SMA,0),

         mid2=iMAOnArray(line2,0,Nodes_Forecast/4,0,MODE_SMA,0),

         mid3=iMAOnArray(line2,0,Nodes_Forecast/8,0,MODE_SMA,0);

  

   DrawLineZZ("ZZM1_",click,finish_bar-(zerot-time_arr[Nodes_Forecast  -1]),mid1,Close[click],(mid1>Close[click]?clrBlue:clrOrange),1,STYLE_DOT);

   DrawLineZZ("ZZM2_",click,finish_bar-(zerot-time_arr[Nodes_Forecast/2-1]),mid2,Close[click],(mid2>Close[click]?clrBlue:clrOrange),1,STYLE_DOT);

   DrawLineZZ("ZZM3_",click,finish_bar-(zerot-time_arr[Nodes_Forecast/4-1]),mid3,Close[click],(mid3>Close[click]?clrBlue:clrOrange),1,STYLE_DOT);

  }

}





void DrawLineZZ(string pref,int i1,int i2,double p,double p_prev,color CLR=clrSalmon,int Width=1,ENUM_LINE_STYLE style=STYLE_SOLID)

{

  string Name=obj_pref2+pref+"_"+IntegerToString(i1,2)+IntegerToString(i2,2);

  datetime t1=i1<0?Time[0]-_Period*60*i1:Time[i1],

           t2=i2<0?Time[0]-_Period*60*i2:Time[i2];

  if(ObjectCreate(0,Name,OBJ_TREND,0,t1,p_prev,t2,p))

   {

    ObjectSetInteger(0,Name,OBJPROP_WIDTH,Width);

    ObjectSetInteger(0,Name,OBJPROP_STYLE,style);

    ObjectSetInteger(0,Name,OBJPROP_RAY_RIGHT,false);

    ObjectSetInteger(0,Name,OBJPROP_COLOR,CLR);

    ObjectSetInteger(0,Name,OBJPROP_HIDDEN,true);

    ObjectSetInteger(0,Name,OBJPROP_SELECTABLE,false);

    ObjectSetInteger(0,Name,OBJPROP_BACK,false);

  }

}





void FillArrayZZ(int InpDepth,int count_start=EMPTY_VALUE, int count_curr=0,bool fill=true)

  {

   

   uint begin=GetTickCount();

  

   int    i,limit=count_start=EMPTY_VALUE?Bars-InpDepth:count_start,whatlookfor=0;

   int    back,pos,lasthighpos=0,lastlowpos=0;

   double extremum;

   double curlow=0.0,curhigh=0.0,lasthigh=0.0,lastlow=0.0;



   if(Bars-1<InpDepth || InpBackstep>=InpDepth)

      return;



   ArrayInitialize(ExtZigzagBuffer,0.0);

   ArrayInitialize(ExtHighBuffer,0.0);

   ArrayInitialize(ExtLowBuffer,0.0);

   ArrayInitialize(up,0.0);

   ArrayInitialize(dn,0.0);



 if(!fill) {ZZ_filled=false;return;}



 if(Use_Close)

  {

   for(i=limit; i>count_curr; i--)

     {

      //--- find lowest Low in depth of bars

      extremum=Close[iLowest(NULL,0,MODE_CLOSE,InpDepth,i)];

      //--- this lowest has been found previously

      if(extremum==lastlow)

         extremum=0.0;

      else 

        { 

         //--- new last Low

         lastlow=extremum; 

         //--- discard extremum if current Low is too High

         if(Close[i]-extremum>=InpDeviation*Point)

            extremum=0.0;

         else

           {

            //--- clear previous extremums in backstep bars

            for(back=1; back<=InpBackstep; back++)

              {

               pos=i+back;

               if(ExtLowBuffer[pos]!=0 && ExtLowBuffer[pos]>=extremum)

                  ExtLowBuffer[pos]=0.0; 

              }

           }

        }

      //--- found extremum is current Low

      if(Close[i]==extremum) ExtLowBuffer[i]=extremum;

      else                   ExtLowBuffer[i]=0.0;

      dn[i]=ExtLowBuffer[i];

      //--- find highest High in depth of bars

      extremum=Close[iHighest(NULL,0,MODE_CLOSE,InpDepth,i)];

      //--- this highest has been found previously

      if(extremum==lasthigh)

         extremum=0.0;

      else 

        {

         //--- new last High

         lasthigh=extremum;

         //--- discard extremum if current High is too Low

         if(extremum-Close[i]>=InpDeviation*Point)

            extremum=0.0;

         else

           {

            //--- clear previous extremums in backstep bars

            for(back=1; back<=InpBackstep; back++)

              {

               pos=i+back;

               if(ExtHighBuffer[pos]!=0 && ExtHighBuffer[pos]<=extremum)

                  ExtHighBuffer[pos]=0.0; 

              }

           }

        }

      //--- found extremum is current High

      if(Close[i]==extremum) ExtHighBuffer[i]=extremum;

      else                   ExtHighBuffer[i]=0.0;

      up[i]=ExtHighBuffer[i];

     }

    }//Close

  else

  {

    for(i=limit; i>count_curr; i--)

     {

      //--- find lowest Low in depth of bars

      extremum=Low[iLowest(NULL,0,MODE_LOW,InpDepth,i)];

      //--- this lowest has been found previously

      if(extremum==lastlow)

         extremum=0.0;

      else 

        { 

         //--- new last Low

         lastlow=extremum; 

         //--- discard extremum if current Low is too High

         if(Low[i]-extremum>InpDeviation*Point)

            extremum=0.0;

         else

           {

            //--- clear previous extremums in backstep bars

            for(back=1; back<=InpBackstep; back++)

              {

               pos=i+back;

               if(ExtLowBuffer[pos]!=0 && ExtLowBuffer[pos]>extremum)

                  ExtLowBuffer[pos]=0.0; 

              }

           }

        }

      //--- found extremum is current Low

      if(Low[i]==extremum) ExtLowBuffer[i]=extremum;

      else                 ExtLowBuffer[i]=0.0;

      dn[i]=ExtLowBuffer[i];

      //--- find highest High in depth of bars

      extremum=High[iHighest(NULL,0,MODE_HIGH,InpDepth,i)];

      //--- this highest has been found previously

      if(extremum==lasthigh)

         extremum=0.0;

      else 

        {

         //--- new last High

         lasthigh=extremum;

         //--- discard extremum if current High is too Low

         if(extremum-High[i]>InpDeviation*Point)

            extremum=0.0;

         else

           {

            //--- clear previous extremums in backstep bars

            for(back=1; back<=InpBackstep; back++)

              {

               pos=i+back;

               if(ExtHighBuffer[pos]!=0 && ExtHighBuffer[pos]<extremum)

                  ExtHighBuffer[pos]=0.0;

              }

           }

        }

      //--- found extremum is current High

      if(High[i]==extremum) ExtHighBuffer[i]=extremum;

      else                  ExtHighBuffer[i]=0.0;

      up[i]=ExtHighBuffer[i];

     }

  }





//--- final cutting 

   if(whatlookfor==0)

     {

      lastlow=0.0;

      lasthigh=0.0;  

     }

   else

     {

      lastlow=curlow;

      lasthigh=curhigh;

     }

   for(i=limit; i>=0; i--)

     {

      switch(whatlookfor)

        {

         case 0: // look for peak or lawn 

            if(lastlow==0.0 && lasthigh==0.0)

              {

               if(ExtHighBuffer[i]!=0.0)

                 {

                  lasthigh=Use_Close?Close[i]:High[i];

                  lasthighpos=i;

                  whatlookfor=-1;

                  up[i]=ExtZigzagBuffer[i]=lasthigh;

                 }

               if(ExtLowBuffer[i]!=0.0)

                 {

                  lastlow=Use_Close?Close[i]:Low[i];

                  lastlowpos=i;

                  whatlookfor=1;

                  dn[i]=ExtZigzagBuffer[i]=lastlow;

                 }

              }

             break;  

         case 1: // look for peak

            if(ExtLowBuffer[i]!=0.0 && ExtLowBuffer[i]<=lastlow && ExtHighBuffer[i]==0.0)

              {

               ExtZigzagBuffer[lastlowpos]=0.0;

               lastlowpos=i;

               lastlow=ExtLowBuffer[i];

               dn[i]=ExtZigzagBuffer[i]=lastlow;

              }

            if(ExtHighBuffer[i]!=0.0 && ExtLowBuffer[i]==0.0)

              {

               lasthigh=ExtHighBuffer[i];

               lasthighpos=i;

               up[i]=ExtZigzagBuffer[i]=lasthigh;

               whatlookfor=-1;

              }   

            break;               

         case -1: // look for lawn

            if(ExtHighBuffer[i]!=0.0 && ExtHighBuffer[i]>=lasthigh && ExtLowBuffer[i]==0.0)

              {

               ExtZigzagBuffer[lasthighpos]=0.0;

               lasthighpos=i;

               lasthigh=ExtHighBuffer[i];

               up[i]=ExtZigzagBuffer[i]=lasthigh;

              }

            if(ExtLowBuffer[i]!=0.0 && ExtHighBuffer[i]==0.0)

              {

               lastlow=ExtLowBuffer[i];

               lastlowpos=i;

               dn[i]=ExtZigzagBuffer[i]=lastlow;

               whatlookfor=1;

              }   

            break;               

        }

     }



  Filled_Time=Time[0];

  //Print("Processing time: ",DoubleToString((GetTickCount()-begin)/1000.0,1)," sec");

  }

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---