210 lines
7 KiB
MQL5
210 lines
7 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| Fair Value Gaps.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 "Copyright 2025, ScarraLuba."
| |
#property link "https://concrete-goonies.web.app"
| |
#property version "1.00"
| |
#property indicator_chart_window
| |
#property indicator_buffers 8
| |
#property indicator_plots 2
| |
//--- plot BullFVG
| |
#property indicator_label1 "BullFVG"
| |
#property indicator_type1 DRAW_CANDLES
| |
#property indicator_color1 clrBlack , clrMintCream
| |
#property indicator_style1 STYLE_SOLID
| |
#property indicator_width1 5
| |
//--- plot BearFVG
| |
#property indicator_label2 "BearFVG"
| |
#property indicator_type2 DRAW_CANDLES
| |
#property indicator_color2 clrBlack , clrMistyRose
| |
#property indicator_style2 STYLE_SOLID
| |
#property indicator_width2 5
| |
| |
//--- input parameters
| |
input int InpLeftRightBars = 1;
| |
| |
//--- indicator buffers
| |
double BullFVGBuffer1[];
| |
double BullFVGBuffer2[];
| |
double BullFVGBuffer3[];
| |
double BullFVGBuffer4[];
| |
double BearFVGBuffer1[];
| |
double BearFVGBuffer2[];
| |
double BearFVGBuffer3[];
| |
double BearFVGBuffer4[];
| |
| |
double c_highBuffer[]; // raw external highs
| |
double c_lowBuffer[]; // raw external lows
| |
int swingHandle0;datetime last_bar_time = 0;
| |
//+------------------------------------------------------------------+
| |
//| Custom indicator initialization function |
| |
//+------------------------------------------------------------------+
| |
int OnInit()
| |
{
| |
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
| |
//--- indicator buffers mapping
| |
SetIndexBuffer(0, BullFVGBuffer1, INDICATOR_DATA);
| |
SetIndexBuffer(1, BullFVGBuffer2, INDICATOR_DATA);
| |
SetIndexBuffer(2, BullFVGBuffer3, INDICATOR_DATA);
| |
SetIndexBuffer(3, BullFVGBuffer4, INDICATOR_DATA);
| |
SetIndexBuffer(4, BearFVGBuffer1, INDICATOR_DATA);
| |
SetIndexBuffer(5, BearFVGBuffer2, INDICATOR_DATA);
| |
SetIndexBuffer(6, BearFVGBuffer3, INDICATOR_DATA);
| |
SetIndexBuffer(7, BearFVGBuffer4, INDICATOR_DATA);
| |
ArraySetAsSeries(c_highBuffer, true);
| |
ArraySetAsSeries(c_lowBuffer, true);
| |
ArraySetAsSeries(BullFVGBuffer1, true);
| |
ArraySetAsSeries(BullFVGBuffer2, true);
| |
ArraySetAsSeries(BullFVGBuffer3, true);
| |
ArraySetAsSeries(BullFVGBuffer4, true);
| |
ArraySetAsSeries(BearFVGBuffer1, true);
| |
ArraySetAsSeries(BearFVGBuffer2, true);
| |
ArraySetAsSeries(BearFVGBuffer3, true);
| |
ArraySetAsSeries(BearFVGBuffer4, true);
| |
| |
swingHandle0 = iCustom(_Symbol, _Period, "Arjo Indicators\\Swing", InpLeftRightBars);
| |
| |
if(swingHandle0 == INVALID_HANDLE)
| |
{
| |
Print("Error loading external indicator 'bt': ", GetLastError());
| |
return INIT_FAILED;
| |
}
| |
last_bar_time = 0;
| |
return(INIT_SUCCEEDED);
| |
}
| |
int OnCalculate(const int32_t rates_total,
| |
const int32_t 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 int32_t &spread[])
| |
{ if(rates_total > 0 && time[rates_total - 1] == last_bar_time)
| |
return rates_total;
| |
| |
if(rates_total < 10)
| |
return prev_calculated;
| |
| |
ArraySetAsSeries(high, true);
| |
ArraySetAsSeries(low, true);
| |
ArraySetAsSeries(open, true);
| |
ArraySetAsSeries(close, true);
| |
| |
if(CopyBuffer(swingHandle0, 0, 0, rates_total, c_highBuffer) <= 0 ||
| |
CopyBuffer(swingHandle0, 1, 0, rates_total, c_lowBuffer) <= 0)
| |
{
| |
Print("Failed to copy buffers from external indicator: ", GetLastError());
| |
return prev_calculated;
| |
}
| |
| |
if(prev_calculated == 0)
| |
{
| |
ArrayInitialize(BullFVGBuffer1, 0.0);
| |
ArrayInitialize(BullFVGBuffer2, 0.0);
| |
ArrayInitialize(BullFVGBuffer3, 0.0);
| |
ArrayInitialize(BullFVGBuffer4, 0.0);
| |
ArrayInitialize(BearFVGBuffer1, 0.0);
| |
ArrayInitialize(BearFVGBuffer2, 0.0);
| |
ArrayInitialize(BearFVGBuffer3, 0.0);
| |
ArrayInitialize(BearFVGBuffer4, 0.0);
| |
}
| |
| |
for(int i = 0; i < rates_total; i++)
| |
{
| |
if(c_highBuffer[i] != 0.0)
| |
{
| |
int s1 = i;
| |
int a1 = s1 - 1;
| |
int a3 = s1 - 3;
| |
int b1 = s1;
| |
int b3 = s1 - 2;
| |
int c1 = s1 - 2;
| |
int c3 = s1 - 4;
| |
| |
if(a3 < 0 || b3 < 0 || c3 < 0 || a1 - 1 < 0 || b1 - 1 < 0 || c1 - 1 < 0)
| |
continue;
| |
| |
bool fvgA = (low[a1] > high[a3]);
| |
bool fvgB = (low[b1] > high[b3]);
| |
bool fvgC = (low[c1] > high[c3]);
| |
| |
if(fvgB)
| |
{
| |
BearFVGBuffer1[b1 - 1] = low[b1];
| |
BearFVGBuffer2[b1 - 1] = low[b1];
| |
BearFVGBuffer3[b1 - 1] = high[b3];
| |
BearFVGBuffer4[b1 - 1] = high[b3];
| |
}
| |
else if(fvgA)
| |
{
| |
BearFVGBuffer1[a1 - 1] = low[a1];
| |
BearFVGBuffer2[a1 - 1] = low[a1];
| |
BearFVGBuffer3[a1 - 1] = high[a3];
| |
BearFVGBuffer4[a1 - 1] = high[a3];
| |
}
| |
else if(fvgC)
| |
{
| |
BearFVGBuffer1[c1 - 1] = low[c1];
| |
BearFVGBuffer2[c1 - 1] = low[c1];
| |
BearFVGBuffer3[c1 - 1] = high[c3];
| |
BearFVGBuffer4[c1 - 1] = high[c3];
| |
}
| |
}
| |
}
| |
| |
for(int i = 0; i < rates_total; i++)
| |
{
| |
if(c_lowBuffer[i] != 0.0)
| |
{
| |
int a1 = i;
| |
int a2 = i - 1;
| |
int a3 = i - 2;
| |
int a4 = i + 1;
| |
| |
if(a2 < 0 || a3 < 0 || a1 - 1 < 0 || a2 - 1 < 0 || a3 - 1 < 0 || a3 - 2 < 0 || a2 - 2 < 0 || a1 - 2 < 0 || a4 >= rates_total)
| |
continue;
| |
| |
bool firstFvg = isBoolishFvg(high, low, a1);
| |
bool secondFvg = isBoolishFvg(high, low, a2);
| |
bool thirdFvg = isBoolishFvg(high, low, a3);
| |
| |
if(firstFvg)
| |
{
| |
BullFVGBuffer1[a1 - 1] = high[a1];
| |
BullFVGBuffer2[a1 - 1] = high[a1];
| |
BullFVGBuffer3[a1 - 1] = low[a1 - 2];
| |
BullFVGBuffer4[a1 - 1] = low[a1 - 2];
| |
}
| |
/* else if(secondFvg)
| |
{
| |
BullFVGBuffer1[a2 - 1] = high[a2];
| |
BullFVGBuffer2[a2 - 1] = high[a2];
| |
BullFVGBuffer3[a2 - 1] = low[a2 - 2];
| |
BullFVGBuffer4[a2 - 1] = low[a2 - 2];
| |
}
| |
else if(thirdFvg)
| |
{
| |
BullFVGBuffer1[a3 - 1] = high[a3];
| |
BullFVGBuffer2[a3 - 1] = high[a3];
| |
BullFVGBuffer3[a3 - 1] = low[a3 - 2];
| |
BullFVGBuffer4[a3 - 1] = low[a3 - 2];
| |
}*/
| |
}
| |
}
| |
last_bar_time = time[rates_total - 1];
| |
return(rates_total);
| |
}
| |
bool isBoolishFvg(const double &high[], const double &low[], int fromIndex = 2)
| |
{
| |
int a3 = MathMax(fromIndex - 2, 1);
| |
return (high[fromIndex] < low[a3]);
| |
}
|