ZigzagColorTwoLevels

Author: Copyright © 2019, Vladimir Karputov
0 Views
0 Downloads
0 Favorites
ZigzagColorTwoLevels
ÿþ//+------------------------------------------------------------------+

//|                                         ZigzagColorTwoLevels.mq5 |

//|                              Copyright © 2019, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

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

#property copyright "Copyright © 2019, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.000"

#property description "Based on the indicator ZigzagColor.mq5"

//--- indicator settings

#property indicator_chart_window

#property indicator_buffers 5

#property indicator_plots   1

#property indicator_type1   DRAW_COLOR_ZIGZAG

#property indicator_color1  clrDodgerBlue,clrRed

#property indicator_width1  2

//--- input parameters

input int ExtDepth=12;

input int ExtDeviation=5;

input int ExtBackstep=3;

int level=3; // recounting's depth 

//--- indicator buffers

double ZigzagPeakBuffer[];

double ZigzagLawnBuffer[];

double HighMapBuffer[];

double LowMapBuffer[];

double ColorBuffer[];

//---

double ExtPeak=0.0,ExtLawn=0.0;

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

//| Custom indicator initialization function                         |

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

void OnInit()

  {

//--- indicator buffers mapping

   SetIndexBuffer(0,ZigzagPeakBuffer,INDICATOR_DATA);

   SetIndexBuffer(1,ZigzagLawnBuffer,INDICATOR_DATA);

   SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX);

   SetIndexBuffer(3,HighMapBuffer,INDICATOR_CALCULATIONS);

   SetIndexBuffer(4,LowMapBuffer,INDICATOR_CALCULATIONS);



//--- set accuracy

   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

//--- name for DataWindow and indicator subwindow label

   IndicatorSetString(INDICATOR_SHORTNAME,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")");

   PlotIndexSetString(0,PLOT_LABEL,"ZigzagColor");

//--- set drawing line empty value

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);

   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);

  }

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

//| Indicator deinitialization function                              |

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

void OnDeinit(const int reason)

  {

//---

   HLineDelete(0,"HLine_Peak");

   HLineDelete(0,"HLine_Medium");

   HLineDelete(0,"HLine_Lawn");

  }

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

//| get highest value for range                                      |

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

double Highest(const double&array[],int range,int fromIndex)

  {

   double res;

//---

   res=array[fromIndex];

   for(int i=fromIndex;i>fromIndex-range && i>=0;i--)

     {

      if(res<array[i]) res=array[i];

     }

//---

   return(res);

  }

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

//| get lowest value for range                                       |

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

double Lowest(const double&array[],int range,int fromIndex)

  {

   double res;

//---

   res=array[fromIndex];

   for(int i=fromIndex;i>fromIndex-range && i>=0;i--)

     {

      if(res>array[i]) res=array[i];

     }

//---

   return(res);

  }

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

