ZigZag_Counter

Author: Copyright 2018, MetaQuotes Software Corp.
Price Data Components
0 Views
0 Downloads
0 Favorites
ZigZag_Counter
ÿþ//+------------------------------------------------------------------+

//|                                               ZigZag_Counter.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                                 https://mql5.com |

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

#property copyright "Copyright 2018, MetaQuotes Software Corp."

#property link      "https://mql5.com"

#property version   "1.00"

#property description "ZigZag Counter indicator"

#property indicator_chart_window

#property indicator_buffers 1

#property indicator_plots   1

//--- plot ZZ

#property indicator_label1  "ZZ Counter"

#property indicator_type1   DRAW_SECTION

#property indicator_color1  clrRed

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- input parameters

input uint     InpDepth       =  12;         // Depth

input uint     InpDeviation   =  5;          // Deviation

input uint     InpBackstep    =  3;          // Backstep

input color    InpFontColorUP =  clrBrown;   // Upper labels color

input color    InpFontColorDN =  clrNavy;    // Lower labels color

input uint     InpFontSize    =  8;          // Labels font size

input string   InpFontName    =  "Calibri";  // Labels font name

//--- indicator buffers

double         BufferZZ[];

//--- structures

struct SDataZZ

  {

   double      price;

   int         index;

  };

//--- global variables

SDataZZ        data_zz[4];

string         prefix;

string         tf;

string         params;

int            depth;

int            deviation;

int            backstep;

int            font_size;

int            count_zz;

int            handle_zz;

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- setting global variables

   depth=int(InpDepth<1 ? 1 : InpDepth);

   deviation=(int)InpDeviation;

   backstep=(int)InpBackstep;

   font_size=int(InpFontSize<6 ? 6 : InpFontSize);

   tf=TimeframeToString(Period());

   prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_"+tf+"_";

   count_zz=ArraySize(data_zz);

   for(int i=0;i<count_zz;i++)

     {

      data_zz[i].index=WRONG_VALUE;

      data_zz[i].price=0;

     }

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferZZ,INDICATOR_DATA);

//--- settings plots parameters

   PlotIndexSetString(0,PLOT_LABEL,"ZZ Counter");

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);

//--- setting indicator parameters

   params=(string)depth+","+(string)deviation+","+(string)backstep;

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

   IndicatorSetString(INDICATOR_SHORTNAME,"ZZ Counter("+params+")");

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferZZ,true);

//--- create ZZ handles

   ResetLastError();

   handle_zz=iCustom(NULL,PERIOD_CURRENT,"Examples\\ZigZag",depth,deviation,backstep);

   if(handle_zz==INVALID_HANDLE)

     {

      Print("The iCustom(MQL5/Indicators/Examples/ZigZag (",(string)depth,",",(string)deviation,",",(string)backstep,")) object was not created: Error ",GetLastError());

      return INIT_FAILED;

     }

//---

   return(INIT_SUCCEEDED);

  }

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

//| Custom indicator deinitialization function                       |

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

void OnDeinit(const int reason)

  {

   ObjectsDeleteAll(0,prefix);

   ChartRedraw(0);

  }

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

