ZigZag_hist

Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
ZigZag_hist
// + ------------------------------------------------------------------ + 
//|                                                     ZigZag hist.mq4 |
// + ------------------------------------------------------------------ + 
#property strict

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1  clrGoldenrod
#property indicator_color2  clrDodgerBlue
#property indicator_color3  clrRed
#property indicator_width1  1
#property indicator_width2  2
#property indicator_width3  3
//---- indicator parameters
input int InpDepth         = 12;    // Depth
input int InpDeviation     = 5;     // Deviation
input int InpBackstep      = 3;     // Backstep
//---- indicator buffers
double ExtZigzagBuffer[];
double ExtHighBuffer[];
double ExtLowBuffer[];
double BuyBuffer[];
double SellBuffer[];
//--- globals
int    ExtLevel=3; // recounting's depth of extremums
// + ------------------------------------------------------------------ + 
//| Custom indicator initialization function                         |
// + ------------------------------------------------------------------ + 
int OnInit()
{
   if(InpBackstep>=InpDepth)
   {
      Print("Backstep cannot be greater or equal to Depth");
      return(INIT_FAILED);
   }
   //--- 2 additional buffers
   IndicatorBuffers(5);
   //---- drawing settings
   SetIndexStyle(0, DRAW_SECTION);
   SetIndexStyle(1, DRAW_LINE, STYLE_DOT, 1);
   SetIndexStyle(2, DRAW_LINE, STYLE_DOT, 1);
   //---- indicator buffers
   SetIndexBuffer(0, ExtZigzagBuffer);
   SetIndexBuffer(1, BuyBuffer);
   SetIndexBuffer(2, SellBuffer);
   SetIndexBuffer(3, ExtHighBuffer);
   SetIndexBuffer(4, ExtLowBuffer);
   SetIndexEmptyValue(0, 0.0);
   //---- indicator short name
   IndicatorShortName("ZigZag(" + string(InpDepth) +    + string(InpDeviation) + "," + string(InpBackstep) + ")");
   //---- initialization done
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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, counterZ, whatlookfor = 0;
   int    back, pos, lasthighpos = 0, lastlowpos = 0;
   double extremum;
   double curlow = 0.0, curhigh = 0.0, lasthigh = 0.0, lastlow = 0.0;
   //--- check for history and inputs
   if(rates_total < InpDepth || InpBackstep >= InpDepth)
      return(0);
   //--- first calculations
   if(prev_calculated == 0)
      limit = InitializeAll();
   else 
   {
      //--- find first extremum in the depth ExtLevel or 100 last bars
      i = counterZ = 0;
      while(counterZ < ExtLevel && i < 100)
      {
         if(ExtZigzagBuffer[i] != 0.0)
         counterZ ++;
         i ++;
      }
      //--- no extremum found - recounting all from begin
      if(counterZ == 0)
         limit = InitializeAll();
      else
      {
         //--- set start position to found extremum position
         limit = i - 1;
         //--- what kind of extremum?
         if(ExtLowBuffer[i] != 0.0) 
         {
            //--- low extremum
            curlow = ExtLowBuffer[i];
            //--- will look for the next high extremum
            whatlookfor = 1;
         }
         else
         {
            //--- high extremum
            curhigh = ExtHighBuffer[i];
            //--- will look for the next low extremum
            whatlookfor = -1;
         }
         //--- clear the rest data
         for(i = limit - 1; i >= 0; i --)  
         {
            ExtZigzagBuffer[i] = 0.0;  
            ExtLowBuffer[i] = 0.0;
            ExtHighBuffer[i] = 0.0;
         }
      }
   }
   //--- main loop      
   for(i = limit; i >= 0; 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;
      //--- 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;
   }
   //--- 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 = High[i];
                  lasthighpos = i;
                  whatlookfor = -1;
                  ExtZigzagBuffer[i] = lasthigh;
                  BuyBuffer[i] = lasthigh;
               }
               if(ExtLowBuffer[i]!=0.0)
               {
                  lastlow = Low[i];
                  lastlowpos = i;
                  whatlookfor = 1;
                  ExtZigzagBuffer[i] = lastlow;
                  SellBuffer[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];
               ExtZigzagBuffer[i] = lastlow;
               SellBuffer[i] = lastlow;
            } else
            if(ExtHighBuffer[i] != 0.0 && ExtLowBuffer[i] == 0.0)
            {
               lasthigh = ExtHighBuffer[i];
               lasthighpos = i;
               ExtZigzagBuffer[i] = lasthigh;
               whatlookfor = -1;
               BuyBuffer[i] = lasthigh;
            } else
               SellBuffer[i] = lastlow;
            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];
               ExtZigzagBuffer[i] = lasthigh;
               BuyBuffer[i] = lasthigh;
            } else
            if(ExtLowBuffer[i] != 0.0 && ExtHighBuffer[i] == 0.0)
            {
               lastlow = ExtLowBuffer[i];
               lastlowpos = i;
               ExtZigzagBuffer[i] = lastlow;
               whatlookfor = 1;
               SellBuffer[i] = lastlow;
            } else
               BuyBuffer[i] = lasthigh;//---
               
            break;               
      }
   }
   //--- done
   return(rates_total);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int InitializeAll()
{
   ArrayInitialize(ExtZigzagBuffer, 0.0);
   ArrayInitialize(ExtHighBuffer, 0.0);
   ArrayInitialize(ExtLowBuffer, 0.0);
   //--- first counting position
   return(Bars-InpDepth);
}
//+------------------------------------------------------------------+

Comments