// + ------------------------------------------------------------------ +
//| 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);
}
//+------------------------------------------------------------------+
Comments