last works ...
This commit is contained in:
@@ -365,9 +365,13 @@ class XCBackTesterEA : public XCBase
|
||||
ZeroMemory(eaTarget);
|
||||
|
||||
//
|
||||
eaPositionDrawer.Destroy();
|
||||
delete eaPositionDrawer;
|
||||
ZeroMemory(eaPositionDrawer);
|
||||
if (eaPositionDrawer != NULL)
|
||||
{
|
||||
//
|
||||
eaPositionDrawer.Destroy();
|
||||
delete eaPositionDrawer;
|
||||
ZeroMemory(eaPositionDrawer);
|
||||
}
|
||||
|
||||
//
|
||||
delete eaVolume;
|
||||
|
||||
@@ -1898,6 +1898,334 @@ class XCMarketPatternDetector : public XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
bool HasOrderFlow(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
XBoxZone &orderFlow[],
|
||||
int orderFlowValidation = 2,
|
||||
bool containsOBs = false,
|
||||
bool containsFVGs = true,
|
||||
bool containsSupportResistances = false,
|
||||
int zonesLoopback = 5,
|
||||
int zonesValidationLength = 21,
|
||||
int maxRequiredZone = 0,
|
||||
int loopback = 100 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
XClean(orderFlow);
|
||||
CleanDirection(dir);
|
||||
|
||||
//
|
||||
// Normalize ...
|
||||
loopback = NormalizeInt(loopback, 10);
|
||||
zonesLoopback = NormalizeInt(zonesLoopback, 3);
|
||||
maxRequiredZone = NormalizeInt(maxRequiredZone, 0);
|
||||
orderFlowValidation = NormalizeInt(orderFlowValidation, 1);
|
||||
zonesValidationLength = NormalizeInt(zonesValidationLength, 3);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Do ...
|
||||
|
||||
//
|
||||
// Collectiong Zones ...
|
||||
XBoxZone tmp;
|
||||
XBoxZone tmps[];
|
||||
XBoxZone _zones[];
|
||||
XBoxZone bullishZones[];
|
||||
XBoxZone bearishZones[];
|
||||
int bullishZonesCount = 0;
|
||||
int bearishZonesCount = 0;
|
||||
|
||||
//
|
||||
// Order Blocks ...
|
||||
if (containsOBs)
|
||||
{
|
||||
//
|
||||
XClean(tmps);
|
||||
CollectOBs(bar, tmps, zonesLoopback, maxRequiredZone, loopback);
|
||||
FillNotExists(_zones, tmps);
|
||||
}
|
||||
|
||||
//
|
||||
// Fair Value Gaps ...
|
||||
if (containsFVGs)
|
||||
{
|
||||
//
|
||||
XClean(tmps);
|
||||
CollectFVGs(bar, tmps, zonesLoopback, maxRequiredZone, loopback);
|
||||
FillNotExists(_zones, tmps);
|
||||
}
|
||||
|
||||
//
|
||||
// Support and Resistances ...
|
||||
if (containsSupportResistances)
|
||||
{
|
||||
//
|
||||
XClean(tmps);
|
||||
CollectZones(bar, tmps, zonesLoopback, maxRequiredZone, loopback);
|
||||
FillNotExists(_zones, tmps);
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Zones ...
|
||||
result = HasChild(_zones);
|
||||
|
||||
//
|
||||
// Extract Only Validated Zones ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
ValidateBoxes(
|
||||
_zones,
|
||||
bar.Index() //
|
||||
);
|
||||
|
||||
//
|
||||
result = HasChild(_zones);
|
||||
}
|
||||
|
||||
//
|
||||
// Separate Zones Direction ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
bullishZonesCount = ExtractByDirection(bullishZones, _zones, X_DIRECTION_BULLISH);
|
||||
bearishZonesCount = ExtractByDirection(bearishZones, _zones, X_DIRECTION_BEARISH);
|
||||
|
||||
//
|
||||
result = IsValidSize(bullishZonesCount) ||
|
||||
IsValidSize(bearishZonesCount);
|
||||
}
|
||||
|
||||
//
|
||||
// Looking for Sequences of Zones ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
int idx = -1;
|
||||
bool has = false;
|
||||
XBoxZone bullOrderFlow[];
|
||||
XBoxZone bearOrderFlow[];
|
||||
|
||||
//
|
||||
// Bullish OrderFlow ...
|
||||
|
||||
//
|
||||
// Sorting ...
|
||||
Copy(bullishZones, bullOrderFlow);
|
||||
Sort(
|
||||
bullOrderFlow,
|
||||
X_SORT_BY_DATE,
|
||||
X_DIRECTION_BEARISH,
|
||||
orderFlowValidation + 1 //
|
||||
);
|
||||
bool hasBullishOrderFlow = ArraySize(bullOrderFlow) >= orderFlowValidation;
|
||||
if (hasBullishOrderFlow)
|
||||
{
|
||||
//
|
||||
// Validate Order Flow ...
|
||||
Copy(bullOrderFlow, tmps);
|
||||
XClean(bullOrderFlow);
|
||||
while (HasChild(tmps))
|
||||
{
|
||||
//
|
||||
tmp.Clean();
|
||||
tmp = tmps[0];
|
||||
ArrayRemove(tmps, 0, 1);
|
||||
|
||||
//
|
||||
idx = GetHighest(tmps);
|
||||
has = !IsValidIndex(idx)
|
||||
? true
|
||||
: tmps[idx].lower < tmp.lower;
|
||||
if (has)
|
||||
{
|
||||
AddIfNotExists(tmp, bullOrderFlow);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
hasBullishOrderFlow = ArraySize(bullOrderFlow) >= orderFlowValidation;
|
||||
}
|
||||
|
||||
//
|
||||
// Bearish OrderFlow ...
|
||||
|
||||
//
|
||||
// Sorting ...
|
||||
Copy(bearishZones, bearOrderFlow);
|
||||
Sort(
|
||||
bearOrderFlow,
|
||||
X_SORT_BY_DATE,
|
||||
X_DIRECTION_BULLISH,
|
||||
orderFlowValidation + 1 //
|
||||
);
|
||||
bool hasBearishOrderFlow = ArraySize(bearOrderFlow) >= orderFlowValidation;
|
||||
if (hasBearishOrderFlow)
|
||||
{
|
||||
//
|
||||
// Validate Order Flow ...
|
||||
Copy(bearOrderFlow, tmps);
|
||||
XClean(bearOrderFlow);
|
||||
while (HasChild(tmps))
|
||||
{
|
||||
//
|
||||
tmp.Clean();
|
||||
tmp = tmps[0];
|
||||
ArrayRemove(tmps, 0, 1);
|
||||
|
||||
//
|
||||
idx = GetLowest(tmps);
|
||||
has = !IsValidIndex(idx)
|
||||
? true
|
||||
: tmps[idx].upper > tmp.upper;
|
||||
if (has)
|
||||
{
|
||||
AddIfNotExists(tmp, bearOrderFlow);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
hasBearishOrderFlow = ArraySize(bearOrderFlow) >= orderFlowValidation;
|
||||
}
|
||||
|
||||
//
|
||||
result = hasBullishOrderFlow ||
|
||||
hasBearishOrderFlow;
|
||||
|
||||
//
|
||||
// Validate Order Flows ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
has = (hasBullishOrderFlow && !hasBearishOrderFlow) ||
|
||||
(hasBearishOrderFlow && !hasBullishOrderFlow);
|
||||
|
||||
//
|
||||
// When only Have One Direction ...
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
if (hasBullishOrderFlow)
|
||||
{
|
||||
//
|
||||
dir = X_DIRECTION_BULLISH;
|
||||
Copy(bullOrderFlow, orderFlow);
|
||||
}
|
||||
else if (hasBearishOrderFlow)
|
||||
{
|
||||
//
|
||||
dir = X_DIRECTION_BEARISH;
|
||||
Copy(bearOrderFlow, orderFlow);
|
||||
}
|
||||
}
|
||||
//
|
||||
// When Two Direction Exists ...
|
||||
else
|
||||
{
|
||||
//
|
||||
// Retrieve Oldest Of Bullish / Bearish ...
|
||||
int oldestBullIDX = GetOldest(bullOrderFlow);
|
||||
int oldestBearIDX = GetOldest(bearOrderFlow);
|
||||
result = IsValidIndex(oldestBullIDX) &&
|
||||
IsValidIndex(oldestBearIDX);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
dir =
|
||||
bullOrderFlow[oldestBullIDX].from > bearOrderFlow[oldestBearIDX].from
|
||||
? X_DIRECTION_BULLISH
|
||||
: bearOrderFlow[oldestBearIDX].from > bullOrderFlow[oldestBullIDX].from
|
||||
? X_DIRECTION_BEARISH
|
||||
: X_DIRECTION_NONE;
|
||||
}
|
||||
|
||||
//
|
||||
result = HasDirection(dir);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (IsXBullish(dir))
|
||||
{
|
||||
Copy(bullOrderFlow, orderFlow);
|
||||
}
|
||||
else if (IsXBearish(dir))
|
||||
{
|
||||
Copy(bearOrderFlow, orderFlow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
XClean(bullOrderFlow);
|
||||
XClean(bearOrderFlow);
|
||||
|
||||
//
|
||||
result = HasChild(orderFlow) &&
|
||||
HasDirection(dir);
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Price ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
int idx = -1;
|
||||
if (IsXBullish(dir))
|
||||
{
|
||||
//
|
||||
idx = GetHighest(orderFlow);
|
||||
result = IsValidIndex(idx) &&
|
||||
bar.low > orderFlow[idx].upper;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
idx = GetLowest(orderFlow);
|
||||
result = IsValidIndex(idx) &&
|
||||
bar.high < orderFlow[idx].lower;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update To Time of Order Flow ...
|
||||
if (result)
|
||||
{
|
||||
UpdateToTime(orderFlow, bar.time);
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
XClean(orderFlow);
|
||||
CleanDirection(dir);
|
||||
}
|
||||
tmp.Clean();
|
||||
XClean(tmps);
|
||||
XClean(_zones);
|
||||
XClean(bullishZones);
|
||||
XClean(bearishZones);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// FVG ...
|
||||
|
||||
|
||||
Reference in New Issue
Block a user