ZigZag_new_nen4
Download scriptThis script is designed to generate a ZigZag indicator, a popular technical analysis tool used to identify significant price swings and trends by filtering out minor market "noise." Instead of showing every tiny fluctuation, it connects major highs and lows to provide a clearer picture of the market's structure.
Here is a breakdown of the logic used in this specific script:
1. Identification of Key Price Points
The script begins by scanning the price history to find significant peaks (highs) and troughs (lows). It uses three primary settings to determine what qualifies as a "major" move:
- Depth: This defines how many bars the script looks back to find the highest high or lowest low.
- Deviation: This ensures that a new point is only created if the price moves by a specific minimum amount. If the price movement is too small, the script ignores it.
- Backstep: This acts as a secondary filter to ensure that points are not placed too close to one another chronologically.
2. Multi-Step Filtering Process
The logic doesn't just mark every high and low it sees; it undergoes a rigorous three-pass cleaning process to ensure the resulting "ZigZag" line is accurate:
- First Pass (Potential Points): The script identifies potential high and low points based on the Depth and Deviation settings. At this stage, many points might still exist that are technically valid but don't form a clean trend.
- Second Pass (Trend Logic): The script compares these potential points against each other. If it finds two consecutive highs where one is higher than the other, it removes the lower one to ensure the line only connects the most significant peaks. It does the same for lows, ensuring only the deepest troughs remain.
- Third Pass (Final Alignment): The script merges these findings into a final set of coordinates, creating the continuous connected line that appears on your chart.
3. Trend Cleaning and Optimization
To make the visual representation even cleaner, the script performs an additional "Trend Correction" check. It looks at the last few identified points to ensure they are not redundant or logically inconsistent (for example, it ensures that the sequence of highs and lows follows a logical "up-down-up" flow). If it detects overlapping or contradictory movements in the most recent data, it removes those intermediate points to keep the line smooth.
4. Optional Visual Labels
The script includes an optional feature for "Labels." If enabled, it can identify whether a specific point on the ZigZag is a High or a Low and place specific visual markers (arrows) accordingly. This helps traders quickly distinguish between the start of an upward trend and the start of a downward correction.
Summary for the User
In plain terms, this script acts as a "filter." It looks at the messy, constant movement of the market and extracts only the most significant turning points. By applying layers of logic to verify these points, it prevents the indicator from creating "fake" turns, providing you with a cleaner visual map of the market's history and current trajectory.
//+------------------------------------------------------------------+
//| ZigZag_new_nen4.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link "http://onix-trade.net/forum/index.php?s=&showtopic=4786&view=findpost&p=272959"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 LightSkyBlue
#property indicator_color3 LemonChiffon
#property indicator_width1 2
#property indicator_style1 0
//----
extern int ExtDepth=21;
extern int ExtDeviation=13;
extern int ExtBackstep=34;
extern int ExtLabel=2;
//----
//----
double ZigZagBuffer[], ha[], la[];
int timeFirstBar=0;
//+------------------------------------------------------------------+
//| ZigZag initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
SetIndexBuffer(0,ZigZagBuffer);
SetIndexBuffer(1,ha);
SetIndexBuffer(2,la);
SetIndexStyle(0,DRAW_SECTION);
SetIndexStyle(1,DRAW_ARROW);
SetIndexStyle(2,DRAW_ARROW);
SetIndexArrow(1,116);
SetIndexArrow(2,116);
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
SetIndexEmptyValue(2,0.0);
IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
if (ExtLabel<0) ExtLabel=0;
if (ExtLabel>1) ExtLabel=1;
//----
return(0);
}
//+------------------------------------------------------------------+
//| ZigZag iteration function |
//+------------------------------------------------------------------+
int start()
{
//----+ ïðîâåðêà êîëè÷åñòâà áàðîâ íà äîñòàòî÷íîñòü äëÿ êîððåêòíîãî ðàñ÷¸òà èíäèêàòîðà
if (Bars-1<ExtDepth)return(0);
//----+ Ââåäåíèå öåëûõ ïåðåìåííûõ ïàìÿòè äëÿ ïåðåñ÷¸òà èíäèêàòîðà òîëüêî íà íåïîäñ÷èòàííûõ áàðàõ
static int time2,time3,time4;
//----+ Ââåäåíèå ïåðåìåííûõ ñ ïëàâàþùåé òî÷êîé äëÿ ïåðåñ÷¸òà èíäèêàòîðà òîëüêî íà íåïîäñ÷èòàííûõ áàðàõ
static double ZigZag2,ZigZag3,ZigZag4;
//----+ Ââåäåíèå öåëûõ ïåðåìåííûõ äëÿ ïåðåñ÷¸òà èíäèêàòîðà òîëüêî íà íåïîäñ÷èòàííûõ áàðàõ è ïîëó÷åíèå óæå ïîäñ÷èòàííûõ áàðîâ
int MaxBar,limit,supr2_bar,supr3_bar,supr4_bar,counted_bars=IndicatorCounted();
//---- ïðîâåðêà íà âîçìîæíûå îøèáêè
if (counted_bars<0)return(-1);
//---- ïîñëåäíèé ïîäñ÷èòàííûé áàð äîëæåí áûòü ïåðåñ÷èòàí
if (counted_bars>0) counted_bars--;
//----+ Ââåäåíèå ïåðåìåííûõ
int index, shift, back,lasthighpos,lastlowpos;
double val,res,TempBuffer[1];
double curlow,curhigh,lasthigh,lastlow;
int metka=0; // =0 - äî ïåðâîãî ïåðåëîìà ZZ. =1 - èùåì ìåòêè ìàêñèìóìîâ. =2 - èùåì ìåòêè ìèíèìóìîâ.
//---- îïðåäåëåíèå íîìåðà ñàìîãî ñòàðîãî áàðà, íà÷èíàÿ ñ êîòîðîãî áóäåò ïðîèçåä¸í ïîëûé ïåðåñ÷¸ò âñåõ áàðîâ
MaxBar=Bars-ExtDepth;
//---- îïðåäåëåíèå íîìåðà ñòàðòîâîãî áàðà â öèêëå, íà÷èíàÿ ñ êîòîðîãî áóäåò ïðîèçåäèòüñÿ ïåðåñ÷¸ò íîâûõ áàðîâ
if (counted_bars==0 || Bars-counted_bars>2)
{
limit=MaxBar;
}
else
{
//----
supr2_bar=iBarShift(NULL,0,time2,TRUE);
supr3_bar=iBarShift(NULL,0,time3,TRUE);
supr4_bar=iBarShift(NULL,0,time4,TRUE);
//----
limit=supr3_bar;
if ((supr2_bar<0)||(supr3_bar<0)||(supr4_bar<0))
{
limit=MaxBar;
}
}
//---- èíèöèàëèçàöèÿ íóëÿ
if (limit>=MaxBar || timeFirstBar!=Time[Bars-1])
{
timeFirstBar=Time[Bars-1];
limit=MaxBar;
}
//----
//---- èçìåíåíèå ðàçìåðà âðåìåííîãî áóôåðà
if (limit==MaxBar) ArrayResize(TempBuffer,Bars); else ArrayResize(TempBuffer,limit+ExtBackstep+1);
//----+-------------------------------------------------+
//----+ íà÷àëî ïåðâîãî áîëüøîãî öèêëà
for(shift=limit; shift>=0; shift--)
{
//--- Low
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=ZigZagBuffer[shift+back];
if((res!=0)&&(res>val)) ZigZagBuffer[shift+back]=0.0;
}
}
}
if (Low[shift]==val)
{
ZigZagBuffer[shift]=val;
if (ExtLabel==1) la[shift]=val;
}
else ZigZagBuffer[shift]=0.0;
//--- 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=TempBuffer[shift+back];
if((res!=0)&&(res<val)) TempBuffer[shift+back]=0.0;
}
}
}
if (High[shift]==val)
{
TempBuffer[shift]=val;
if (ExtLabel==1) ha[shift]=val;
}
else TempBuffer[shift]=0.0;
}
//----+ êîíåö ïåðâîãî áîëüøîãî öèêëà
// final cutting
lasthigh=-1; lasthighpos=-1;
lastlow= -1; lastlowpos= -1;
//----+-------------------------------------------------+
//----+ íà÷àëî âòîðîãî áîëüøîãî öèêëà
for(shift=limit; shift>=0; shift--)
{
curlow=ZigZagBuffer[shift];
curhigh=TempBuffer[shift];
if((curlow==0)&&(curhigh==0)) continue;
//---
if(curhigh!=0)
{
if(lasthigh>0)
{
if(lasthigh<curhigh) TempBuffer[lasthighpos]=0;
else TempBuffer[shift]=0;
}
//---
if(lasthigh<curhigh || lasthigh<0)
{
lasthigh=curhigh;
lasthighpos=shift;
}
lastlow=-1;
}
//----
if(curlow!=0)
{
if(lastlow>0)
{
if(lastlow>curlow) ZigZagBuffer[lastlowpos]=0;
else ZigZagBuffer[shift]=0;
}
//---
if((curlow<lastlow)||(lastlow<0))
{
lastlow=curlow;
lastlowpos=shift;
}
lasthigh=-1;
}
}
//----+ êîíåö âòîðîãî áîëüøîãî öèêëà
//----+-------------------------------------------------+
//----+ íà÷àëî òðåòüåãî öèêëà
for(shift=limit; shift>=0; shift--)
{
res=TempBuffer[shift];
if(res!=0.0) ZigZagBuffer[shift]=res;
}
//----+ êîíåö òðåòüåãî öèêëà
// Ïðîâåðêà ïåðâîãî ëó÷à
int i=0,j=0;
res=0;
for (shift=0;i<3;shift++)
{
if (ZigZagBuffer[shift]>0)
{
i++;
if (i==1 && ZigZagBuffer[shift]==High[shift])
{
j=shift;
res=ZigZagBuffer[shift];
}
if (i==2 && res>0 && ZigZagBuffer[shift]==High[shift])
{
if (ZigZagBuffer[shift]>=ZigZagBuffer[j]) ZigZagBuffer[j]=0; else ZigZagBuffer[shift]=0;
res=0;
i=0;
j=0;
shift=0;
}
}
}
//+--- Âîññòàíîâëåíèå çíà÷åíèé èíäèêàòîðíîãî áóôôåðà, êîòîðûå ìîãëè áûòü óòåðÿíû
if (limit<MaxBar)
{
ZigZagBuffer[supr2_bar]=ZigZag2;
ZigZagBuffer[supr3_bar]=ZigZag3;
ZigZagBuffer[supr4_bar]=ZigZag4;
for(int qqq=supr4_bar-1; qqq>supr3_bar; qqq--)ZigZagBuffer[qqq]=0;
for(int ggg=supr3_bar-1; ggg>supr2_bar; ggg--)ZigZagBuffer[ggg]=0;
}
//+---+============================================+
//+--- èñïðàâëåíèå âîçíèêàþùèõ ãîðáîâ
double vel1, vel2, vel3, vel4;
int bar1, bar2, bar3, bar4;
int count;
if (limit==MaxBar)supr4_bar=MaxBar;
for(int bar=supr4_bar; bar>=0; bar--)
{
if (ZigZagBuffer[bar]!=0)
{
count++;
vel4=vel3;bar4=bar3;
vel3=vel2;bar3=bar2;
vel2=vel1;bar2=bar1;
vel1=ZigZagBuffer[bar];bar1=bar;
if (count<3)continue;
if ((vel3<vel2)&&(vel2<vel1)){ZigZagBuffer[bar2]=0;bar=bar3+1;}
if ((vel3>vel2)&&(vel2>vel1)){ZigZagBuffer[bar2]=0;bar=bar3+1;}
if ((vel2==vel1)&&(vel1!=0 )){ZigZagBuffer[bar1]=0;bar=bar3+1;}
}
}
//+--- çàïîìèíàíèå âðåìåíè òð¸õ ïîñëåäíèõ ïåðåãèáîâ Çèãçàãà è çíà÷åíèé èíäèêàòîðà â ýòèõ òî÷êàõ
time2=Time[bar2];
time3=Time[bar3];
time4=Time[bar4];
ZigZag2=vel2;
ZigZag3=vel3;
ZigZag4=vel4;
//+---
//---- çàâåðøåíèå âû÷èñëåíèé çíà÷åíèé èíäèêàòîðà
if (ExtLabel==1)
{
for(shift=Bars-1; shift>=0; shift--)
{
if (ZigZagBuffer[shift]>0)
{
if (ha[shift]>0)
{
// metka=2; shift--;
metka=2; la[shift]=0; shift--;
}
else
{
// metka=1; shift--;
metka=1; ha[shift]=0; shift--;
}
}
if (metka==0)
{
ha[shift]=0; la[shift]=0;
}
else if (metka==1)
{
if (ha[shift]>0) metka=0;
la[shift]=0;
}
else if (metka==2)
{
if (la[shift]>0) metka=0;
ha[shift]=0;
}
}
}
return(0);
}
//---+ +---------------------------------------------------------------------+
Comments