// + ------------------------------------------------------------------ + //| ZigZag hist.mq4 | // + ------------------------------------------------------------------ + #property strict #property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 clrGoldenrod #property indicator_color2 clrDodgerBlue #property indicator_color3 clrRed #property indicator_width1 1 #property indicator_width2 2 #property indicator_width3 3 //---- 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[]; double BuyBuffer[]; double SellBuffer[]; //--- 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(5); //---- drawing settings SetIndexStyle(0, DRAW_SECTION); SetIndexStyle(1, DRAW_LINE, STYLE_DOT, 1); SetIndexStyle(2, DRAW_LINE, STYLE_DOT, 1); //---- indicator buffers SetIndexBuffer(0, ExtZigzagBuffer); SetIndexBuffer(1, BuyBuffer); SetIndexBuffer(2, SellBuffer); SetIndexBuffer(3, ExtHighBuffer); SetIndexBuffer(4, 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; BuyBuffer[i] = lasthigh; } if(ExtLowBuffer[i]!=0.0) { lastlow = Low[i]; lastlowpos = i; whatlookfor = 1; ExtZigzagBuffer[i] = lastlow; SellBuffer[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; SellBuffer[i] = lastlow; } else if(ExtHighBuffer[i] != 0.0 && ExtLowBuffer[i] == 0.0) { lasthigh = ExtHighBuffer[i]; lasthighpos = i; ExtZigzagBuffer[i] = lasthigh; whatlookfor = -1; BuyBuffer[i] = lasthigh; } else SellBuffer[i] = lastlow; 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; BuyBuffer[i] = lasthigh; } else if(ExtLowBuffer[i] != 0.0 && ExtHighBuffer[i] == 0.0) { lastlow = ExtLowBuffer[i]; lastlowpos = i; ExtZigzagBuffer[i] = lastlow; whatlookfor = 1; SellBuffer[i] = lastlow; } else BuyBuffer[i] = lasthigh;//--- 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); } //+------------------------------------------------------------------+