129 lines
3.8 KiB
Plaintext
129 lines
3.8 KiB
Plaintext
//+------------------------------------------------------------------+
|
||||
|
|
//| 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
|