This commit is contained in:
2025-10-15 13:24:34 +03:30
parent cfe8734715
commit d24610c47b
4 changed files with 1981 additions and 346 deletions
@@ -3519,6 +3519,345 @@ class XCMarketPatternDetector : public XCBase
return result;
}
int CollectOBs(
XOHCL &bar,
XBoxZone &dest[],
int zonesLoopback = 5,
int maxRequiredZone = 0,
int loopback = 100 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Normalize ...
loopback = NormalizeInt(loopback, 10);
zonesLoopback = NormalizeInt(zonesLoopback, 3);
maxRequiredZone = NormalizeInt(maxRequiredZone, 0);
//
// Validate ...
bool has = bar.IsValid();
if (!has)
{
return result;
}
//
XOHCL iBar;
XBoxZone iBox;
ENUM_X_DIRECTION iDir;
int start = bar.Index();
int end = start + loopback;
for (int i = start; i < end; i++)
{
//
iBar.Clean();
iBox.Clean();
iDir = X_DIRECTION_NONE;
//
has = bar.BarAt(i, iBar);
has = has &&
HasOB(iBar, iDir, iBox, zonesLoopback);
if (has)
{
//
AddIfNotExists(
iBox,
dest //
);
}
//
has = maxRequiredZone <= 0 ||
(maxRequiredZone > 0 && ArraySize(dest) < maxRequiredZone);
if (!has)
{
break;
}
}
//
result = ArraySize(dest);
//
// Cleanup ...
iBar.Clean();
iBox.Clean();
iDir = X_DIRECTION_NONE;
//
return result;
}
int CollectFVGs(
XOHCL &bar,
XBoxZone &dest[],
int zonesLoopback = 5,
int maxRequiredZone = 0,
int loopback = 100 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Normalize ...
loopback = NormalizeInt(loopback, 10);
zonesLoopback = NormalizeInt(zonesLoopback, 3);
maxRequiredZone = NormalizeInt(maxRequiredZone, 0);
//
// Validate ...
bool has = bar.IsValid();
if (!has)
{
return result;
}
//
XOHCL iBar;
XBoxZone iBox;
ENUM_X_DIRECTION iDir;
int start = bar.Index();
int end = start + loopback;
for (int i = start; i < end; i++)
{
//
iBar.Clean();
iBox.Clean();
iDir = X_DIRECTION_NONE;
//
has = bar.BarAt(i, iBar);
has = has &&
HasFVG(iBar, iDir, iBox, zonesLoopback);
if (has)
{
//
AddIfNotExists(
iBox,
dest //
);
}
//
has = maxRequiredZone <= 0 ||
(maxRequiredZone > 0 && ArraySize(dest) < maxRequiredZone);
if (!has)
{
break;
}
}
//
result = ArraySize(dest);
//
// Cleanup ...
iBar.Clean();
iBox.Clean();
iDir = X_DIRECTION_NONE;
//
return result;
}
int CollectZones(
XOHCL &bar,
XBoxZone &dest[],
int zonesLoopback = 5,
int zonesValidationLength = 21,
int maxRequiredZone = 0,
int loopback = 100 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Normalize ...
loopback = NormalizeInt(loopback, 10);
zonesLoopback = NormalizeInt(zonesLoopback, 3);
maxRequiredZone = NormalizeInt(maxRequiredZone, 0);
zonesValidationLength = NormalizeInt(zonesValidationLength, 3);
//
// Validate ...
bool has = bar.IsValid();
if (!has)
{
return result;
}
//
XOHCL iBar;
XBoxZone iBox;
XOHCL iZoneBar;
int start = bar.Index();
int end = start + loopback;
for (int i = start; i < end; i++)
{
//
iBar.Clean();
iBox.Clean();
iZoneBar.Clean();
//
has = bar.BarAt(i, iBar);
if (!has)
{
continue;
}
//
// Support ...
has = HasSupport(iBar, iZoneBar, zonesValidationLength, zonesLoopback);
if (has)
{
//
has = ToSupportBox(iZoneBar, iBox, bar.time, zonesValidationLength);
if (has)
{
//
AddIfNotExists(
iBox,
dest //
);
}
}
//
// Resistance ...
has = HasResistance(iBar, iZoneBar, zonesValidationLength, zonesLoopback);
if (has)
{
//
has = ToResistanceBox(iZoneBar, iBox, bar.time, zonesValidationLength);
if (has)
{
//
AddIfNotExists(
iBox,
dest //
);
}
}
//
has = maxRequiredZone <= 0 ||
(maxRequiredZone > 0 && ArraySize(dest) < maxRequiredZone);
if (!has)
{
break;
}
}
//
result = ArraySize(dest);
//
// Cleanup ...
iBar.Clean();
iBox.Clean();
iZoneBar.Clean();
//
return result;
}
int FilterZones(
XOHCL &bar,
XBoxZone &source[],
ENUM_X_DIRECTION filterDir,
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = 0;
//
// Prepare ...
XBoxZone tmp[];
Copy(
source,
tmp //
);
XClean(source);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(tmp) &&
IsXValid(priceType) &&
HasDirection(filterDir);
if (!has)
{
//
XClean(tmp);
return result;
}
//
XBoxZone iBox;
double price = bar.GetPrice(priceType);
bool isBullish = IsXBullish(filterDir);
while (HasChild(tmp))
{
//
iBox = tmp[0];
ArrayRemove(tmp, 0, 1);
//
has =
//
// Direction Pass ...
(!HasDirection(forDir)
? true
: forDir == iBox.dir)
//
&&
//
// Price Pass ...
(isBullish
? price > iBox.lower
: price < iBox.upper);
if (has)
{
AddIfNotExists(iBox, source);
}
//
iBox.Clean();
}
//
result = ArraySize(source);
//
// Cleanup ...
XClean(tmp);
iBox.Clean();
//
return result;
}
//
// Protected ...
protected: