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