mql5/Indicators/DexterrFX - SMC Bible/Fractal.mq5
younglubah-gmail e7c311acc0 new files added
2026-03-04 16:34:49 +02:00

172 lines
4.9 KiB
MQL5

//+------------------------------------------------------------------+
//| Fractal.mq5 |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property copyright "2025"
#property version "1.40"
#property indicator_chart_window
#property indicator_plots 2
#property indicator_buffers 2
//--- Swing High
#property indicator_label1 "SwingHigh"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrCrimson
#property indicator_width1 1
//--- Swing Low
#property indicator_label2 "SwingLow"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrMediumSeaGreen
#property indicator_width2 1
input int InpLeftRightBars = 3; // swing detection size
input int InpLeftRightBars0 = 1; // between-point minimum swing size
input ushort code = 170; // Arrow symbol
double SwingHighBuffer[];
double SwingLowBuffer[];
int lastHighIndex = -1;
int lastLowIndex = -1;
datetime last_bar_time = 0;
//------------------------------------------------------------
inline bool IsSwingHigh_L(const double &high[], int i, int L)
{
for(int j = 1; j <= L; j++)
if(high[i] <= high[i - j] || high[i] <= high[i + j]) return false;
return true;
}
//------------------------------------------------------------
inline bool IsSwingLow_L(const double &low[], int i, int L)
{
for(int j = 1; j <= L; j++)
if(low[i] >= low[i - j] || low[i] >= low[i + j]) return false;
return true;
}
//------------------------------------------------------------
int OnInit()
{
SetIndexBuffer(0, SwingHighBuffer, INDICATOR_DATA);
SetIndexBuffer(1, SwingLowBuffer, INDICATOR_DATA);
ArrayInitialize(SwingHighBuffer, 0.0);
ArrayInitialize(SwingLowBuffer, 0.0);
PlotIndexSetInteger(0, PLOT_ARROW, code);
PlotIndexSetInteger(1, PLOT_ARROW, code);
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[])
{
if(rates_total < InpLeftRightBars*2 + 1)
return 0;
if(rates_total > 0 && time[rates_total - 1] == last_bar_time)
return rates_total;
ArrayInitialize(SwingHighBuffer, 0.0);
ArrayInitialize(SwingLowBuffer, 0.0);
lastHighIndex = -1;
lastLowIndex = -1;
int start = InpLeftRightBars;
int end = rates_total - 1 - InpLeftRightBars;
for(int i = start; i <= end; i++)
{
bool isHigh = IsSwingHigh_L(high, i, InpLeftRightBars);
bool isLow = IsSwingLow_L(low, i, InpLeftRightBars);
// --- Swing High ---
if(isHigh)
{
SwingHighBuffer[i] = high[i];
if(lastHighIndex != -1 && lastHighIndex > lastLowIndex)
{
int a = lastHighIndex;
int b = i;
if(a > b) { int tmp = a; a = b; b = tmp; }
double minVal = DBL_MAX;
int minIndex = -1;
for(int k = a + 1; k < b; k++)
{
// only consider swing lows with L = InpLeftRightBars0
if(IsSwingLow_L(low, k, InpLeftRightBars0))
{
if(low[k] < minVal)
{
minVal = low[k];
minIndex = k;
}
}
}
if(minIndex != -1)
SwingLowBuffer[minIndex] = minVal; // draw in SwingLowBuffer
}
lastHighIndex = i;
}
// --- Swing Low ---
if(isLow)
{
SwingLowBuffer[i] = low[i];
if(lastLowIndex != -1 && lastLowIndex > lastHighIndex)
{
int a = lastLowIndex;
int b = i;
if(a > b) { int tmp = a; a = b; b = tmp; }
double maxVal = -DBL_MAX;
int maxIndex = -1;
for(int k = a + 1; k < b; k++)
{
// only consider swing highs with L = InpLeftRightBars0
if(IsSwingHigh_L(high, k, InpLeftRightBars0))
{
if(high[k] > maxVal)
{
maxVal = high[k];
maxIndex = k;
}
}
}
if(maxIndex != -1)
SwingHighBuffer[maxIndex] = maxVal; // draw in SwingHighBuffer
}
lastLowIndex = i;
}
}
last_bar_time = time[rates_total - 1];
return rates_total;
}