This script is a specialized visual tool designed for financial charting. Its primary purpose is to identify and highlight significant price "swing points"—specifically the major peaks (highs) and valleys (lows) of a market trend—while filtering out minor market noise.
Core Logic Overview
The script operates by scanning historical price data to find significant turning points based on three user-defined parameters: Depth (how far back the script looks), Deviation (the minimum price change required to consider a move "significant"), and Backstep (the sensitivity of the movement).
Rather than plotting every single price fluctuation, the logic follows a multi-stage refinement process:
1. Identification of Extremes The tool first scans the price history to find the highest highs and lowest lows within a specific look-back window. It only acknowledges a point as a "potential" turn if it exceeds the user's set deviation. This ensures that small, insignificant price wobbles do not trigger a signal.
2. Trend Refinement and Filtering Once potential peaks and valleys are identified, the script performs a "pruning" process. It compares consecutive points to ensure that the markers actually represent meaningful structural shifts. If a new high or low is detected that overrides a previous one (for example, if price continues to move higher before settling), the script removes the old, lower point and replaces it with the more significant extreme. This results in a clean "zigzag" pattern where each peak is higher than its predecessor in an uptrend, and each valley is lower in a downtrend.
3. Automated Trend Detection and Alerts The most advanced part of this script is its ability to analyze the direction of these zigzag points automatically:
- Trend Recognition: It compares the position of the current major swing point against the previous one.
- Directional Analysis: If the sequence of high/low points suggests the market structure is shifting from making lower highs to making higher highs (or vice versa), the script recognizes this as a trend change.
- Visual and Audio Feedback: When a new trend is identified, the script triggers a text alert on your screen (e.g., "Up trend Started" or "Down trend Started").
- Dynamic Fibonacci Integration: Simultaneously with these alerts, the script automatically deletes the old trend markers and draws a new Fibonacci Retracement tool based on the most recent two significant swing points.
Summary for the User
In simple terms, this script acts as an automated analyst. It clears away the "messy" price action of the market to show you the underlying structural skeleton. By identifying the most important peaks and valleys, it tells you when a trend has fundamentally shifted and automatically draws the tools necessary to measure that new trend's potential targets.
//+------------------------------------------------------------------+
//| 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,0,4);
SetIndexArrow(0, 233);
SetIndexStyle(1,DRAW_ARROW,0,4);
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) Alert("ZigZag Channels Down trend Started ");
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) Alert("ZigZag Channels Up trend Started ");
OldLastZigZag=LastZigZag;
OldPreviousZigZag=PreviousZigZag;
ObjectDelete("Fibo");
ObjectCreate("Fibo", OBJ_FIBO, 0, Time[PreviousZigZag], ExtMapBuffer[LastZigZag], Time[LastZigZag], ExtMapBuffer[PreviousZigZag]);
}
}
}
//end//
Comments