//| Detrended Price Oscillator                                       |

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

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

  {

   int i,limit=0;

//--- check for rates count

   if(rates_total<100)

     {

      //--- clean up arrays

      ArrayInitialize(ZigzagPeakBuffer,0.0);

      ArrayInitialize(ZigzagLawnBuffer,0.0);

      ArrayInitialize(HighMapBuffer,0.0);

      ArrayInitialize(LowMapBuffer,0.0);

      ArrayInitialize(ColorBuffer,0.0);

      //--- exit with zero result

      return(0);

     }

//--- preliminary calculations

   int counterZ=0,whatlookfor=0;

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

   double val=0,res=0;

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

//--- set empty values

   if(prev_calculated==0)

     {

      ArrayInitialize(ZigzagPeakBuffer,0.0);

      ArrayInitialize(ZigzagLawnBuffer,0.0);

      ArrayInitialize(HighMapBuffer,0.0);

      ArrayInitialize(LowMapBuffer,0.0);

      //--- start calculation from bar number ExtDepth

      limit=ExtDepth-1;

     }

//---

   if(prev_calculated>0)

     {

      i=rates_total-1;

      while(counterZ<level && i>rates_total -100)

        {

         res=(ZigzagPeakBuffer[i]+ZigzagLawnBuffer[i]);

         //---

         if(res!=0) counterZ++;

         i--;

        }

      i++;

      limit=i;

      //---

      if(LowMapBuffer[i]!=0)

        {

         curlow=LowMapBuffer[i];

         whatlookfor=1;

        }

      else

        {

         curhigh=HighMapBuffer[i];

         whatlookfor=-1;

        }

      //---

      for(i=limit+1;i<rates_total && !IsStopped();i++)

        {

         ZigzagPeakBuffer[i]=0.0;

         ZigzagLawnBuffer[i]=0.0;

         //ArrowUp[i]=0.0;

         //ArrowDown[i]=0.0;

         LowMapBuffer[i]=0.0;

         HighMapBuffer[i]=0.0;

        }

     }

//----

   for(shift=limit;shift<rates_total && !IsStopped();shift++)

     {

      val=Lowest(low,ExtDepth,shift);

      //---

      if(val==lastlow) val=0.0;

      else

        {

         lastlow=val;

         //---

         if((low[shift]-val)>(ExtDeviation*_Point)) val=0.0;

         else

           {

            //---

            for(back=ExtBackstep;back>=1;back--)

              {

               res=LowMapBuffer[shift-back];

               //---

               if((res!=0) && (res>val)) LowMapBuffer[shift-back]=0.0;

              }

           }

        }

      //---

      if(low[shift]==val) LowMapBuffer[shift]=val;

      else

         LowMapBuffer[shift]=0.0;

      //--- high

      val=Highest(high,ExtDepth,shift);

      //---

      if(val==lasthigh) val=0.0;

      else

        {

         lasthigh=val;

         //---

         if((val-high[shift])>(ExtDeviation*_Point)) val=0.0;

         else

           {

            //---

            for(back=ExtBackstep;back>=1;back--)

              {

               res=HighMapBuffer[shift-back];

               //---

               if((res!=0) && (res<val)) HighMapBuffer[shift-back]=0.0;

              }

           }

        }

      //---

      if(high[shift]==val) HighMapBuffer[shift]=val;

      else  HighMapBuffer[shift]=0.0;

     }

// final cutting 

   if(whatlookfor==0)

     {

      lastlow=0;

      lasthigh=0;

     }

   else

     {

      lastlow=curlow;

      lasthigh=curhigh;

     }

//----

   for(shift=limit;shift<rates_total && !IsStopped();shift++)

     {

      res=0.0;

      switch(whatlookfor)

        {

         // look for peak or lawn 

         case 0: if(lastlow==0 && lasthigh==0)

           {

            if(HighMapBuffer[shift]!=0)

              {

               lasthigh=high[shift];

               lasthighpos=shift;

               whatlookfor=-1;

               ZigzagPeakBuffer[shift]=lasthigh;

               ColorBuffer[shift]=0;

               res=1;

              }

            if(LowMapBuffer[shift]!=0)

              {

               lastlow=low[shift];

               lastlowpos=shift;

               whatlookfor=1;

               ZigzagLawnBuffer[shift]=lastlow;

               ColorBuffer[shift]=1;

               res=1;

              }

           }

         break;

         // look for peak

         case 1: if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow &&

                    HighMapBuffer[shift]==0.0)

           {

            ZigzagLawnBuffer[lastlowpos]=0.0;

            lastlowpos=shift;

            lastlow=LowMapBuffer[shift];

            ZigzagLawnBuffer[shift]=lastlow;

            ColorBuffer[shift]=1;

            res=1;

           }

         if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)

           {

            lasthigh=HighMapBuffer[shift];

            lasthighpos=shift;

            ZigzagPeakBuffer[shift]=lasthigh;

            ColorBuffer[shift]=0;

            whatlookfor=-1;

            res=1;

           }

         break;

         // look for lawn

         case -1:  if(HighMapBuffer[shift]!=0.0 && 

                      HighMapBuffer[shift]>lasthigh && 

                      LowMapBuffer[shift]==0.0)

           {

            ZigzagPeakBuffer[lasthighpos]=0.0;

            lasthighpos=shift;

            lasthigh=HighMapBuffer[shift];

            ZigzagPeakBuffer[shift]=lasthigh;

            ColorBuffer[shift]=0;

           }

         if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)

           {

            lastlow=LowMapBuffer[shift];

            lastlowpos=shift;

            ZigzagLawnBuffer[shift]=lastlow;

            ColorBuffer[shift]=1;

            whatlookfor=1;

           }

         break;

         default: return(rates_total);

        }



     }

   ExtPeak=0.0;ExtLawn=0.0;

   for(int j=rates_total-1-1;j>rates_total-1-100;j--)

     {

      if(ZigzagPeakBuffer[j]!=0.0)

         ExtPeak=ZigzagPeakBuffer[j];

      if(ZigzagLawnBuffer[j]!=0.0)

         ExtLawn=ZigzagLawnBuffer[j];

      if(ExtPeak!=0.0 && ExtLawn!=0.0)

        {

         HLineMove(0,"HLine_Peak",ExtPeak,0,clrTomato);

         HLineMove(0,"HLine_Medium",(ExtPeak+ExtLawn)/2.0,0,clrGreenYellow);

         HLineMove(0,"HLine_Lawn",ExtLawn,0,clrRoyalBlue);

         break;

        }

     }

