How can I enhance the ZigZag-Indicator in MetaTrader Terminal 5 to include bars and points for visualizing ranges?
How can I enhance the ZigZag-Indicator in MetaTrader Terminal 5 to include bars and points for visualizing ranges?
Loading saved threads...
Hirwa Léandre · External communityPost link
External question — Stack Overflow Stack Exchange
Author: Hirwa Léandre
Original post: https://stackoverflow.com/questions/76305003
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
Title :
Enhancing ZigZag-Indicator in MetaTrader Terminal 5: Visualizing Range with Bars and Points
Question :
I'm looking to enhance the functionality of the ZigZag indicator in MetaTrader Terminal 5 by visualizing the range between the highest and lowest points using bars and points. Currently, the indicator only plots lines connecting the significant swing highs and lows. However, I believe that incorporating bars and points would offer a more comprehensive view of the indicator's behavior and potentially identify additional trading opportunities.
I have successfully combined the addition of
BarCountBuffer[]
and
PointCountBuffer[]
to the existing code. These buffers are used to store the number of bars and points since the last extreme point in the ZigZag-indicator.
//+------------------------------------------------------------------+
//| Leandre Hirwa.mq5 |
//| |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 3
//--- plot ZigZag
#property indicator_label1 "ZigZag"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- plot High points
#property indicator_label2 "High Points"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrGreen
#property indicator_style2 STYLE_ARROWUP
//--- plot Low points
#property indicator_label3 "Low Points"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrRed
#property indicator_style3 STYLE_ARROWDOWN
//--- input parameters
input int InpDepth = 12; // Depth
input int InpDeviation= 5; // Deviation
input int InpBackstep = 3; // Back Step
//--- indicator buffers
double ZigZagBuffer[]; // main buffer
double HighMapBuffer[]; // ZigZag high extremes (peaks)
double LowMapBuffer[]; // ZigZag low extremes (bottoms)
double BarCountBuffer[]; // number of bars since last extreme point
double PointCountBuffer[]; // number of points since last extreme point
int ExtRecalc=3; // number of last extremes for recalculation
enum EnSearchMode
{
Extremum=0, // searching for the first extremum
Peak=1, // searching for the next ZigZag peak
Bottom=-1 // searching for the next ZigZag bottom
};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA);
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,BarCountBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,PointCountBuffer,INDICATOR_CALCULATIONS);
//--- set short name and digits
string short_name=StringFormat("ZigZag(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0,PLOT_LABEL,short_name);
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}
//+------------------------------------------------------------------+
//| ZigZag calculation |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
{
if(rates_total<100)
return(0);
//---
int i=0;
int start=0,extreme_counter=0,extreme_search=Extremum;
int shift=0,back=0,last_high_pos=0,last_low_pos=0;
double val=0,res=0;
double curlow=0,curhigh=0,last_high=0,last_low=0;
//--- initializing
if(prev_calculated==0)
{
ArrayInitialize(ZigZagBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
ArrayInitialize(BarCountBuffer,0.0);
ArrayInitialize(PointCountBuffer,0.0);
start=InpDepth;
}
//--- ZigZag was already calculated before
if(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted bar
while(extreme_counter<ExtRecalc && i>rates_total-100)
{
res=ZigZagBuffer[i];
if(res!=0.0)
extreme_counter++;
i--;
}
i++;
start=i;
//--- what type of extremum we search for
if(LowMapBuffer[i]!=0.0)
{
curlow=LowMapBuffer[i];
extreme_search=Peak;
}
else
{
curhigh=HighMapBuffer[i];
extreme_search=Bottom;
}
//--- clear indicator values
for(i=start+1; i<rates_total && !IsStopped(); i++)
{
ZigZagBuffer[i] =0.0;
LowMapBuffer[i] =0.0;
HighMapBuffer[i]=0.0;
BarCountBuffer[i] = 0.0;
PointCountBuffer[i] = 0.0;
}
}
//--- searching for high and low extremes
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
//--- low
val=low[Lowest(low,InpDepth,shift)];
if(val==last_low)
val=0.0;
else
{
last_low=val;
if((low[shift]-val)>InpDeviation*_Point)
val=0.0;
else
{
for(back=1; back<=InpBackstep; 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[Highest(high,InpDepth,shift)];
if(val==last_high)
val=0.0;
else
{
last_high=val;
if((val-high[shift])>InpDeviation*_Point)
val=0.0;
else
{
for(back=1; back<=InpBackstep; 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;
}
//--- set last values
if(extreme_search==0) // undefined values
{
last_low=0.0;
last_high=0.0;
}
else
{
last_low=curlow;
last_high=curhigh;
}
//--- final selection of extreme points for ZigZag
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case Extremum:
if(last_low==0.0 && last_high==0.0)
{
if(HighMapBuffer[shift]!=0)
{
last_high=high[shift];
last_high_pos=shift;
extreme_search=Bottom;
ZigZagBuffer[shift]=last_high;
res=1;
}
if(LowMapBuffer[shift]!=0.0)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=Peak;
ZigZagBuffer[shift]=last_low;
res=1;
}
}
break;
case Peak:
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low && HighMapBuffer[shift]==0.0)
{
ZigZagBuffer[last_low_pos]=0.0;
last_low_pos=shift;
last_low=LowMapBuffer[shift];
ZigZagBuffer[shift]=last_low;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
last_high=HighMapBuffer[shift];
last_high_pos=shift;
ZigZagBuffer[shift]=last_high;
extreme_search=Bottom;
res=1;
}
break;
case Bottom:
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>last_high && LowMapBuffer[shift]==0.0)
{
ZigZagBuffer[last_high_pos]=0.0;
last_high_pos=shift;
last_high=HighMapBuffer[shift];
ZigZagBuffer[shift]=last_high;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
last_low=LowMapBuffer[shift];
last_low_pos=shift;
ZigZagBuffer[shift]=last_low;
extreme_search=Peak;
}
break;
default:
return(rates_total);
}
//--- calculate bar and point counts
if (res == 1)
{
if (extreme_search == Peak)
BarCountBuffer[shift] = BarCountBuffer[shift - 1] + 1;
else if (extreme_search == Bottom)
BarCountBuffer[shift] = BarCountBuffer[shift - 1];
if (BarCountBuffer[shift] > 0)
PointCountBuffer[shift] = PointCountBuffer[shift - 1] + MathAbs(ZigZagBuffer[shift] - ZigZagBuffer[shift - 1]);
}
else
{
BarCountBuffer[shift] = BarCountBuffer[shift - 1];
PointCountBuffer[shift] = PointCountBuffer[shift - 1];
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
Anybody can access my codes from the following Google doc
link
Quote
Report
Post Reply
Quoted from Forex.com.bd-Editorial External question — Stack Overflow Stack Exchange Author: Hirwa Léandre Source score (net votes, not local likes): 1 Original post: https://stackoverflow.com/questions/76305003 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. Title : Enhancing ZigZag-Indicator in MetaTrader Terminal 5: Visualizing Range with Bars and Points Question : I'm looking to enhance the functionality of the ZigZag indicator in MetaTrader Terminal 5 by visualizing the range between the highest and lowest points using bars and points. Currently, the indicator only plots lines connecting the significant swing highs and lows. However, I believe that incorporating bars and points would offer a more comprehensive view of the indicator's behavior and potentially identify additional trading opportunities. I have successfully combined the addition of BarCountBuffer[] and PointCountBuffer[] to the existing code. These buffers are used to store the number of bars and points since the last extreme point in the ZigZag-indicator. //+------------------------------------------------------------------+ //| Leandre Hirwa.mq5 | //| | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property link "https://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 3 //--- plot ZigZag #property indicator_label1 "ZigZag" #property indicator_type1 DRAW_SECTION #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot High points #property indicator_label2 "High Points" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrGreen #property indicator_style2 STYLE_ARROWUP //--- plot Low points #property indicator_label3 "Low Points" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrRed #property indicator_style3 STYLE_ARROWDOWN //--- input parameters input int InpDepth = 12; // Depth input int InpDeviation= 5; // Deviation input int InpBackstep = 3; // Back Step //--- indicator buffers double ZigZagBuffer[]; // main buffer double HighMapBuffer[]; // ZigZag high extremes (peaks) double LowMapBuffer[]; // ZigZag low extremes (bottoms) double BarCountBuffer[]; // number of bars since last extreme point double PointCountBuffer[]; // number of points since last extreme point int ExtRecalc=3; // number of last extremes for recalculation enum EnSearchMode { Extremum=0, // searching for the first extremum Peak=1, // searching for the next ZigZag peak Bottom=-1 // searching for the next ZigZag bottom }; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA); SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(3,BarCountBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(4,PointCountBuffer,INDICATOR_CALCULATIONS); //--- set short name and digits string short_name=StringFormat("ZigZag(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep); IndicatorSetString(INDICATOR_SHORTNAME,short_name); PlotIndexSetString(0,PLOT_LABEL,short_name); IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //--- set an empty value PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); } //+------------------------------------------------------------------+ //| ZigZag calculation | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], { if(rates_total<100) return(0); //--- int i=0; int start=0,extreme_counter=0,extreme_search=Extremum; int shift=0,back=0,last_high_pos=0,last_low_pos=0; double val=0,res=0; double curlow=0,curhigh=0,last_high=0,last_low=0; //--- initializing if(prev_calculated==0) { ArrayInitialize(ZigZagBuffer,0.0); ArrayInitialize(HighMapBuffer,0.0); ArrayInitialize(LowMapBuffer,0.0); ArrayInitialize(BarCountBuffer,0.0); ArrayInitialize(PointCountBuffer,0.0); start=InpDepth; } //--- ZigZag was already calculated before if(prev_calculated>0) { i=rates_total-1; //--- searching for the third extremum from the last uncompleted bar while(extreme_counter<ExtRecalc && i>rates_total-100) { res=ZigZagBuffer[i]; if(res!=0.0) extreme_counter++; i--; } i++; start=i; //--- what type of extremum we search for if(LowMapBuffer[i]!=0.0) { curlow=LowMapBuffer[i]; extreme_search=Peak; } else { curhigh=HighMapBuffer[i]; extreme_search=Bottom; } //--- clear indicator values for(i=start+1; i<rates_total && !IsStopped(); i++) { ZigZagBuffer[i] =0.0; LowMapBuffer[i] =0.0; HighMapBuffer[i]=0.0; BarCountBuffer[i] = 0.0; PointCountBuffer[i] = 0.0; } } //--- searching for high and low extremes for(shift=start; shift<rates_total && !IsStopped(); shift++) { //--- low val=low[Lowest(low,InpDepth,shift)]; if(val==last_low) val=0.0; else { last_low=val; if((low[shift]-val)>InpDeviation*_Point) val=0.0; else { for(back=1; back<=InpBackstep; 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[Highest(high,InpDepth,shift)]; if(val==last_high) val=0.0; else { last_high=val; if((val-high[shift])>InpDeviation*_Point) val=0.0; else { for(back=1; back<=InpBackstep; 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; } //--- set last values if(extreme_search==0) // undefined values { last_low=0.0; last_high=0.0; } else { last_low=curlow; last_high=curhigh; } //--- final selection of extreme points for ZigZag for(shift=start; shift<rates_total && !IsStopped(); shift++) { res=0.0; switch(extreme_search) { case Extremum: if(last_low==0.0 && last_high==0.0) { if(HighMapBuffer[shift]!=0) { last_high=high[shift]; last_high_pos=shift; extreme_search=Bottom; ZigZagBuffer[shift]=last_high; res=1; } if(LowMapBuffer[shift]!=0.0) { last_low=low[shift]; last_low_pos=shift; extreme_search=Peak; ZigZagBuffer[shift]=last_low; res=1; } } break; case Peak: if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low && HighMapBuffer[shift]==0.0) { ZigZagBuffer[last_low_pos]=0.0; last_low_pos=shift; last_low=LowMapBuffer[shift]; ZigZagBuffer[shift]=last_low; res=1; } if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0) { last_high=HighMapBuffer[shift]; last_high_pos=shift; ZigZagBuffer[shift]=last_high; extreme_search=Bottom; res=1; } break; case Bottom: if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>last_high && LowMapBuffer[shift]==0.0) { ZigZagBuffer[last_high_pos]=0.0; last_high_pos=shift; last_high=HighMapBuffer[shift]; ZigZagBuffer[shift]=last_high; } if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0) { last_low=LowMapBuffer[shift]; last_low_pos=shift; ZigZagBuffer[shift]=last_low; extreme_search=Peak; } break; default: return(rates_total); } //--- calculate bar and point counts if (res == 1) { if (extreme_search == Peak) BarCountBuffer[shift] = BarCountBuffer[shift - 1] + 1; else if (extreme_search == Bottom) BarCountBuffer[shift] = BarCountBuffer[shift - 1]; if (BarCountBuffer[shift] > 0) PointCountBuffer[shift] = PointCountBuffer[shift - 1] + MathAbs(ZigZagBuffer[shift] - ZigZagBuffer[shift - 1]); } else { BarCountBuffer[shift] = BarCountBuffer[shift - 1]; PointCountBuffer[shift] = PointCountBuffer[shift - 1]; } } //--- return value of prev_calculated for next call return(rates_total); } Anybody can access my codes from the following Google doc link
Checking account access…