Author: Copyright � 2005, MetaQuotes Software Corp.
ZigZag_v4

This script is designed to generate a visual "ZigZag" pattern on your trading charts. Its primary purpose is to filter out minor market noise and highlight the significant structural turns in price movement, making it easier for a trader to identify major highs and lows.

How the Logic Works

The tool operates by scanning through historical price data and applying several layers of filtering logic to determine which price points are important enough to be plotted as part of the zigzag line.

1. Identifying Significant Extremes Instead of marking every single price tick, the script looks at a specific "depth" of candles (defined by the user settings). It searches for the highest high and the lowest low within that window. By doing this, it ignores small fluctuations and only pays attention to peaks and valleys that represent a meaningful move in price.

2. Filtering by Movement (Deviation) To prevent the line from jumping around due to tiny price changes, the script uses a "deviation" rule. It calculates the distance between the current price and the previous significant point. If the move is too small, the script ignores it. This ensures that the zigzag only creates a new point when the market has moved a substantial amount in one direction.

3. Refining the Shape (Backstepping) The script also incorporates a "backstep" logic. This acts as a secondary verification step where it looks back at recent bars to ensure that the peak or valley identified is actually the most extreme point in that local area. If it finds a more significant point nearby, it adjusts the data to maintain a clean, continuous line.

4. Establishing Trends and Alternation The logic is programmed to recognize the natural flow of the market: after a major high is established, the script looks for a low, and vice versa. It uses a "final cutting" process to compare new points against previous ones. If a new high is formed that is higher than the previous one, or a new low is formed that is lower than the last one, it corrects the coordinates to ensure the zigzag line accurately reflects the most extreme price boundaries reached during that trend.

Summary for the User

In plain terms, this script acts as a visual "cleaner" for your chart. It ignores the "jitter" of daily price movements and draws a clear path connecting the most important high and low points. This allows you to see the underlying structure of the market trends more clearly, helping you identify where the price is reversing or consolidating.

Miscellaneous
Implements a curve of type %1
5 Views
0 Downloads
0 Favorites
ZigZag_v4
//+------------------------------------------------------------------+
//|                                        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[];

//+------------------------------------------------------------------+
//| 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);
//---- 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=Bars-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=Bars-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=Bars-1; shift>=0; shift--)
     {
      if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         res=ExtMapBuffer2[shift];
         if(res!=0.0) ExtMapBuffer[shift]=res;
        }
     }
  }

Comments