# aa_ZigZag Pointer
Download scriptThis tool is designed to provide a clear visual representation of significant price movements by identifying and marking key structural points—specifically, the peaks (highs) and valleys (lows)—within a trading chart. Rather than cluttering your screen with every minor fluctuation, this logic filters out "market noise" to highlight the most meaningful trends.
How the Logic Works
The script operates through a multi-layered filtering process to ensure that only the most prominent price points are displayed:
1. Identifying Potential Extremes The tool constantly scans the historical price data based on user-defined depth and deviation settings. It looks for price points that stand out as significant local highs or lows. If a new price point is discovered, the script evaluates whether it qualifies as a "turning point" based on how far it deviates from previous prices.
2. Smoothing and Backstepping To prevent the indicator from reacting to every tiny tick, the logic incorporates a "backstep" feature. This ensures that if multiple price points occur in very rapid succession, only the most significant one is kept. It effectively cleans up the path between high and low points so the resulting trend lines appear smooth and intentional.
3. Dynamic Correction (The "Final Cutting") One of the most sophisticated parts of this logic is its ability to correct itself in real-time. Because markets are fluid, a high point might be surpassed by even higher price action shortly after it appears. The script performs a secondary pass over the data to ensure that:
- A new peak will "overwrite" or remove an older, lower peak if they occur in the same sequence.
- A new valley will "overwrite" or remove an older, higher valley.
This ensures that the visual path always moves logically from one major high to the next major low (and vice versa), creating a continuous, connected structure of the market's trajectory.
Summary for the User
In simple terms, this script acts like a "trend filter." It ignores the minor ups and downs of the minute-by-minute price action and draws out the skeleton of the market move. By highlighting these primary turning points, it helps traders visualize the broader direction of the market, making it easier to identify support levels, resistance zones, and overall trend reversals.
//+------------------------------------------------------------------+
//| ZigZag Pointer.mq4 |
//| zigzag modified by Dr. Gaines |
//| dr_richard_gaines@yahoo.com |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "dr_richard_gaines"
#property link "http://www.metaquotes.net/"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_width1 1
#property indicator_color2 Red
#property indicator_width2 1
//---- 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_ARROW);
SetIndexArrow(0, 233);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 234);
//---- 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) ExtMapBuffer2[shift]=res;
}
}
}
//end//
Comments