174 lines
No EOL
12 KiB
MQL5
174 lines
No EOL
12 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Fair Value Gap Indicator |
|
|
//| Copyright 2024, Hieu Hoang |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024, hieuhoangcntt@gmail.com"
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\\Utils\\MetricSaver.mqh"
|
|
|
|
|
|
// https://www.mql5.com/en/code/51977 (convertido a EA)
|
|
|
|
double _low, _high;
|
|
string object_names[];
|
|
datetime pre_time = 0;
|
|
const int bull = 5;
|
|
const int bear = 5;
|
|
int c_bull;
|
|
int c_bear;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool isGreenCandle(double open, double close)
|
|
{
|
|
return open < close;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool isRedCandle(double open, double close)
|
|
{
|
|
return !isGreenCandle(open, close);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool isBullFVG(int index,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[])
|
|
{
|
|
if(isGreenCandle(open[index-1], close[index-1]) &&
|
|
high[index-2] < low[index] && high[index-2] < _low
|
|
)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool isBearFVG(int index,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[])
|
|
{
|
|
if(isRedCandle(open[index-1], close[index-1]) &&
|
|
low[index-2] > high[index] && low[index-2] > _high
|
|
)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
CMetricsSave::Start(FILE_CODE2);
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void create_object(string name, color clrColor, const datetime time1, const datetime time2, const double low, const double high)
|
|
{
|
|
ArrayResize(object_names, ArraySize(object_names) + 1);
|
|
object_names[ArraySize(object_names) - 1] = name;
|
|
ObjectCreate(0, name, OBJ_RECTANGLE, 0, time1, low, time2, high);
|
|
ObjectSetInteger(0, name, OBJPROP_COLOR, clrColor);
|
|
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
|
ObjectSetInteger(0, name, OBJPROP_FILL, true);
|
|
ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
MqlRates rates[];
|
|
int copied = CopyRates(_Symbol, PERIOD_CURRENT, 0, 100, rates);
|
|
if(copied <= 0)
|
|
return;
|
|
|
|
datetime time[];
|
|
double open[];
|
|
double high[];
|
|
double low[];
|
|
double close[];
|
|
|
|
ArrayResize(time, copied);
|
|
ArrayResize(open, copied);
|
|
ArrayResize(high, copied);
|
|
ArrayResize(low, copied);
|
|
ArrayResize(close, copied);
|
|
|
|
for(int i = 0; i < copied; i++)
|
|
{
|
|
time[i] = rates[i].time;
|
|
open[i] = rates[i].open;
|
|
high[i] = rates[i].high;
|
|
low[i] = rates[i].low;
|
|
close[i] = rates[i].close;
|
|
}
|
|
|
|
int rates_total = copied;
|
|
|
|
if(pre_time == time[rates_total - 1])
|
|
return;
|
|
pre_time = time[rates_total - 1];
|
|
delete_objects();
|
|
_low = low[rates_total - 1];
|
|
_high = high[rates_total - 1];
|
|
c_bull = 0;
|
|
c_bear = 0;
|
|
for(int i = rates_total - 2; i >= 2; i--)
|
|
{
|
|
_low = _low < low[i] ? _low : low[i];
|
|
_high = _high > high[i] ? _high: high[i];
|
|
if(c_bull < bull && isBullFVG(i, open, high, low, close))
|
|
{
|
|
create_object("Buy range " + string(high[i-2]) + " ↗ " + string(low[i]), clrBlue, time[i-2], time[rates_total-1], low[i], high[i-2]);
|
|
c_bull ++;
|
|
if(c_bull >= bull && c_bear >= bear)
|
|
break;
|
|
}
|
|
else if(c_bear < bear && isBearFVG(i, open, high, low, close))
|
|
{
|
|
create_object("Sell range " + string(low[i-2]) + " ↘ " + string(high[i]), clrRed, time[i-2], time[rates_total-1], high[i], low[i-2]);
|
|
c_bear ++;
|
|
if(c_bull >= bull && c_bear >= bear)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void delete_objects()
|
|
{
|
|
for(int i = 0; i < ArraySize(object_names); i++)
|
|
ObjectDelete(0, object_names[i]);
|
|
ArrayResize(object_names, 0);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
pre_time = 0;
|
|
delete_objects();
|
|
CMetricsSave::Destroy();
|
|
}
|
|
//+------------------------------------------------------------------+ |