01_zigzagvalue
Download scriptThis script is a specialized technical analysis tool designed to simplify the way you view market trends by identifying significant price movements and "swing points." Instead of showing every minor price fluctuation, it filters out the noise to highlight the primary peaks and valleys in a currency pair or asset's history.
Core Functionality
The primary purpose of this tool is to create a clear visual path of the market's direction. It works by scanning historical price data to find "highs" and "lows" that meet specific criteria, effectively drawing a connected line (a ZigZag) that moves from one significant peak to the next valley, or vice versa.
How the Logic Works
The script follows a systematic three-step process to determine what to display on your chart:
1. Data Filtering and Sensitivity The script doesn't just mark every price change. It uses three main parameters—Depth, Deviation, and Backstep—to decide what qualifies as a "significant" move.
- It looks backward at a certain number of bars to find the highest and lowest points.
- It ensures that a new point is only recognized if the price has moved enough to exceed a specific "deviation" threshold. This prevents the chart from becoming cluttered with tiny, insignificant price ripples.
2. Peak and Valley Identification Once the script identifies potential high and low points, it enters a logic loop to decide which ones are "true" turning points:
- If the market is currently in an upward trend (looking for a peak), the script constantly monitors for a new high. If it finds one that is higher than the previous record, it updates the current "peak."
- Conversely, if it is in a downward trend (looking for a valley), it searches for the lowest price point.
- By comparing these points against each other, the script "cuts" out the intermediate data, ensuring that the final line on your chart represents the most prominent structural shifts in the market.
3. Visual Mapping and Labeling After the logic determines where the significant turns are, the script handles the visual presentation:
- ZigZag Line: It draws a continuous line connecting these key points, making it easy to see the current trend at a glance.
- Dynamic Labeling: The script can automatically place text labels on the chart. These labels show the specific price values of the peaks and valleys.
- Swing Calculation: Depending on your settings, the tool can also calculate and display the "swing" (the difference in price) between two consecutive points, helping you quickly measure the magnitude of a market move.
Summary for the User
In short, this script acts as a market filter. It strips away the constant "jitter" of live trading to reveal the underlying structure of the price action. By identifying only the most meaningful peaks and valleys based on your chosen sensitivity, it allows you to see the "big picture" of market trends more clearly.
//+------------------------------------------------------------------+
//| https://www.facebook.com/traderknj |
//| Copyright 2016, KNJ company |
//| TraderKNJ@yahoo.com |
//+------------------------------------------------------------------+
#property copyright "TraderKNJ@yahoo.com"
#property link "https://www.facebook.com/traderknj"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Lavender
//---- indicator parameters input window
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
extern color PivotsColor=Magenta;
extern bool ZigZagLineShow=True;
extern bool PivotsValueShow=True;
extern bool SwingValueShow=False;
//---- indicator buffers
double ZigzagBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
int level=3; // recounting's depth
bool downloadhistory=false;
double Pip=Point;
bool Started=False;
string mad;
int i,counted_bars=IndicatorCounted();
int limit,counterZ,whatlookfor;
int shift,back,lasthighpos,lastlowpos;
double val,res;
double curlow,curhigh,lasthigh,lastlow;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(3);
//---- drawing settings
if(ZigZagLineShow)
{SetIndexStyle(0,DRAW_SECTION);}
//---- indicator buffers mapping
SetIndexBuffer(0,ZigzagBuffer);
SetIndexBuffer(1,HighMapBuffer);
SetIndexBuffer(2,LowMapBuffer);
SetIndexEmptyValue(0,0.0);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int deinit()
{
DelObj();
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DelObj()
{
string ObjName;
for(i=ObjectsTotal()-1; i>=0; i--)
{
ObjName=ObjectName(i);
if(StringFind(ObjName,"ZZLabel",0)>=0)
ObjectDelete(ObjName);
}
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
if(counted_bars==0 && downloadhistory) // history was downloaded
{
ArrayInitialize(ZigzagBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
}
if(counted_bars==0)
{
limit=Bars-ExtDepth;
downloadhistory=true;
}
if(counted_bars>0)
{
while(counterZ<level && i<100)
{
res=ZigzagBuffer[i];
if(res!=0) counterZ++;
i++;
}
i--;
limit=i;
if(LowMapBuffer[i]!=0)
{
curlow=LowMapBuffer[i];
whatlookfor=1;
}
else
{
curhigh=HighMapBuffer[i];
whatlookfor=-1;
}
for(i=limit-1;i>=0;i--)
{
ZigzagBuffer[i]=0.0;
LowMapBuffer[i]=0.0;
HighMapBuffer[i]=0.0;
}
}
for(shift=limit; shift>=0; shift--)
{
val=Low[iLowest(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=LowMapBuffer[shift+back];
if((res!=0) && (res>val)) LowMapBuffer[shift+back]=0.0;
}
}
}
if(Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
//--- high
val=High[iHighest(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=HighMapBuffer[shift+back];
if((res!=0) && (res<val)) HighMapBuffer[shift+back]=0.0;
}
}
}
if(High[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
}
// final cutting
if(whatlookfor==0)
{
lastlow=0;
lasthigh=0;
}
else
{
lastlow=curlow;
lasthigh=curhigh;
}
for(shift=limit;shift>=0;shift--)
{
res=0.0;
bool OutOfForLoop=False;
switch(whatlookfor)
{
case 0: // look for peak or lawn
if(lastlow==0 && lasthigh==0)
{
if(HighMapBuffer[shift]!=0)
{
lasthigh=High[shift];
lasthighpos=shift;
whatlookfor=-1;
ZigzagBuffer[shift]=lasthigh;
res=1;
}
if(LowMapBuffer[shift]!=0)
{
lastlow=Low[shift];
lastlowpos=shift;
whatlookfor=1;
ZigzagBuffer[shift]=lastlow;
res=1;
}
}
break;
case 1: // look for peak
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
{
ZigzagBuffer[lastlowpos]=0.0;
lastlowpos=shift;
lastlow=LowMapBuffer[shift];
ZigzagBuffer[shift]=lastlow;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
lasthigh=HighMapBuffer[shift];
lasthighpos=shift;
ZigzagBuffer[shift]=lasthigh;
whatlookfor=-1;
res=1;
}
break;
case -1: // look for lawn
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
{
ZigzagBuffer[lasthighpos]=0.0;
lasthighpos=shift;
lasthigh=HighMapBuffer[shift];
ZigzagBuffer[shift]=lasthigh;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
lastlow=LowMapBuffer[shift];
lastlowpos=shift;
ZigzagBuffer[shift]=lastlow;
whatlookfor=1;
}
break;
default: OutOfForLoop=True;
}
if(OutOfForLoop) break;
}
//////////////////
if(PivotsValueShow)
{
if(counted_bars<1)
{
DelObj();
limit=Bars-1;
}
else limit=0;
for(i=limit; i>=0; i--)
{
int k=i;
double zz;
double d1=0,d2=0,d3=0;
datetime t1=0,t2=0,t3=0;
while(k<Bars-2)
{
zz=ZigzagBuffer[k];
if(zz!=0)
{
d1 = d2; d2 = d3; d3 = zz;
t1 = t2; t2 = t3; t3 = Time[k];
}
if(d1>0) break;
k++;
}
if(d1==0) continue;
double LabelPos;
int ib=iBarShift(NULL,0,t1);
if(d1>d2) LabelPos=NormalizeDouble(High[ib]+0.5*iATR(NULL,0,10,ib),Digits);
else LabelPos=Low[ib];
string ObjName="ZZLabel_Leg1";
//------
if (SwingValueShow)
mad=DoubleToStr(d1,Digits)+"("+DoubleToStr((d1-d2),Digits)+")";
else
mad=DoubleToStr(d1,Digits);
//------
if(ObjectFind(ObjName)<0)
ObjectCreate(ObjName,OBJ_TEXT,0,t1,LabelPos);
else
ObjectMove(ObjName,0,t1,LabelPos);
ObjectSetText(ObjName,mad,8,"Arial",PivotsColor);
//////////////////////
ib=iBarShift(NULL,0,t2);
if(d2>d3) LabelPos=NormalizeDouble(High[ib]+0.5*iATR(NULL,0,10,ib),Digits);
else LabelPos=Low[ib];
ObjName="ZZLabel"+DoubleToStr(t1,Digits);
if (SwingValueShow)
mad=DoubleToStr(d2,Digits)+"("+DoubleToStr((d2-d3), Digits)+")";
else
mad=DoubleToStr(d2,Digits);
if(ObjectFind(ObjName)<0)
{
ObjectCreate(ObjName,OBJ_TEXT,0,t2,LabelPos);
ObjectSetText(ObjName,mad,8,"Arial",PivotsColor);
}
}
}
return(0);
}
//+------------------------------------------------------------------+
Comments