//| Custom indicator iteration function                              |

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

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[])

  {

//--- @>25@:0 =0 <8=8<0;L=>5 :>;85AB2> 10@>2 4;O @0AGQB0

   if(rates_total<fmax(4,depth*2) || Point()==0) return 0;

//--- #AB0=>2:0 8=45:A0F88 <0AA82>2 :0: C B09<A5@89

   ArraySetAsSeries(open,true);

   ArraySetAsSeries(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(close,true);

   ArraySetAsSeries(time,true);

//--- @>25@:0 8 @0AGQB :>;8G5AB20 ?@>AG8BK205<KE 10@>2

   int limit=rates_total-prev_calculated;

   if(limit>1)

     {

      limit=rates_total-depth-1;

      ArrayInitialize(BufferZZ,0);

      ObjectsDeleteAll(0,prefix);

      ChartRedraw();

     }

//--- >43>B>2:0 40==KE

   int count=(limit>0 ? rates_total : 1),copied=0;

   copied=CopyBuffer(handle_zz,0,0,count,BufferZZ);

   if(copied!=count) return 0;



//---  0AGQB 8=48:0B>@0

   for(int i=0;i<count_zz;i++)

     {

      data_zz[i].index=WRONG_VALUE;

      data_zz[i].price=0;

     }

   for(int i=limit; i>=0 && !IsStopped(); i--)

     {

      Counter(rates_total,i,count_zz,data_zz,BufferZZ,time,params,InpFontColorUP,InpFontColorDN);

     }



//--- return value of prev_calculated for next call

   return(rates_total);

  }

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

//| !GQBG8:                                                          |

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

void Counter(const int rates_total,

             const int shift,

             const int count,

             SDataZZ &zz_data[],

             double &buffer_zz[],

             const datetime &time[],

             const string params_zz,

             const color color_up,

             const color color_dn

            )

  {

   GetLastNumExtremumSection(rates_total,shift,count,zz_data,buffer_zz);

   for(int i=0;i<count;i++)

      if(zz_data[i].index==WRONG_VALUE)

         return;

   if(IsExtremum(data_zz[2].price,data_zz[1].price,data_zz[0].price))

     {

      int diff_price2=int(fabs((data_zz[3].price-data_zz[2].price)/Point()));

      int diff_price1=int(fabs((data_zz[2].price-data_zz[1].price)/Point()));

      int diff_price0=int(fabs((data_zz[1].price-data_zz[0].price)/Point()));

      int diff_index2=data_zz[3].index-data_zz[2].index;

      int diff_index1=data_zz[2].index-data_zz[1].index;

      int diff_index0=data_zz[1].index-data_zz[0].index;

      string text2=(string)diff_index2+" bars, "+(string)diff_price2+" points";

      string text1=(string)diff_index1+" bars, "+(string)diff_price1+" points";

      string text0=(string)diff_index0+" bars, "+(string)diff_price0+" points";

      

      string name2=prefix+params_zz+"_"+TimeToString(time[data_zz[3].index]);

      string name1=prefix+params_zz+"_1";

      string name0=prefix+params_zz+"_0";

      

      ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT;

      string direct="";

      color  clr=clrGray;

      if(data_zz[2].price<data_zz[1].price)

        {

         DrawLabel(name2,text2,direct+"Lower ZigZag extremum\n"+tf+": "+text2,data_zz[2].price,time[data_zz[2].index],ANCHOR_LEFT_UPPER,color_dn);

         DrawLabel(name1,text1,direct+"Upper ZigZag extremum\n"+tf+": "+text1,data_zz[1].price,time[data_zz[1].index],ANCHOR_LEFT_LOWER,color_up);

         DrawLabel(name0,text0,direct+"Lower ZigZag extremum\n"+tf+": "+text0,data_zz[0].price,time[data_zz[0].index],ANCHOR_LEFT_UPPER,color_dn);

        }

      else

        {

         DrawLabel(name2,text2,direct+"Upper ZigZag extremum\n"+tf+": "+text2,data_zz[2].price,time[data_zz[2].index],ANCHOR_LEFT_LOWER,color_up);

         DrawLabel(name1,text1,direct+"Lower ZigZag extremum\n"+tf+": "+text1,data_zz[1].price,time[data_zz[1].index],ANCHOR_LEFT_UPPER,color_dn);

         DrawLabel(name0,text0,direct+"Upper ZigZag extremum\n"+tf+": "+text0,data_zz[0].price,time[data_zz[0].index],ANCHOR_LEFT_LOWER,color_up);

        }

     }

  }

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

//| >72@0I05B =0;8G85 M:AB@5<C<0                                    |

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

bool IsExtremum(double a, double b, double c)

  {

   return((a-b)*(b-c)<0);

  }

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

//| K2>4 <5B:8                                                      |

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

void DrawLabel(const string name,

               const string text,

               const string tooltip,

               const double price,

               const datetime time,

               const ENUM_ANCHOR_POINT anchor,

               const color clr=clrGray

              )

  {

   if(ObjectFind(0,name)<0)

     {

      ObjectCreate(0,name,OBJ_TEXT,0,0,0);

      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);

      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,InpFontSize);

      ObjectSetString(0,name,OBJPROP_FONT,InpFontName);

     }

   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);

   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);

   ObjectSetInteger(0,name,OBJPROP_TIME,time);

   ObjectSetDouble(0,name,OBJPROP_PRICE,price);

   ObjectSetString(0,name,OBJPROP_TEXT,text);

   ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);

//---

   string nm=name+"_HL";

   if(ObjectFind(0,nm)<0)

     {

      ObjectCreate(0,nm,OBJ_TREND,0,0,0);

      ObjectSetInteger(0,nm,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,nm,OBJPROP_HIDDEN,true);

      ObjectSetInteger(0,nm,OBJPROP_STYLE,STYLE_DOT);

      ObjectSetInteger(0,nm,OBJPROP_RAY,false);

     }

   ObjectSetInteger(0,nm,OBJPROP_COLOR,clr);

   ObjectSetInteger(0,nm,OBJPROP_TIME,0,time);

   ObjectSetInteger(0,nm,OBJPROP_TIME,1,time+PeriodSeconds()*5);

   ObjectSetDouble(0,nm,OBJPROP_PRICE,0,price);

   ObjectSetDouble(0,nm,OBJPROP_PRICE,1,price);

   ObjectSetString(0,nm,OBJPROP_TOOLTIP,"\n");

  }

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

//| 0?8AK205B 2 <0AA82 7040==>5 :>;8G5AB2>                          |

//| ?>A;54=8E M:AB@5<C<0 8=48:0B>@0 ZigZag A B8?>< DRAW_SECTION      |

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

void GetLastNumExtremumSection(const int rates_total,const int shift,const int count,SDataZZ &array[],const double &buffer_zz[])

  {

   if(count<1) return;

   int j=0;

   for(int i=shift; i<rates_total; i++) {

      if(buffer_zz[i]!=0) {

         array[j].index=i;

         array[j].price=buffer_zz[i];

         j++;

         if(j>count-1) break;

         }

      }

  }

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

//| Timeframe to string                                              |

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

string TimeframeToString(const ENUM_TIMEFRAMES timeframe)

  {

   return StringSubstr(EnumToString(timeframe),7);

  }

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

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 ---