Author: Copyright � 2005, MetaQuotes Software Corp.
ZigZag2

This script is designed to create a "ZigZag" visual aid on your trading charts. Its primary purpose is to filter out the minor "noise" of constant price fluctuations, allowing you to see the broader structural trends by identifying significant peaks (highs) and valleys (lows) in market movement.

How the Logic Works

The script processes price data through a multi-stage filtering system to ensure that only meaningful price extremes are displayed:

1. Identifying Potential Extremes The tool scans the recent history of price candles. It looks for the highest highs and lowest lows within a specific window (defined by the user's settings). However, it doesn't mark every tiny movement as a peak; it uses a "deviation" threshold. If a price move is too small, the script ignores it, ensuring that only significant swings are captured.

2. Smoothing and Backstepping To prevent the chart from appearing cluttered with jagged lines, the logic incorporates a "backstep" mechanism. This checks neighboring candles to ensure that a point is truly a unique turning point. If multiple consecutive candles show similar highs or lows, the script prioritizes the most significant one and removes the others.

3. The Peak-to-Valley Validation (The ZigZag Effect) This is the core intelligence of the script. It follows a strict rule of sequence: a new "High" cannot be confirmed until a "Low" has been established, and vice versa.

  • If the price creates a new high that is higher than the previous confirmed high, it updates the line.
  • If the price continues to move in one direction without hitting a significant reversal point, the script keeps the line straight.
  • It effectively "connects the dots" between major structural pivots.

4. Final Refinement and Connection In the final stage of its calculation, the script performs a cleanup pass. It ensures that the lines are drawn correctly from one turning point to the next without overlapping or creating impossible price paths. It also handles the transition between high-point segments and low-point segments, resulting in the continuous, angular "zigzag" line seen on the chart.

Summary for the Trader

Instead of watching every tick of price movement, this tool helps you visualize the "skeleton" of the market. It highlights where the price has fundamentally shifted direction, making it easier to identify support and resistance levels, trend changes, and major market swings at a glance.

Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
ZigZag2
//+------------------------------------------------------------------+
//|                                        Custom Moving Average.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//---- indicator buffers
double ExtMapBuffer[];
double ExtMapBuffer2[];
int cbars=100;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(2);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexEmptyValue(0,0.0);
   ArraySetAsSeries(ExtMapBuffer,true);
   ArraySetAsSeries(ExtMapBuffer2,true);
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    shift, back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   for(shift=cbars-ExtDepth; shift>=0; shift--)
     {
      val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,shift)];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtMapBuffer[shift+back];
               if((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0; 
              }
           }
        } 
      ExtMapBuffer[shift]=val;
      //--- high
      val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtMapBuffer2[shift+back];
               if((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0; 
              } 
           }
        }
      ExtMapBuffer2[shift]=val;
     }

   // final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=cbars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtMapBuffer[shift];
      curhigh=ExtMapBuffer2[shift];
      if((curlow==0)&&(curhigh==0)) continue;
      //---
      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) ExtMapBuffer2[lasthighpos]=0;
            else ExtMapBuffer2[shift]=0;
           }
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }
      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtMapBuffer[lastlowpos]=0;
            else ExtMapBuffer[shift]=0;
           }
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     }
  
   for(shift=cbars-1; shift>=0; shift--)
     {
      if(shift>=cbars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         res=ExtMapBuffer2[shift];
         if(res!=0.0) ExtMapBuffer[shift]=res;
        }
     }
  }

Comments