Files
Bell-PriceActionWithEma-EA/Experts/SimpleFVG.mq5
T

186 lines
6.0 KiB
Plaintext
Raw Normal View History

2026-03-11 01:01:25 +07:00
//+------------------------------------------------------------------+
2026-03-11 16:06:24 +07:00
//| SimpleFVG.mq5 Fair Value Gap Visual Strategy (Test mode) |
//| |
//| Modules: |
//| Config.mqh → Step 0: Inputs, enums, constants |
//| Trend.mqh → Step 1: EMA34/EMA89 trend detection |
//| FVG.mqh → Step 2: FVG scanning & management |
//| Drawing.mqh → Step 4: Chart visualization |
2026-03-11 01:01:25 +07:00
//+------------------------------------------------------------------+
#property copyright "SimpleFVG"
2026-03-11 16:06:24 +07:00
#property version "2.00"
#property description "FVG strategy visualizer EMA trend + FVG zones on chart"
2026-03-11 01:01:25 +07:00
2026-03-11 16:06:24 +07:00
#include "SimpleFVG/Config.mqh"
#include "SimpleFVG/Trend.mqh"
#include "SimpleFVG/FVG.mqh"
2026-03-11 18:13:27 +07:00
#include "SimpleFVG/Trade.mqh"
2026-03-11 16:06:24 +07:00
#include "SimpleFVG/Drawing.mqh"
2026-03-11 01:01:25 +07:00
//+------------------------------------------------------------------+
2026-03-11 16:06:24 +07:00
//| OnInit |
2026-03-11 01:01:25 +07:00
//+------------------------------------------------------------------+
int OnInit()
{
2026-03-11 16:06:24 +07:00
//--- Step 1: Initialize trend (EMA handles + chart indicators) ---
if(!TrendInit())
return INIT_FAILED;
2026-03-11 01:01:25 +07:00
2026-03-11 16:06:24 +07:00
//--- Step 2: Initialize FVG array ---
FVGInit();
2026-03-11 01:01:25 +07:00
2026-03-11 16:06:24 +07:00
//--- Initial scan on existing bars ---
TrendUpdate();
FVGUpdate();
2026-03-11 01:01:25 +07:00
2026-03-11 16:06:24 +07:00
//--- Step 4: Draw everything ---
DrawAll();
2026-03-11 01:01:25 +07:00
2026-03-11 16:06:24 +07:00
if(InpDebugLog)
PrintFormat("[INIT] SimpleFVG v2.0 | %s %s | EMA%d/%d | FVG lookback=%d maxAge=%d",
GetTradeSymbol(), EnumToString(InpTimeframe),
InpEMAFastPeriod, InpEMASlowPeriod,
InpFVGLookbackBars, InpFVGMaxAgeBars);
2026-03-19 21:41:57 +07:00
//--- Initialize last processed exit time so we don't reset based on old history.
g_LastExitDealTime = GetLatestTP_SL_ExitDealTime();
2026-03-11 16:06:24 +07:00
return INIT_SUCCEEDED;
2026-03-11 01:01:25 +07:00
}
2026-03-19 21:41:57 +07:00
//--- Track last processed TP/SL exit so we can reset strategy state
//--- only when a new SL/TP happens (not from older history).
datetime g_LastExitDealTime = 0;
datetime GetLatestTP_SL_ExitDealTime()
{
datetime now = TimeCurrent();
if(now == 0)
return 0;
if(!HistorySelect(0, now))
return 0;
datetime latest = 0;
string symbol = GetTradeSymbol();
int deals = HistoryDealsTotal();
for(int i = 0; i < deals; i++)
{
ulong dealTicket = HistoryDealGetTicket(i);
if(dealTicket == 0)
continue;
string dealSymbol = (string)HistoryDealGetString(dealTicket, DEAL_SYMBOL);
long dealMagic = (long)HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
if(dealSymbol != symbol || dealMagic != InpEAMagic)
continue;
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(dealTicket, DEAL_ENTRY);
if(entry != DEAL_ENTRY_OUT && entry != DEAL_ENTRY_INOUT)
continue;
ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger(dealTicket, DEAL_REASON);
if(reason != DEAL_REASON_TP && reason != DEAL_REASON_SL)
continue;
datetime dealTime = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME);
if(dealTime > latest)
latest = dealTime;
}
return latest;
}
//--- If a new TP/SL exit is detected since the last processed time,
//--- reset all FVG statuses by re-initializing the array and rescanning.
bool CheckAndResetOnNewTP_SL_Exit()
{
datetime now = TimeCurrent();
if(now == 0)
return false;
if(!HistorySelect(0, now))
return false;
datetime latestExit = g_LastExitDealTime;
string symbol = GetTradeSymbol();
int deals = HistoryDealsTotal();
for(int i = 0; i < deals; i++)
{
ulong dealTicket = HistoryDealGetTicket(i);
if(dealTicket == 0)
continue;
string dealSymbol = (string)HistoryDealGetString(dealTicket, DEAL_SYMBOL);
long dealMagic = (long)HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
if(dealSymbol != symbol || dealMagic != InpEAMagic)
continue;
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(dealTicket, DEAL_ENTRY);
if(entry != DEAL_ENTRY_OUT && entry != DEAL_ENTRY_INOUT)
continue;
ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger(dealTicket, DEAL_REASON);
if(reason != DEAL_REASON_TP && reason != DEAL_REASON_SL)
continue;
datetime dealTime = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME);
if(dealTime > g_LastExitDealTime && dealTime > latestExit)
latestExit = dealTime;
}
if(latestExit <= g_LastExitDealTime)
return false;
//--- Only reset strategy state when our position is fully closed.
//--- This avoids resetting on partial TP/SL deals while position still exists.
if(CountOurPositions() > 0)
return false;
g_LastExitDealTime = latestExit;
//--- Cancel any pending limit orders left from before the exit.
CancelAllOurLimitOrders();
//--- Reset FVG states completely and rescan from scratch.
FVGInit();
TrendUpdate();
FVGUpdate();
if(InpDebugLog)
PrintFormat("[RESET] New SL/TP exit at %s → reset FVG array",
TimeToString(g_LastExitDealTime));
return true;
}
2026-03-11 16:06:24 +07:00
//+------------------------------------------------------------------+
//| OnDeinit |
//+------------------------------------------------------------------+
2026-03-11 01:01:25 +07:00
void OnDeinit(const int reason)
{
2026-03-11 16:06:24 +07:00
TrendDeinit();
DrawCleanup();
2026-03-11 01:01:25 +07:00
}
2026-03-11 16:06:24 +07:00
//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
2026-03-11 01:01:25 +07:00
void OnTick()
{
2026-03-11 16:06:24 +07:00
if(!IsNewBar())
return;
2026-03-11 01:01:25 +07:00
2026-03-19 21:41:57 +07:00
//--- IMPORTANT: reset internal FVG status after TP/SL so we don't reuse
//--- old TOUCHED/MITIGATED states.
if(CheckAndResetOnNewTP_SL_Exit())
{
DrawAll();
return; // avoid entering a new trade on the same bar immediately
}
2026-03-11 16:06:24 +07:00
TrendUpdate();
FVGUpdate();
2026-03-11 18:13:27 +07:00
ManageFVGTrades();
2026-03-11 16:06:24 +07:00
DrawAll();
2026-03-11 01:01:25 +07:00
}