//+------------------------------------------------------------------+ //| ZigzagColor.mq5 | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2000-2025, MetaQuotes Ltd." #property link "https://www.mql5.com" //--- indicator settings #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_ZIGZAG #property indicator_color1 clrDodgerBlue,clrRed //--- input parameters input int InpDepth =12; // Depth input int InpDeviation=5; // Deviation input int InpBackstep =3; // Back Step //--- indicator buffers double ZigzagPeakBuffer[]; double ZigzagBottomBuffer[]; double HighMapBuffer[]; double LowMapBuffer[]; double ColorBuffer[]; int ExtRecalc=3; // recounting's depth 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,ZigzagPeakBuffer,INDICATOR_DATA); SetIndexBuffer(1,ZigzagBottomBuffer,INDICATOR_DATA); SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX); SetIndexBuffer(3,HighMapBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(4,LowMapBuffer,INDICATOR_CALCULATIONS); //--- set accuracy IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //--- name for DataWindow and indicator subwindow label string short_name=StringFormat("ZigZagColor(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep); IndicatorSetString(INDICATOR_SHORTNAME,short_name); PlotIndexSetString(0,PLOT_LABEL,short_name); //--- 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[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(rates_total<100) return(0); //--- int i,start=0; int extreme_counter=0,extreme_search=Extremum; int shift,back=0,last_high_pos=0,last_low_pos=0; double val=0,res=0; double cur_low=0,cur_high=0,last_high=0,last_low=0; //--- initializing if(prev_calculated==0) { ArrayInitialize(ZigzagPeakBuffer,0.0); ArrayInitialize(ZigzagBottomBuffer,0.0); ArrayInitialize(HighMapBuffer,0.0); ArrayInitialize(LowMapBuffer,0.0); //--- start calculation from bar number InpDepth start=InpDepth-1; } //--- 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_counterrates_total -100) { res=(ZigzagPeakBuffer[i]+ZigzagBottomBuffer[i]); //--- if(res!=0) extreme_counter++; i--; } i++; start=i; //--- what type of exremum we search for if(LowMapBuffer[i]!=0) { cur_low=LowMapBuffer[i]; extreme_search=Peak; } else { cur_high=HighMapBuffer[i]; extreme_search=Bottom; } //--- clear indicator values for(i=start+1; i(InpDeviation*_Point)) val=0.0; else { for(back=InpBackstep; back>=1; 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=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=InpBackstep; back>=1; back--) { res=HighMapBuffer[shift-back]; //--- if((res!=0) && (reslast_high && LowMapBuffer[shift]==0.0) { ZigzagPeakBuffer[last_high_pos]=0.0; last_high_pos=shift; last_high=HighMapBuffer[shift]; ZigzagPeakBuffer[shift]=last_high; ColorBuffer[shift]=0; } if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0) { last_low=LowMapBuffer[shift]; last_low_pos=shift; ZigzagBottomBuffer[shift]=last_low; ColorBuffer[shift]=1; extreme_search=Peak; } break; default: return(rates_total); } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Get highest value for range | //+------------------------------------------------------------------+ double Highest(const double&array[],int count,int start) { double res=array[start]; //--- for(int i=start-1; i>start-count && i>=0; i--) if(resstart-count && i>=0; i--) if(res>array[i]) res=array[i]; //--- return(res); } //+------------------------------------------------------------------+