ZZSA
Download scriptThis script is a specialized technical analysis tool designed to identify and visualize significant structural trends in price movements by connecting major "peaks" and "valleys" on a trading chart. It simplifies the complex movement of market prices into a clear, jagged line that highlights the overall direction of the trend while filtering out minor market noise.
How the Logic Works
The tool processes market data through three primary logical phases to ensure the resulting lines are accurate and meaningful:
1. Identifying Significant Extremes The script scans historical price data looking for the highest highs and lowest lows within a specific range (defined by the "Depth" setting). Instead of marking every small price fluctuation, it uses a sensitivity filter to ensure that only movements of a certain size—those exceeding a specific deviation—are recognized as significant enough to form part of the main trend line.
2. Refining the Data Points (Smoothing) Once potential highs and lows are identified, the script performs a "look-back" check. It compares current price points with those immediately preceding them. If it finds that a newer point is more extreme than a nearby previous one, it replaces the older point. This ensures that the line accurately connects the most prominent market turns rather than getting distracted by smaller ripples in the price action.
3. Trend Enforcement and Final Trimming To create a clean "zigzag" effect, the script applies a final logic pass to ensure the trend follows a logical flow:
- Alternation: The tool ensures that high points and low points alternate correctly. It prevents the line from creating multiple consecutive highs or lows in a row without a significant change in direction.
- Superiority Check: If a new peak is found that is higher than the previous peak (or a new valley lower than the previous valley), the script intelligently "cuts" the old, less significant point and connects to the new one. This results in a sharp, clear path representing the strongest price action.
Visual Output and Alerts
The final result is a continuous red line on your chart that marks the backbone of the market's movement. Additionally, the script includes an automated alert system: when the tool identifies a significant new structural turn at the most recent price candle, it triggers an audible notification to alert the user to the potential shift in momentum.
//+------------------------------------------------------------------+
//| 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 Alers=1;
extern int nBars=150;
//---- 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,k;
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;k=0;}
else
{
res=ExtMapBuffer2[shift];
if(res!=0.0) {ExtMapBuffer[shift]=res;if (Alers==1 && res!=0 && shift==0) PlaySound("Oops.wav");}
}
}
}
Comments