Posted By: boatman
Zig Zag function - 02/09/15 10:29
I've been trying to create a zig zag function in Zorro to track the swing highs and swing lows of the price series. I know that this indicator doesn't have any predictive value, but I'd like to test whether entering a trade on a retracement of a recent swing has any merit.
To this end, I've been trying to convert the Metaquotes zig zag indicator across to Lite-C, but the code is unintelligble gibberish to me.
I was wondering if anyone could help me out with this, or at least point me in the right direction.
First, here is the MQL code that I'm trying to convert, followed by my somewhat poor first attempt.
I'd really like to convert the MQL version converted, but don't have a clue where to start. Any clues much appreciated!
My attempt at something similar: I resorted to a completely different approach with my attempt, essentially looking for peaks and valleys using the Fractals indicator (in hindsight, I probably should have just used 'Peak" and 'Valley - would have been simplar!), and then setting those peaks and valleys to be legs of the zig zag if they represent a certain % price move.
To this end, I've been trying to convert the Metaquotes zig zag indicator across to Lite-C, but the code is unintelligble gibberish to me.
I was wondering if anyone could help me out with this, or at least point me in the right direction.
First, here is the MQL code that I'm trying to convert, followed by my somewhat poor first attempt.
I'd really like to convert the MQL version converted, but don't have a clue where to start. Any clues much appreciated!
Code:
//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+
My attempt at something similar: I resorted to a completely different approach with my attempt, essentially looking for peaks and valleys using the Fractals indicator (in hindsight, I probably should have just used 'Peak" and 'Valley - would have been simplar!), and then setting those peaks and valleys to be legs of the zig zag if they represent a certain % price move.
Code:
#define NZ_FractalUP AlgoVar[0] #define NZ_FractalDW AlgoVar[1] function run() { vars Price = series(price()); //=======================Fractals======================== var FractalUP_current = FractalHigh(series(priceHigh()),7); //if no fractal on that bar, returns zero var FractalDW_current = FractalLow(series(priceLow()),7); //if no fractal on that bar, returns zero //Non-zero fractals only if (FractalUP_current != 0) NZ_FractalUP = FractalUP_current; if (FractalDW_current != 0) NZ_FractalDW = FractalDW_current; //To access fractals back history, create a series of the non-zero values: vars FractalUP = series(NZ_FractalUP); vars FractalDW = series(NZ_FractalDW); // plot("FUseries", FractalUP[0], DOT, GREEN); //plot the series of non-zero up fractals // plot("FDseries", FractalDW[0], DOT, RED); //plot the series of non-zero down fractals var x = 1; //% move to trigger new leg of zigzag static var ZigZagUP; static var ZigZagDW; if (FractalUP[0] > (x/100)*ZigZagDW + ZigZagDW) ZigZagUP = FractalUP[0]; if (FractalDW[0] < ZigZagUP - (x/100)*ZigZagUP) ZigZagDW = FractalDW[0]; plot("ZigZagUP", ZigZagUP, MAIN|DOT, ORANGE); plot("ZigZagDW", ZigZagDW, MAIN|DOT, BLUE); }