//+------------------------------------------------------------------+ //| ZigZag.mq4 | //| Copyright 2006-2014, MetaQuotes Software Corp. | //| http://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2006-2014, MetaQuotes Software Corp." #property link "http://www.mql4.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 || InpBackstep>=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<ExtLevel && i<100) { if(ExtZigzagBuffer[i]!=0.0) counterZ++; i++; } //--- no extremum found - recounting all from begin if(counterZ==0) limit=InitializeAll(); else { //--- set start position to found extremum position limit=i-1; //--- what kind of extremum? if(ExtLowBuffer[i]!=0.0) { //--- low extremum curlow=ExtLowBuffer[i]; //--- will look for the next high extremum whatlookfor=1; } else { //--- high extremum curhigh=ExtHighBuffer[i]; //--- will look for the next low extremum whatlookfor=-1; } //--- clear the rest data for(i=limit-1; i>=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]<extremum) ExtHighBuffer[pos]=0.0; } } } //--- found extremum is current high if(high[i]==extremum) ExtHighBuffer[i]=extremum; else ExtHighBuffer[i]=0.0; } //--- final cutting if(whatlookfor==0) { lastlow=0.0; lasthigh=0.0; } else { lastlow=curlow; lasthigh=curhigh; } for(i=limit; i>=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]<lastlow && ExtHighBuffer[i]==0.0) { ExtZigzagBuffer[lastlowpos]=0.0; lastlowpos=i; lastlow=ExtLowBuffer[i]; ExtZigzagBuffer[i]=lastlow; } if(ExtHighBuffer[i]!=0.0 && ExtLowBuffer[i]==0.0) { lasthigh=ExtHighBuffer[i]; lasthighpos=i; ExtZigzagBuffer[i]=lasthigh; whatlookfor=-1; } break; case -1: // look for lawn if(ExtHighBuffer[i]!=0.0 && ExtHighBuffer[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); } //+------------------------------------------------------------------+
MQL4://+------------------------------------------------------------------+ //| ZigZag.mq4 | //| Copyright 2006-2014, MetaQuotes Software Corp. | //| http://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2006-2014, MetaQuotes Software Corp." #property link "http://www.mql4.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 || InpBackstep>=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<ExtLevel && i<100) { if(ExtZigzagBuffer[i]!=0.0) counterZ++; i++; } //--- no extremum found - recounting all from begin if(counterZ==0) limit=InitializeAll(); else { //--- set start position to found extremum position limit=i-1; //--- what kind of extremum? if(ExtLowBuffer[i]!=0.0) { //--- low extremum curlow=ExtLowBuffer[i]; //--- will look for the next high extremum whatlookfor=1; } else { //--- high extremum curhigh=ExtHighBuffer[i]; //--- will look for the next low extremum whatlookfor=-1; } //--- clear the rest data for(i=limit-1; i>=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]<extremum) ExtHighBuffer[pos]=0.0; } } } //--- found extremum is current high if(high[i]==extremum) ExtHighBuffer[i]=extremum; else ExtHighBuffer[i]=0.0; } //--- final cutting if(whatlookfor==0) { lastlow=0.0; lasthigh=0.0; } else { lastlow=curlow; lasthigh=curhigh; } for(i=limit; i>=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]<lastlow && ExtHighBuffer[i]==0.0) { ExtZigzagBuffer[lastlowpos]=0.0; lastlowpos=i; lastlow=ExtLowBuffer[i]; ExtZigzagBuffer[i]=lastlow; } if(ExtHighBuffer[i]!=0.0 && ExtLowBuffer[i]==0.0) { lasthigh=ExtHighBuffer[i]; lasthighpos=i; ExtZigzagBuffer[i]=lasthigh; whatlookfor=-1; } break; case -1: // look for lawn if(ExtHighBuffer[i]!=0.0 && ExtHighBuffer[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); } //+------------------------------------------------------------------+
ExtHighBuffer
and ExtLowBuffer
, finding the second to most recent non-zero value, and checking whether the current price is above it (for highs) or below it (for lows). The check should be placed right above the return(rates_total);
line.Thanks so much for the help.You just probably need to run a cycle throughExtHighBuffer
andExtLowBuffer
, finding the second to most recent non-zero value, and checking whether the current price is above it (for highs) or below it (for lows). The check should be placed right above thereturn(rates_total);
line.
If you want alerts on the bars that might still get repainted, then check the most recent non-zero values.What of those that might still get repainted? recent non-value right?
can you help with the code for second most recent non zero value for the just the high. Came back to this work and still couldnt get a suitable logic to code it. I am still a learnerIf you want alerts on the bars that might still get repainted, then check the most recent non-zero values.
int j; double secondRecent = 0; for (j = 0; i < Bars; j++) { if (ExtHighBuffer[j] != 0) { if (secondRecent == 0) { secondRecent = ExtHighBuffer[j]; } else { secondRecent = ExtHighBuffer[j]; break; } } else if (ExtLowBuffer[j] != 0) { if (secondRecent == 0) { secondRecent = ExtLowBuffer[j]; } else { secondRecent = ExtLowBuffer[j]; break; } } } double ask = MarketInfo(Symbol(), MODE_ASK); double bid = MarketInfo(Symbol(), MODE_BID); if (ask > secondRecent) { Z = "UP"; } else if (bid < secondRecent) { Z = "DOWN"; }
MQL4:int j; double secondRecent = 0; for (j = 0; i < Bars; j++) { if (ExtHighBuffer[j] != 0) { if (secondRecent == 0) { secondRecent = ExtHighBuffer[j]; } else { secondRecent = ExtHighBuffer[j]; break; } } else if (ExtLowBuffer[j] != 0) { if (secondRecent == 0) { secondRecent = ExtLowBuffer[j]; } else { secondRecent = ExtLowBuffer[j]; break; } } } double ask = MarketInfo(Symbol(), MODE_ASK); double bid = MarketInfo(Symbol(), MODE_BID); if (ask > secondRecent) { Z = "UP"; } else if (bid < secondRecent) { Z = "DOWN"; }