MQL5Book/Indicators/p5/IndFractals.mq5

110 lines
3.6 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:41 +02:00
//+------------------------------------------------------------------+
//| IndFractals.mq5 |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
// plot settings
#property indicator_type1 DRAW_ARROW
#property indicator_type2 DRAW_ARROW
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_label1 "Fractal Up"
#property indicator_label2 "Fractal Down"
input int FractalOrder = 3;
// indicator buffers
double UpBuffer[];
double DownBuffer[];
// 10 pixels padding from extremums
const int ArrowShift = 10;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// indicator buffers mapping
SetIndexBuffer(0, UpBuffer, INDICATOR_DATA);
SetIndexBuffer(1, DownBuffer, INDICATOR_DATA);
// set bullets
PlotIndexSetInteger(0, PLOT_ARROW, 217);
PlotIndexSetInteger(1, PLOT_ARROW, 218);
// arrow padding while drawing
PlotIndexSetInteger(0, PLOT_ARROW_SHIFT, -ArrowShift);
PlotIndexSetInteger(1, PLOT_ARROW_SHIFT, +ArrowShift);
// empty value for drawings (can be omitted, as EMPTY_VALUE is default)
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
return FractalOrder > 0 ? INIT_SUCCEEDED : INIT_PARAMETERS_INCORRECT;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
if(prev_calculated == 0)
{
// initialize entire buffers on start
ArrayInitialize(UpBuffer, EMPTY_VALUE);
ArrayInitialize(DownBuffer, EMPTY_VALUE);
}
else
{
// initialize new bars
for(int i = prev_calculated; i < rates_total; ++i)
{
UpBuffer[i] = EMPTY_VALUE;
DownBuffer[i] = EMPTY_VALUE;
}
}
// look throught all or new bars having FractalOrder bars in neighbourhood
for(int i = fmax(prev_calculated - FractalOrder - 1, FractalOrder); i < rates_total - FractalOrder; ++i)
{
// check if this high is highest on neighbouring bars
UpBuffer[i] = high[i];
for(int j = 1; j <= FractalOrder; ++j)
{
if(high[i] <= high[i + j] || high[i] <= high[i - j])
{
UpBuffer[i] = EMPTY_VALUE;
break;
}
}
// check if this low is lowest on neighbouring bars
DownBuffer[i] = low[i];
for(int j = 1; j <= FractalOrder; ++j)
{
if(low[i] >= low[i + j] || low[i] >= low[i - j])
{
DownBuffer[i] = EMPTY_VALUE;
break;
}
}
}
return rates_total;
}
//+------------------------------------------------------------------+