This script is designed to identify and visualize significant price structural turning points—specifically the "peaks" and "valleys"—on a financial trading chart. By filtering out minor market noise, it helps traders focus on the primary movements of the price action.
Core Logic and Functionality
1. Identifying Significant Extremes The script scans historical price data to find high and low points based on three user-defined sensitivity settings:
- Depth: Determines how far back the script looks to find a peak or valley.
- Deviation: Acts as a "noise filter," ensuring that only significant price moves are captured rather than tiny fluctuations.
- Backstep: Ensures that the peaks and valleys are spaced out logically, preventing multiple points from being clustered too closely together.
2. Dynamic Point Selection (The ZigZag Effect) As new price data arrives, the script constantly re-evaluates the most recent high and low points. If a newer, more extreme peak or valley is formed, the script "prunes" the previous point. For example, if the price reaches a new higher high before completing a trend, the old point is removed to ensure the line accurately represents the most extreme move taken during that period.
3. Trend Direction Detection The logic includes a specialized observation layer that monitors the sequence of these turning points. It tracks the positions of the "current" and "previous" identified peaks and valleys. By comparing their relative positions on the chart, the script can detect when the structural flow of the market is shifting.
4. Automated Alerts One of the primary features for a trader is the automated notification system. When the script detects a specific pattern—namely a significant shift in the direction of the trend based on the new positioning of these peaks and valleys—it triggers an alert. This allows you to be notified of "Possible changes in direction" in real-time without having to manually scan every candle for structural breaks.
Summary for the User
Essentially, this tool acts as a structural map for the market. It ignores the "jitter" of daily price movement and highlights only the major landmarks. By identifying these landmarks, it provides a clear visual of the current trend and proactively alerts you when the market begins to structure itself in an opposing direction.
//+------------------------------------------------------------------+
//| 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[];
int OldLastZigZag, OldPreviousZigZag;
//+------------------------------------------------------------------+
//| 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;
}
int i=0;
int LastZigZag, PreviousZigZag;
int h=0;
while ( ExtMapBuffer[h]==0 && ExtMapBuffer2[h]==0) {
h++;
}
LastZigZag=h;
h++;
while(ExtMapBuffer[h]==0 && ExtMapBuffer2[h]==0) {
h++;
}
PreviousZigZag=h;
if (OldLastZigZag!=LastZigZag || OldPreviousZigZag!=PreviousZigZag) {
if ((OldLastZigZag>LastZigZag)&& (OldPreviousZigZag>PreviousZigZag)) Alert("Possible change in direction... (M",Period()," ",Symbol(),")");
OldLastZigZag=LastZigZag;
OldPreviousZigZag=PreviousZigZag;
//ObjectDelete("Fibo");
//ObjectCreate("Fibo", OBJ_FIBO, 0, Time[PreviousZigZag], ExtMapBuffer[LastZigZag], Time[LastZigZag], ExtMapBuffer[PreviousZigZag]);
}
if (OldLastZigZag!=LastZigZag || OldPreviousZigZag!=PreviousZigZag) {
if((OldLastZigZag<LastZigZag)&& (OldPreviousZigZag<PreviousZigZag)) Alert("Possible change in direction... (M",Period()," ",Symbol(),")");
OldLastZigZag=LastZigZag;
OldPreviousZigZag=PreviousZigZag;
//ObjectDelete("Fibo");
//ObjectCreate("Fibo", OBJ_FIBO, 0, Time[PreviousZigZag], ExtMapBuffer[LastZigZag], Time[LastZigZag], ExtMapBuffer[PreviousZigZag]);
}
}
}
//end//
Comments