This script provides a specialized version of the ZigZag indicator designed to simplify chart analysis by highlighting only significant price movements. Unlike standard indicators that might clutter a screen with minor fluctuations, this tool focuses on identifying major "zig" and "zag" trends, helping traders visualize historical market structure, such as Elliott Waves or large trend shifts.
How the Logic Works
The script functions by filtering out small price changes and only drawing lines when a significant reversal occurs. It uses three primary rules to determine which points on the chart become "peaks" or "valleys":
- Price Deviation: The indicator requires the price to move by a specific percentage (the Deviation) before it will acknowledge a new point. If the price moves less than this amount, the script ignores it as insignificant noise.
- Depth: This setting defines the minimum distance (in number of bars) required between two peaks or valleys. It ensures that the indicator doesn't create too many points in a short period, forcing the ZigZag to stay focused on major movements.
- Backstep: This is a secondary filter that defines the minimum number of bars between highs and lows, preventing the indicator from "re-calculating" or shifting a point too frequently.
Technical Performance and Behavior
A unique feature of this specific script is its optimization for computer performance. Instead of scanning the entire price history every time the market moves, it is designed to recalculate only a small fraction of recent bars. This prevents the computer from becoming bogged down, making it smoother to use in real-time.
The indicator also features an intelligent "self-correcting" mechanism:
- Dynamic Adjustment: Because market prices are fluid, the most recent segment of the ZigZag can still change as new data comes in. The script is capable of shifting or updating its most recent points to ensure the current trend is accurately represented.
- Dual Peak Handling: It is designed to handle instances where a high and a low might occur on the same bar, ensuring the visual representation remains accurate and consistent with the ZigZag style.
Practical Application
Because this script identifies only the most significant turning points, it is best utilized for:
- Historical Analysis: Reviewing past price action to identify structural patterns.
- Trend Identification: Quickly seeing the direction of the market without being distracted by minor volatility.
- Pattern Recognition: Identifying major waves or trend reversals that are larger than standard market noise.
Note that because this indicator can "re-draw" or adjust its most recent point based on live price action, it is intended for analyzing trends and structures rather than as a primary signal for immediate entry or exit points in fast-moving trades.
/*
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
//Version: Final, October 1, 2006 |
Editing: Nikolay Kositsin farria@mail.redcom.ru |
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
Ýòîò âàðèàíò èíäèêàòîðà ZigZag, â îòëè÷èå îò îðèãèíàëà, íà êàæäîì òèêå
ïåðåñ÷èòûâàåòñÿ òîëüêî íà åù¸ íåïîäñ÷èòàííûõ áàðàõ è ïîýòîìó ñîâñåì
íå ãðóçèò êîìïüþòåð. Ïîìèìî ýòîãî â äàííîì èíäèêàòîðå îòðèñîâêà ëèíèè
ïðîèñõîäèò èìåííî â ñòèëå ZIGZAG, è ïîýòîìó èíäèêàòîð êîððåêòíî
èçîáðàæàåò îäíîâðåìåííî äâå ñâîèõ âåðùèíû(Õàé è Ëîó) íà îäíîì è òîì æå
áàðå!
Íèêîëàé Êîñèöèí
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
Depth - ýòî ìèíèìàëüíîå êîë-âî áàðîâ, íà êîòîðîì íå áóäåò âòîðîãî
ìàêñèìóìà (ìèíèìóìà) ìåíüøå (áîëüøå) íà Deviation ïèïñîâ, ÷åì
ïðåäûäóùåãî, òî åñòü ðàñõîäèòüñÿ ZigZag ìîæåò âñåãäà, à ñõîäèòñÿ
(ëèáî ñäâèíóòüñÿ öåëèêîì) áîëüøå, ÷åì íà Deviation, ZigZag ìîæåò
òîëüêî ïîñëå Depth áàðîâ. Backstep - ýòî ìèíèìàëüíîå êîëè÷åñòâî áàðîâ
ìåæäó ìàêñèìóìàìè (ìèíèìóìàìè).
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
Èíäèêàòîð Çèãçàã ðÿä ëèíèé òðåíäà, êîòîðûå ñîåäèíÿþò ñóùåñòâåííûå
âåðøèíû è îñíîâàíèÿ íà öåíîâîì ãðàôèêå. Ïàðàìåòð ìèíèìàëüíîãî
èçìåíåíèÿ öåí îïðåäåëÿåò ïðîöåíò, íà êîòîðûé öåíà äîëæíà ïåðåìåñòèòü,
÷òîáû ñôîðìèðîâàòü íîâóþ "Çèã" èëè "Çàã" ëèíèþ. Ýòîò èíäèêàòîð
îòñåèâàåò èçìåíåíèÿ íà àíàëèçèðóåìîì ãðàôèêå, âåëè÷èíà êîòîðûõ ìåíüøå
çàäàííîé. Òàêèì îáðàçîì, çèãçàã îòðàæàåò òîëüêî ñóùåñòâåííûå
èçìåíåíèÿ. Çèãçàã èñïîëüçóåòñÿ, ãëàâíûì îáðàçîì, äëÿ îáëåã÷åííîãî
âîñïðèÿòèÿ ãðàôèêîâ, òàê êàê îí ïîêàçûâàåò òîëüêî íàèáîëåå çíà÷èìûå
èçìåíåíèÿ è ðàçâîðîòû. Òàêæå ñ åãî ïîìîùüþ ìîæíî âûÿâëÿòü Âîëíû
Ýëëèîòà è ðàçëè÷íûå ôèãóðû íà ãðàôèêå. Âàæíî óñâîèòü, ÷òî ïîñëåäíèé
îòðåçîê èíäèêàòîðà ìîæåò ìåíÿòüñÿ â çàâèñèìîñòè îò èçìåíåíèé
àíàëèçèðóåìûõ äàííûõ. Ýòî îäèí èç íåìíîãèõ èíäèêàòîðîâ, ó êîòîðîãî
èçìåíåíèå öåíû áóìàãè ìîæåò âûçâàòü èçìåíåíèå ïðåäûäóùåãî çíà÷åíèÿ.
Ïîäîáíàÿ ñïîñîáíîñòü êîððåêòèðîâêè ñâîèõ çíà÷åíèé ïî ïîñëåäóþùèì
èçìåíåíèÿì öåíû äåëàåò Çèãçàã ïðåêðàñíûì èíñòðóìåíòîì äëÿ àíàëèçà óæå
ïðîèçîøåäøèõ öåíîâûõ èçìåíåíèé. Ïîýòîìó íå ñëåäóåò ïûòàòüñÿ ñîçäàòü
òîðãîâóþ ñèñòåìó íà îñíîâå Çèãçàãà: îí ëó÷øå ïîäõîäèò äëÿ àíàëèçà
èñòîðè÷åñêèõ äàííûõ, ÷åì äëÿ ïðîãíîçèðîâàíèÿ.
Copyright © 2005, MetaQuotes Software Corp.
*/
//+------------------------------------------------------------------+
//| ZigZag_NK.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_chart_window
//---- êîëè÷åñòâî èíäèêàòîðíûõ áóôôåðîâ
#property indicator_buffers 2
//---- öâåò èíäèêàòîðà
#property indicator_color1 Aqua
#property indicator_color2 Aqua
//---- òîëùèíà èíäèêàòîðíîé ëèíèè
#property indicator_width1 0
#property indicator_width2 0
//---- ñòèëü èíäèêàòîðíîé ëèíèè
#property indicator_style1 1
#property indicator_style2 1
//---- ÂÕÎÄÍÛÅ ÏÀÐÀÌÅÒÐÛ ÈÍÄÈÊÀÒÎÐÀ
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//----
//---- èíäèêàòîðíûå áóôôåðû
double LowestBuffer[],HighestBuffer[];
//----+ Ââåäåíèå öåëûõ ïåðåìåííûõ ïàìÿòè äëÿ ïåðåñ÷¸òà èíäèêàòîðà òîëüêî íà íåïîäñ÷èòàííûõ áàðàõ
int MaxBar,time2,LASTLOWPOS,LASTHIGHPOS,LHTIME,LLTIME,size;
//----+ Ââåäåíèå ïåðåìåííûõ ïàìÿòè ñ ïëàâàþùåé òî÷êîé äëÿ ïåðåñ÷¸òà èíäèêàòîðà òîëüêî íà íåïîäñ÷èòàííûõ áàðàõ
double LowestMEMORY[1],HighestMEMORY[1],LASTLOW0,LASTLOW1,LASTHIGH0,LASTHIGH1,LASTHIGHEST,LASTLOWEST;
//+------------------------------------------------------------------+
//| ZigZag initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- äâà èíäèêàòîðíûõ áóôôåðà èñïîëüçîâàí äëÿ ñ÷¸òà
SetIndexBuffer(0,LowestBuffer);
SetIndexBuffer(1,HighestBuffer);
//---- Ñòèëü èñïîëíåíèÿ ãðàôèêà âèäå ëîìàííîé ZigZag
SetIndexStyle(0,DRAW_ZIGZAG);
SetIndexStyle(1,DRAW_ZIGZAG);
//---- óñòàíîâêà çíà÷åíèé èíäèêàòîðà, êîòîðûå íå áóäóò âèäèìû íà ãðàôèêå
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
//---- èìåíà äëÿ îêîí äàííûõ è ëýéáû äëÿ ñóáúîêîí
SetIndexLabel(0,"Low" );
SetIndexLabel(1,"High");
IndicatorShortName("ZigZag (ExtDepth="+ExtDepth+", ExtDeviation="+ExtDeviation+", ExtBackstep="+ExtBackstep+" )");
//---- îïðåäåëåíèå ðàçìåðîâ âðåìåííûõ áóôôåðîâ
size=ExtBackstep+1;
//---- èçìåíåíèå ðàçìåðîâ âðåìåííûõ áóôôåðîâ
if(ArrayResize(LowestMEMORY,size)!=size)return(-1);
if(ArrayResize(HighestMEMORY,size)!=size)return(-1);
//---- çàâåðøåíèå èíèöèàëèçàöèè
return(0);
}
//+------------------------------------------------------------------+
//| ZigZag iteration function |
//+------------------------------------------------------------------+
int start()
{
//----+ ïðîâåðêà êîëè÷åñòâà áàðîâ íà äîñòàòî÷íîñòü äëÿ êîððåêòíîãî ðàñ÷¸òà èíäèêàòîðà
if (Bars-1<ExtDepth)return(0);
//----+ Ââåäåíèå öåëûõ ïåðåìåííûõ è ïîëó÷åíèå óæå ïîäñ÷èòàííûõ áàðîâ
int limit,iii,counted_bars=IndicatorCounted();
//---- ïðîâåðêà íà âîçìîæíûå îøèáêè
if (counted_bars<0)return(-1);
//---- ïîñëåäíèé ïîäñ÷èòàííûé áàð äîëæåí áûòü ïåðåñ÷èòàí
if (counted_bars>0) counted_bars--;
//----+ Ââåäåíèå ïåðåìåííûõ
int bar,back,lasthighpos,lastlowpos;
double curlow,curhigh,lasthigh0,lastlow0,lasthigh1,lastlow1,val,res;
//---- îïðåäåëåíèå íîìåðà ñàìîãî ñòàðîãî áàðà, íà÷èíàÿ ñ êîòîðîãî áóäåò ïðîèçåä¸í ïîëûé ïåðåñ÷¸ò âñåõ áàðîâ
MaxBar=Bars-ExtDepth;
//---- îïðåäåëåíèå íîìåðà ñòàðòîâîãî áàðà â öèêëå, íà÷èíàÿ ñ êîòîðîãî áóäåò ïðîèçîäèòüñÿ ïåðåñ÷¸ò íîâûõ áàðîâ
limit=Bars-counted_bars-1;
//+--- âîññòàíîâëåíèå çíà÷åíèé ïåðåìåííûõ +======+
int Tnew=Time[limit+1];
if (limit<MaxBar)
{
if (Tnew==time2)
{
lastlow0=LASTLOW0;
lasthigh0=LASTHIGH0;
//+---
lastlow1=LASTLOW1;
lasthigh1=LASTHIGH1;
//+---
lastlowpos=iBarShift(NULL,0,LLTIME,true);
lasthighpos=iBarShift(NULL,0,LHTIME,true);
//+--- ïðîâåðêà ïåðåìåííûõ lasthighpos è lastlowpos íà êîððåêòíîñòü äëÿ äàëüíåéøåãî ðàñ÷¸òà
if ((lasthighpos<0)||(lastlowpos<0))
{
Print("Îøèáêà âîññòàíîâëåíèÿ ïåðåìåííûõ!!! Ïîòåðÿíû çíà÷åíèÿ ïåðåìåííûõ lasthighpos è lastlowpos");
Print("Áóäåò ïðîèçâåä¸í ïåðåñ÷¸ò èíäèêàòîðà íà âñåõ áàðàõ!");
return(-1);
}
//+---
LowestBuffer[lastlowpos]=LASTLOWEST;
HighestBuffer[lasthighpos]=LASTHIGHEST;
//+---
for(iii=size-1; iii>=0; iii--)
{
LowestBuffer[iii+limit+1]=LowestMEMORY[iii];
HighestBuffer[iii+limit+1]=HighestMEMORY[iii];
}
//+---
}
else
{
if (Tnew>time2)
Print("Îøèáêà âîññòàíîâëåíèÿ ïåðåìåííûõ!!! Tnew>time2");
else Print("Îøèáêà âîññòàíîâëåíèÿ ïåðåìåííûõ!!! Tnew<time2");
Print("Áóäåò ïðîèçâåä¸í ïåðåñ÷¸ò èíäèêàòîðà íà âñåõ áàðàõ!");
return(-1);
}
}
//+--- +==========================================+
//---- èíèöèàëèçàöèÿ íóëÿ
if (limit>=MaxBar)
{
for (bar=Bars-1; bar>=MaxBar;bar--)
{
LowestBuffer [bar]=0.0;
HighestBuffer[bar]=0.0;
}
lastlow1=-1;
lasthigh1=-1;
lastlowpos=-1;
lasthighpos=-1;
limit=MaxBar;
}
//----+ ---------- <<< íà÷àëî ïåðâîãî áîëüøîãî öèêëà >>> -----------+
for(bar=limit; bar>=0; bar--)
{
//+--- Ñîõðàíåíèå çíà÷åíèé ïåðåìåííûõ +=========+
if (bar==1)
{
if(((limit==1)&&(time2==Time[2]))||(limit>1))
{
LASTLOW0=lastlow0;
LASTHIGH0=lasthigh0;
//+---
for(iii=size-1; iii>=0; iii--)
{
LowestMEMORY[iii]=LowestBuffer[iii+2];
HighestMEMORY[iii]=HighestBuffer[iii+2];
}
}
}
//+---+=========================================+
//--- low
val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,bar)];
if(val==lastlow0) val=0.0;
else
{
lastlow0=val;
if((Low[bar]-val)>(ExtDeviation*Point))val=0.0;
else
{
for(back=1; back<=ExtBackstep; back++)
{
res=LowestBuffer[bar+back];
if((res!=0)&&(res>val))LowestBuffer[bar+back]=0.0;
}
}
}
LowestBuffer[bar]=val;
//--- high
val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,bar)];
if(val==lasthigh0) val=0.0;
else
{
lasthigh0=val;
if((val-High[bar])>(ExtDeviation*Point))val=0.0;
else
{
for(back=1; back<=ExtBackstep; back++)
{
res=HighestBuffer[bar+back];
if((res!=0)&&(res<val))HighestBuffer[bar+back]=0.0;
}
}
}
HighestBuffer[bar]=val;
}
//----+ êîíåö ïåðâîãî áîëüøîãî öèêëà
//----+ ---------- <<< íà÷àëî âòîðîãî áîëüøîãî öèêëà >>> -----------+
for(bar=limit; bar>=0; bar--)
{
//+--- Ñîõðàíåíèå çíà÷åíèé ïåðåìåííûõ +====+
if (bar==1)
{
if(((limit==1)&&(time2==Time[2]))||(limit>1))
{
time2=Time [2];
LASTLOW1=lastlow1;
LASTHIGH1=lasthigh1;
//+---
LLTIME=Time[lastlowpos];
LHTIME=Time[lasthighpos];
//+---
LASTLOWEST=LowestBuffer[lastlowpos];
LASTHIGHEST=HighestBuffer[lasthighpos];
}
}
//+---+====================================+
curlow=LowestBuffer[bar];
curhigh=HighestBuffer[bar];
//---
if((curlow==0)&&(curhigh==0))continue;
//---
if(curhigh!=0)
{
if(lasthigh1>0)
{
if(lasthigh1<curhigh)HighestBuffer[lasthighpos]=0;
else HighestBuffer[bar]=0;
}
//---
if(lasthigh1<curhigh || lasthigh1<0)
{
lasthigh1=curhigh;
lasthighpos=bar;
}
lastlow1=-1;
}
//----
if(curlow!=0)
{
if(lastlow1>0)
{
if(lastlow1>curlow) LowestBuffer[lastlowpos]=0;
else LowestBuffer[bar]=0;
}
//---
if((curlow<lastlow1)||(lastlow1<0))
{
lastlow1=curlow;
lastlowpos=bar;
}
lasthigh1=-1;
}
}
//----+ êîíåö âòîðîãî áîëüøîãî öèêëà
//+-----------------------------------------------------------------+
//---- çàâåðøåíèå âû÷èñëåíèé çíà÷åíèé èíäèêàòîðà
return(0);
}
//+---------------------------------------------------------------------------+
Comments