ZigZag_v3
Download scriptThis script functions as a specialized technical analysis tool designed to identify and map the significant structural "peaks" and "valleys" in a financial market's price movement. Often referred to by its structural behavior as a ZigZag indicator, its primary goal is to filter out minor market noise and highlight the major trends.
Core Functionality
The script scans historical price data to identify prominent high and low points. Instead of showing every single price fluctuation, it simplifies the market path into a series of connected points. This allows traders to see the overarching "skeleton" of the market's movement more clearly.
How the Logic Works
The tool operates through a multi-stage filtering process:
- Point Identification: The script looks back over a user-defined number of candles (Depth) to find the highest high and the lowest low within that period.
- Sensitivity Filtering: It uses specific settings (Deviation and Backstep) to determine how much price movement is required to trigger a new point. If a price change is too small, the script ignores it, ensuring that only significant reversals are displayed on your chart.
- Trend Validation: As the price moves, the script constantly compares new highs and lows against the previous ones. If a new "higher high" or "lower low" is detected that exceeds the established thresholds, it updates the visual map.
- Point Correction: One of the most important features of this logic is its ability to "redraw." If the market creates a new peak that is higher than the previous one before reaching a final settlement, the script will intelligently remove the old, lower peak and replace it with the current, higher one. This ensures the visual trend always represents the true extreme of the price movement.
User Experience
For the end-user, this means the chart remains clean and easy to read. Rather than being overwhelmed by constant price flickering, you are presented with a clear path of major structural shifts. This is particularly useful for identifying support and resistance levels, as well as determining the current direction of the prevailing trend.
//+------------------------------------------------------------------+
//| 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)&&(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