ZigZag1_v1
Download scriptThis script functions as a specialized visual tool designed to identify and map out significant structural turning points in financial market price action. Often referred to as a "ZigZag" indicator, its primary purpose is to filter out the "noise" of minor price fluctuations to reveal the underlying trend of the market.
Core Logic and Behavior
The script operates by analyzing price data through three distinct logical layers:
1. Significant Extremes Identification Rather than marking every single price movement, the script scans historical data to find specific peaks (highs) and valleys (lows). It uses three user-defined parameters to determine what qualifies as a "significant" move:
- Depth: Defines how far back the script looks to find a high or low point.
- Deviation: Acts as a threshold; if a price move is smaller than this amount, the script ignores it as insignificant noise.
- Backstep: Ensures that the points identified are distinct from one another by requiring a minimum "gap" between consecutive marks.
2. Dynamic Filtering As the script moves forward in time, it constantly evaluates new high and low points against those it has already recorded. If a new price point is discovered that is more extreme than a previous one (for example, a higher peak or a lower valley) within the allowed parameters, the script intelligently "re-writes" the data. It effectively removes the older, less significant mark and replaces it with the new, more prominent one. This creates a clean, connected line that tracks the most important pivots in the market history.
3. Final Structural Refining To ensure the visual output is clear and logically sound, the script performs a final pass over the data. It checks for alternating peaks and valleys—ensuring that a "high" is always followed by a "low" and vice versa. This prevents the indicator from overlapping or creating confusing clusters of lines, resulting in a smooth, zigzagging path that highlights the core trajectory of the asset's price movement.
Summary of Visual Output
The final result is a red line on your chart that connects major market highs and lows. By stripping away the minor fluctuations, it allows traders to see the "skeleton" of the market trend, making it easier to identify major support levels, resistance zones, and significant trend reversals at a glance.
//+------------------------------------------------------------------+
//| 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);
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.0)||(curhigh==0.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;
};//z
//---
if((curlow<lastlow)||(lastlow<0))
{
lastlow=curlow;
lastlowpos=shift;
};//z
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;
//if(res>0.0) ExtMapBuffer[shift]=res;
}
}
}
Comments