ZigZag_Separate
Download scriptThis 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.
//+------------------------------------------------------------------+
//| 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