ZigZagS

This script is designed to provide a visual representation of market trends by identifying and connecting significant price "peaks" and "valleys." It automates the process of filtering out minor market noise to highlight the core movements of the price action.

Core Logic Overview

The logic operates in three primary phases to ensure that only the most relevant price points are displayed on your chart:

1. Identifying Potential Turning Points The script scans historical price data based on a specific look-back period (Depth). It searches for local highs and lows within this window. To prevent the chart from becoming cluttered with every tiny fluctuation, it uses two filters:

  • Deviation: This ensures that a new high or low is only recognized if it moves a significant enough distance from the previous point.
  • Backstep: This acts as a smoothing mechanism. It checks recent price bars to ensure that the identified point is indeed the most extreme price in its immediate neighborhood, effectively "cleaning up" small zig-zags.

2. Refining and Pruning the Data Once the potential highs and lows are identified, the script performs a "final cutting" process. It reviews the sequence of points to ensure they follow a logical progression. If a new high is found that is higher than a previously recorded one in the same direction, the script intelligently updates the path. This logic ensures that the line moves forward logically rather than jumping back and forth between minor price ticks.

3. Visual Connection Finally, the script organizes these refined points into a continuous "ZigZag" line. It connects the highs to the lows sequentially, providing a clear visual map of the market's structure. This allows a user to easily see the broader trend—identifying where the market is shifting from bullish to bearish or vice versa.

Key Functional Parameters

  • Depth: Determines how far back the script looks to find a high or low (larger values result in a "smoother" line that captures bigger trends).
  • Deviation: Controls the minimum change required to consider a new point significant.
  • Backstep: Determines how many bars to check to confirm that a point is the actual highest/lowest in its immediate area.
  • nBars: Limits the analysis to a specific number of recent candles, helping to maintain performance and focus on current market conditions.
Miscellaneous
Implements a curve of type %1
15 Views
0 Downloads
0 Favorites
ZigZagS
//+------------------------------------------------------------------+
//|                                                      ZigZagS.mq4 |
//+------------------------------------------------------------------+

#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;
extern int nBars=50;
//---- 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, LoopBegin;
  double val, res;
  double curlow, curhigh, lasthigh, lastlow;

 	if (nBars==0) LoopBegin=Bars-ExtDepth;
  else LoopBegin=nBars;
  LoopBegin=MathMin(Bars-ExtDepth, LoopBegin);

  for(shift=LoopBegin; 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