//--- OnCalculate done. Return new prev_calculated.

   return(rates_total);

  }

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

//| Create the horizontal line                                       | 

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

bool HLineCreate(const long            chart_ID=0,        // chart's ID 

                 const string          name="HLine",      // line name 

                 const int             sub_window=0,      // subwindow index 

                 double                price=0,           // line price 

                 const color           clr=clrRed,        // line color 

                 const ENUM_LINE_STYLE style=STYLE_DASH,  // line style 

                 const int             width=1,           // line width 

                 const bool            back=false,        // in the background 

                 const bool            selection=false,   // highlight to move 

                 const bool            hidden=true,       // hidden in the object list 

                 const long            z_order=0)         // priority for mouse click 

  {

//--- if the price is not set, set it at the current Bid price level 

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value 

   ResetLastError();

//--- create a horizontal line 

   if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price))

     {

      Print(__FUNCTION__,

            ": failed to create a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- set line color 

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- set line display style 

   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);

//--- set line width 

   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);

//--- display in the foreground (false) or background (true) 

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the line by mouse 

//--- when creating a graphical object using ObjectCreate function, the object cannot be 

//--- highlighted and moved by default. Inside this method, selection parameter 

//--- is true by default making it possible to highlight and move the object 

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- hide (true) or display (false) graphical object name in the object list 

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart 

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//--- successful execution 

   return(true);

  }

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

//| Move horizontal line                                             | 

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

bool HLineMove(const long   chart_ID=0,   // chart's ID 

               const string name="HLine", // line name 

               double       price=0,      // line price 

               const int    sub_window=0, // subwindow index 

               const color  clr=clrRed)   // line color

  {

//--- if the line price is not set, move it to the current Bid price level 

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//---

   if(ObjectFind(chart_ID,name)<0)

      return(HLineCreate(chart_ID,name,sub_window,price,clr));

//--- reset the error value 

   ResetLastError();

//--- move a horizontal line 

   if(!ObjectMove(chart_ID,name,0,0,price))

     {

      Print(__FUNCTION__,

            ": failed to move the horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

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

//| Delete a horizontal line                                         | 

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

bool HLineDelete(const long   chart_ID=0,   // chart's ID 

                 const string name="HLine") // line name 

  {

//--- reset the error value 

   ResetLastError();

//--- delete a horizontal line 

   if(!ObjectDelete(chart_ID,name))

     {

      Print(__FUNCTION__,

            ": failed to delete a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

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

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