//+------------------------------------------------------------------+ //| ZigZag.mq4 | //| Copyright 2006-2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2006-2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property strict #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 Red //---- indicator parameters input int InpDepth=12; // Depth input int InpDeviation=5; // Deviation input int InpBackstep=3; // Backstep //---- indicator buffers double ExtZigzagBuffer[]; double ExtHighBuffer[]; double ExtLowBuffer[]; //--- globals int ExtLevel=3; // recounting's depth of extremums //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { if(InpBackstep>=InpDepth) { Print("Backstep cannot be greater or equal to Depth"); return(INIT_FAILED); } //--- 2 additional buffers IndicatorBuffers(3); //---- drawing settings SetIndexStyle(0,DRAW_SECTION); //---- indicator buffers SetIndexBuffer(0,ExtZigzagBuffer); SetIndexBuffer(1,ExtHighBuffer); SetIndexBuffer(2,ExtLowBuffer); SetIndexEmptyValue(0,0.0); //---- indicator short name IndicatorShortName("ZigZag("+string(InpDepth)+","+string(InpDeviation)+","+string(InpBackstep)+")"); //---- initialization done return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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[]) { int i,limit,counterZ,whatlookfor=0; int back,pos,lasthighpos=0,lastlowpos=0; double extremum; double curlow=0.0,curhigh=0.0,lasthigh=0.0,lastlow=0.0; //--- check for history and inputs if(rates_total=InpDepth) return(0); //--- first calculations if(prev_calculated==0) limit=InitializeAll(); else { //--- find first extremum in the depth ExtLevel or 100 last bars i=counterZ=0; while(counterZ=0; i--) { ExtZigzagBuffer[i]=0.0; ExtLowBuffer[i]=0.0; ExtHighBuffer[i]=0.0; } } } //--- main loop for(i=limit; i>=0; i--) { //--- find lowest low in depth of bars extremum=low[iLowest(NULL,0,MODE_LOW,InpDepth,i)]; //--- this lowest has been found previously if(extremum==lastlow) extremum=0.0; else { //--- new last low lastlow=extremum; //--- discard extremum if current low is too high if(low[i]-extremum>InpDeviation*Point) extremum=0.0; else { //--- clear previous extremums in backstep bars for(back=1; back<=InpBackstep; back++) { pos=i+back; if(ExtLowBuffer[pos]!=0 && ExtLowBuffer[pos]>extremum) ExtLowBuffer[pos]=0.0; } } } //--- found extremum is current low if(low[i]==extremum) ExtLowBuffer[i]=extremum; else ExtLowBuffer[i]=0.0; //--- find highest high in depth of bars extremum=high[iHighest(NULL,0,MODE_HIGH,InpDepth,i)]; //--- this highest has been found previously if(extremum==lasthigh) extremum=0.0; else { //--- new last high lasthigh=extremum; //--- discard extremum if current high is too low if(extremum-high[i]>InpDeviation*Point) extremum=0.0; else { //--- clear previous extremums in backstep bars for(back=1; back<=InpBackstep; back++) { pos=i+back; if(ExtHighBuffer[pos]!=0 && ExtHighBuffer[pos]=0; i--) { switch(whatlookfor) { case 0: // look for peak or lawn if(lastlow==0.0 && lasthigh==0.0) { if(ExtHighBuffer[i]!=0.0) { lasthigh=High[i]; lasthighpos=i; whatlookfor=-1; ExtZigzagBuffer[i]=lasthigh; } if(ExtLowBuffer[i]!=0.0) { lastlow=Low[i]; lastlowpos=i; whatlookfor=1; ExtZigzagBuffer[i]=lastlow; } } break; case 1: // look for peak if(ExtLowBuffer[i]!=0.0 && ExtLowBuffer[i]lasthigh && ExtLowBuffer[i]==0.0) { ExtZigzagBuffer[lasthighpos]=0.0; lasthighpos=i; lasthigh=ExtHighBuffer[i]; ExtZigzagBuffer[i]=lasthigh; } if(ExtLowBuffer[i]!=0.0 && ExtHighBuffer[i]==0.0) { lastlow=ExtLowBuffer[i]; lastlowpos=i; ExtZigzagBuffer[i]=lastlow; whatlookfor=1; } break; } } //--- done return(rates_total); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int InitializeAll() { ArrayInitialize(ExtZigzagBuffer,0.0); ArrayInitialize(ExtHighBuffer,0.0); ArrayInitialize(ExtLowBuffer,0.0); //--- first counting position return(Bars-InpDepth); } //+------------------------------------------------------------------+