ZigZag_Separate

Download script
Author: Copyright � 2005, MetaQuotes Software Corp.
ZigZag_Separate

This script is designed to identify and visualize significant price reversals on a trading chart by creating a "ZigZag" pattern. Instead of showing every minor fluctuation in price, it filters out the noise to highlight the major peaks (highs) and valleys (lows).

How the Logic Works

The tool processes market data through a three-stage logic flow to ensure that only the most important structural points are displayed:

1. Initial Peak and Valley Detection The script scans the historical price data looking for extreme highs and lows within a specific window of time (defined by your settings). It identifies a point as a potential "turn" only if the price move is significant enough to meet a minimum distance requirement. This prevents the indicator from reacting to tiny, insignificant wiggles in the market.

2. Proximity Filtering To keep the chart clean, the script performs a "backstep" check. If it finds a new high or low, it looks at the points immediately preceding it. If a newer, more significant point is found very close to an old one, it discards the older point. This ensures that the lines on your chart represent a continuous path rather than a cluttered mess of overlapping dots.

3. Dynamic Optimization (The "Final Cutting") The final stage of the logic is what makes this specific script effective. It performs a comprehensive review of all detected points to enforce a logical sequence:

  • Trend Validation: If a new high is reached that is higher than the previous recorded high, it automatically erases the old high and replaces it with the new one.
  • Alternating Sequence: The logic ensures that the chart follows a natural flow—switching between a high and a low. It prevents the script from marking two "highs" in a row without a "low" in between, which helps in accurately identifying the current trend direction.

Key Behavior Summary

The end result is a clean, connected line that snakes across your chart. It automatically ignores minor price movements until a significant reversal occurs, effectively "drawing" the skeleton of the market's movement. This allows you to see the clear structure of the market trends at a glance, making it easier to identify support and resistance levels.

Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
ZigZag_Separate
//+------------------------------------------------------------------+
//|                                        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_separate_window
#property indicator_buffers 1
#property indicator_color1 Yellow
//---- 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);
   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=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