Files
Bell-PriceActionWithEma-EA/Include/ICT2026/ConfirmFvg.mqh
T
2026-05-24 22:24:36 +07:00

129 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//+------------------------------------------------------------------+
//| ConfirmFvg.mqh — FVG trên Confirm TF (M5) cho MSS entry |
//+------------------------------------------------------------------+
#ifndef ICT2026_CONFIRMFVG_MQH
#define ICT2026_CONFIRMFVG_MQH
#include <ICT2026/Fvg.mqh>
IctFvgZone g_ictConfirmFvgZones[];
int g_ictConfirmFvgCount = 0;
static ulong g_ictConfirmFvgNextId = 100000;
void IctConfirmFvg_Reset()
{
g_ictConfirmFvgCount = 0;
ArrayResize(g_ictConfirmFvgZones, 0);
}
bool IctConfirmFvg_IsDuplicate(const datetime createdTime, const double upper, const double lower)
{
const double tol = _Point * 2.0;
for(int i = 0; i < g_ictConfirmFvgCount; i++)
{
if(g_ictConfirmFvgZones[i].createdTime != createdTime)
continue;
if(MathAbs(g_ictConfirmFvgZones[i].upper - upper) <= tol &&
MathAbs(g_ictConfirmFvgZones[i].lower - lower) <= tol)
return true;
}
return false;
}
void IctConfirmFvg_AddZone(const IctFvgZone &zone)
{
if(g_ictConfirmFvgCount >= InpFvgMaxZones)
{
for(int i = 0; i < g_ictConfirmFvgCount - 1; i++)
g_ictConfirmFvgZones[i] = g_ictConfirmFvgZones[i + 1];
g_ictConfirmFvgCount--;
}
ArrayResize(g_ictConfirmFvgZones, g_ictConfirmFvgCount + 1);
g_ictConfirmFvgZones[g_ictConfirmFvgCount] = zone;
g_ictConfirmFvgCount++;
}
void IctConfirmFvg_UpdateAll(const string sym, const ENUM_TIMEFRAMES tf)
{
for(int i = 0; i < g_ictConfirmFvgCount; i++)
IctFvg_UpdateZoneState(sym, tf, g_ictConfirmFvgZones[i]);
}
void IctConfirmFvg_ScanNew(const string sym, const ENUM_TIMEFRAMES tf,
const ENUM_ICT_FVG_SIDE wantSide,
const datetime notBefore,
const bool fullLookback = false)
{
if(wantSide == ICT_FVG_NONE)
return;
const int maxShift = MathMin(InpMssConfirmFvgBars, Bars(sym, tf) - 3);
if(maxShift < 1)
return;
int fromSh = fullLookback ? maxShift : MathMin(maxShift, MathMax(1, InpFvgScanBarsPerUpdate));
for(int sh = fromSh; sh >= 1; sh--)
{
ENUM_ICT_FVG_SIDE side = ICT_FVG_NONE;
double upper = 0.0, lower = 0.0;
datetime timeA = 0, timeC = 0;
if(!IctFvg_TryDetectAtShift(sym, tf, sh, wantSide, side, upper, lower, timeA, timeC))
continue;
if(notBefore > 0 && timeC < notBefore)
continue;
if(IctConfirmFvg_IsDuplicate(timeC, upper, lower))
continue;
IctFvgZone zone;
zone.Clear();
zone.id = g_ictConfirmFvgNextId++;
zone.side = side;
zone.state = ICT_FVG_AVAILABLE;
zone.upper = upper;
zone.lower = lower;
zone.createdTime = timeC;
zone.timeStart = timeA;
zone.expireTime = timeC + (datetime)(InpFvgExpireDays * 86400);
zone.locked = true;
IctFvg_UpdateZoneState(sym, tf, zone);
IctConfirmFvg_AddZone(zone);
if(InpDebug)
PrintFormat("[ICT2026/CFVG] New %s [%.2f %.2f] @ %s",
IctFvgSideText(zone.side), zone.lower, zone.upper,
TimeToString(timeC, TIME_DATE | TIME_MINUTES));
}
}
int IctConfirmFvg_FindLatestAfter(const datetime notBefore, const ENUM_ICT_FVG_SIDE side)
{
int bestIdx = -1;
datetime bestT = 0;
for(int i = 0; i < g_ictConfirmFvgCount; i++)
{
if(g_ictConfirmFvgZones[i].side != side)
continue;
if(notBefore > 0 && g_ictConfirmFvgZones[i].createdTime < notBefore)
continue;
if(g_ictConfirmFvgZones[i].createdTime >= bestT)
{
bestT = g_ictConfirmFvgZones[i].createdTime;
bestIdx = i;
}
}
return bestIdx;
}
int IctConfirmFvg_FindById(const ulong id)
{
for(int i = 0; i < g_ictConfirmFvgCount; i++)
if(g_ictConfirmFvgZones[i].id == id)
return i;
return -1;
}
#endif