Add support for Draw Trend Line for Order Flow ...
This commit is contained in:
@@ -37,306 +37,6 @@ enum ENUM_X121SMC_XWZ_PRIORITY
|
||||
X121SMC_XWZ_PRIORITY_STRONG_HIGH,
|
||||
};
|
||||
|
||||
//
|
||||
struct X121SMCXWZZone
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
XCFVG *fvg;
|
||||
XCOrderBlock *ob;
|
||||
XCSupplyZone *supply;
|
||||
XCDemandZone *demand;
|
||||
XCSupportZone *support;
|
||||
XCResistanceZone *resistance;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
X121SMCXWZZone()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
ZeroMemory(ob);
|
||||
ZeroMemory(fvg);
|
||||
ZeroMemory(supply);
|
||||
ZeroMemory(demand);
|
||||
ZeroMemory(support);
|
||||
ZeroMemory(resistance);
|
||||
}
|
||||
|
||||
//
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
return HasOB() &&
|
||||
HasFVG() &&
|
||||
HasDirection();
|
||||
}
|
||||
|
||||
//
|
||||
bool AsBox(XBoxZone &box)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
box.Clean();
|
||||
|
||||
//
|
||||
result = IsValid() &&
|
||||
HasDirection();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XBoxZone obBox;
|
||||
bool hasOBBox = ToBox(
|
||||
obBox,
|
||||
ob //
|
||||
);
|
||||
result = hasOBBox;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
box.Clean();
|
||||
obBox.Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
box = obBox;
|
||||
|
||||
//
|
||||
obBox.Clean();
|
||||
|
||||
//
|
||||
bool hasOB = HasOB();
|
||||
bool hasFVG = HasFVG();
|
||||
bool hasSupply = HasSupply();
|
||||
bool hasDemand = HasDemand();
|
||||
bool hasSupport = HasSupport();
|
||||
bool hasResistance = HasResistance();
|
||||
|
||||
//
|
||||
// OB Compared since box used obBox ...
|
||||
|
||||
//
|
||||
if (hasFVG)
|
||||
{
|
||||
//
|
||||
if (fvg.Upper() > box.upper)
|
||||
{
|
||||
box.upper = fvg.Upper();
|
||||
}
|
||||
|
||||
//
|
||||
if (fvg.Lower() < box.lower)
|
||||
{
|
||||
box.lower = fvg.Lower();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = box.IsValid();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool HasOB()
|
||||
{
|
||||
return ob != NULL &&
|
||||
ob.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasFVG()
|
||||
{
|
||||
return fvg != NULL &&
|
||||
fvg.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasSupply()
|
||||
{
|
||||
return supply != NULL &&
|
||||
supply.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasDemand()
|
||||
{
|
||||
return demand != NULL &&
|
||||
demand.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasSupport()
|
||||
{
|
||||
return support != NULL &&
|
||||
support.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasResistance()
|
||||
{
|
||||
return resistance != NULL &&
|
||||
resistance.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool IsBullish()
|
||||
{
|
||||
//
|
||||
return HasOB() &&
|
||||
ob.IsBullish() &&
|
||||
HasFVG() &&
|
||||
fvg.IsBullish();
|
||||
}
|
||||
|
||||
//
|
||||
bool IsBearish()
|
||||
{
|
||||
//
|
||||
return HasOB() &&
|
||||
ob.IsBearish() &&
|
||||
HasFVG() &&
|
||||
fvg.IsBearish();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasDirection()
|
||||
{
|
||||
return IsBullish() ||
|
||||
IsBearish();
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateZone(
|
||||
int barIndex = 0,
|
||||
ENUM_TIMEFRAMES forPeriod = NULL,
|
||||
bool forceOB = false,
|
||||
bool forceFVG = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (barIndex < 0)
|
||||
{
|
||||
barIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValid() &&
|
||||
HasDirection();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = ob.GetSymbol();
|
||||
if (forPeriod == NULL)
|
||||
{
|
||||
forPeriod = ob.GetPeriod();
|
||||
}
|
||||
ENUM_X_DIRECTION forDir = GetDirection();
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
symbol,
|
||||
forPeriod,
|
||||
barIndex + 1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
cBar.Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isObBreaked =
|
||||
IsBullish(forDir)
|
||||
? cBar.close < ob.Lower()
|
||||
: cBar.close > ob.Upper();
|
||||
|
||||
//
|
||||
bool isFVGBreaked =
|
||||
IsBullish(forDir)
|
||||
? cBar.close < fvg.Lower()
|
||||
: cBar.close > fvg.Upper();
|
||||
|
||||
//
|
||||
bool isBreaked = true;
|
||||
if ((forceOB && forceFVG) ||
|
||||
(!forceOB && !forceFVG))
|
||||
{
|
||||
isBreaked =
|
||||
isObBreaked ||
|
||||
isFVGBreaked;
|
||||
}
|
||||
else if (forceFVG)
|
||||
{
|
||||
isBreaked = isFVGBreaked;
|
||||
}
|
||||
else if (forceOB)
|
||||
{
|
||||
isBreaked = isObBreaked;
|
||||
}
|
||||
|
||||
//
|
||||
result = !isBreaked;
|
||||
|
||||
//
|
||||
cBar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION GetDirection()
|
||||
{
|
||||
//
|
||||
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
bool hasDirection = HasDirection();
|
||||
if (!hasDirection)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isBullish = IsBullish();
|
||||
|
||||
//
|
||||
result =
|
||||
isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
struct X121SMCStrategyXWZSignalConditions
|
||||
@@ -371,9 +71,7 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
ENUM_X121SMC_XWZ_PRIORITY priority;
|
||||
|
||||
//
|
||||
// X121SMCXWZZone startZone;
|
||||
X121SMCXWZZone bullishFlow[];
|
||||
X121SMCXWZZone bearishFlow[];
|
||||
XOBFVG orderFlow[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
@@ -503,8 +201,7 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
|
||||
//
|
||||
// startZone.Clean();
|
||||
Clean(bullishFlow);
|
||||
Clean(bearishFlow);
|
||||
Clean(orderFlow);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -512,27 +209,93 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
//
|
||||
|
||||
//
|
||||
bool HasBullishFlow()
|
||||
bool HasOrderFlow()
|
||||
{
|
||||
return HasChild(bullishFlow);
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = HasChild(orderFlow);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int CountBullishFlow()
|
||||
bool HasOrderFlow(
|
||||
ENUM_X_DIRECTION &orderFlowDir //
|
||||
)
|
||||
{
|
||||
return ArraySize(bullishFlow);
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = HasChild(orderFlow);
|
||||
if (result)
|
||||
{
|
||||
orderFlowDir = orderFlow[0].GetDirection();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool HasBearishFlow()
|
||||
int CountOrderFlow()
|
||||
{
|
||||
return HasChild(bearishFlow);
|
||||
return ArraySize(orderFlow);
|
||||
}
|
||||
|
||||
//
|
||||
int CountBearishFlow()
|
||||
int GetSwings(
|
||||
XOBFVGPivot &pivots[] //
|
||||
)
|
||||
{
|
||||
return ArraySize(bearishFlow);
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
Clean(pivots);
|
||||
|
||||
//
|
||||
int count = 0;
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
has = HasOrderFlow();
|
||||
if (!has)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
count = CountOrderFlow();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XOBFVGPivot iPivots[];
|
||||
int iPivotsCount = orderFlow[i]
|
||||
.GetSwings(iPivots);
|
||||
bool hasPivots = IsValidSize(iPivotsCount);
|
||||
if (hasPivots)
|
||||
{
|
||||
//
|
||||
Copy(
|
||||
iPivots,
|
||||
pivots,
|
||||
false //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
Clean(iPivots);
|
||||
}
|
||||
|
||||
//
|
||||
result = ArraySize(pivots);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -542,6 +305,22 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
value = NormalizeTime(value);
|
||||
|
||||
//
|
||||
int count = 0;
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
// Order Flow ...
|
||||
ENUM_X_DIRECTION orderFlowDir;
|
||||
has = HasOrderFlow(orderFlowDir);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
count = CountOrderFlow();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
orderFlow[i].UpdateTo(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -550,18 +329,19 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
|
||||
//
|
||||
int DetectOrderFlow(
|
||||
ENUM_X_DIRECTION forDir,
|
||||
ENUM_X_DIRECTION &orderFlowDir,
|
||||
XPOIState &htfState,
|
||||
XPOIState &mtfState,
|
||||
XPOIState &stfState,
|
||||
int barIndex = 0,
|
||||
ENUM_TIMEFRAMES forPeriod = NULL,
|
||||
XCPOIDrawer *drawer = NULL //
|
||||
XPOIState &stfState //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
Clean(orderFlow);
|
||||
orderFlowDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
bool isValid =
|
||||
//
|
||||
@@ -569,8 +349,7 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
IsValid(period) &&
|
||||
htfState.HasChild() &&
|
||||
mtfState.HasChild() &&
|
||||
stfState.HasChild() &&
|
||||
HasDirection(forDir)
|
||||
stfState.HasChild()
|
||||
//
|
||||
;
|
||||
if (!isValid)
|
||||
@@ -579,27 +358,14 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
}
|
||||
|
||||
//
|
||||
if (forPeriod == NULL)
|
||||
{
|
||||
forPeriod = period;
|
||||
}
|
||||
|
||||
//
|
||||
bool isBullish = IsBullish(forDir);
|
||||
|
||||
//
|
||||
int idx = -1;
|
||||
int count = 0;
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
XOBFVG tmpOBFVGs[];
|
||||
count = ExtractOBFVGZones(
|
||||
// Bullish OBFVGs ...
|
||||
XOBFVG bullOBFVGs[];
|
||||
int bullOBFVGsCount = ExtractOBFVGZones(
|
||||
htfState,
|
||||
mtfState,
|
||||
stfState,
|
||||
tmpOBFVGs,
|
||||
forDir,
|
||||
bullOBFVGs,
|
||||
X_DIRECTION_BULLISH,
|
||||
NULL, // For Period ...
|
||||
//
|
||||
// Start ...
|
||||
@@ -624,169 +390,107 @@ struct X121SMCStrategyXWZSignalConditions
|
||||
//
|
||||
true, // Ignore Inside in Place Filter ...
|
||||
//
|
||||
true, // Detect Inside OB POI(s) ...
|
||||
false, // Detect Inside FVG POI(s) ...
|
||||
true, // Detect Inside OB POI(s) ...
|
||||
true, // Detect Inside FVG POI(s) ...
|
||||
true // Apply From Filter to Selected POI(s) ...
|
||||
);
|
||||
has = IsValidSize(count);
|
||||
if (has)
|
||||
bool hasBullOBFVGs = IsValidSize(bullOBFVGsCount);
|
||||
|
||||
//
|
||||
// Bearish OBFVGs ...
|
||||
XOBFVG bearOBFVGs[];
|
||||
int bearOBFVGsCount = ExtractOBFVGZones(
|
||||
htfState,
|
||||
mtfState,
|
||||
stfState,
|
||||
bearOBFVGs,
|
||||
X_DIRECTION_BEARISH,
|
||||
NULL, // For Period ...
|
||||
//
|
||||
// Start ...
|
||||
XZONE_STATE_PASSED,
|
||||
true, // Force Body Out ...
|
||||
//
|
||||
// Activation ...
|
||||
XZONE_STATE_PASSED,
|
||||
true, // Force Body In ...
|
||||
//
|
||||
// Breaktion ...
|
||||
XZONE_STATE_FAILED,
|
||||
false, // Force Body In ...
|
||||
//
|
||||
// Works ...
|
||||
XZONE_STATE_PASSED,
|
||||
true, // Force Body Out ...
|
||||
//
|
||||
true, // Apply Sort ...
|
||||
true, // From Filter ...
|
||||
true, // Place Filter ...
|
||||
//
|
||||
true, // Ignore Inside in Place Filter ...
|
||||
//
|
||||
true, // Detect Inside OB POI(s) ...
|
||||
true, // Detect Inside FVG POI(s) ...
|
||||
true // Apply From Filter to Selected POI(s) ...
|
||||
);
|
||||
bool hasBearOBFVGs = IsValidSize(bearOBFVGsCount);
|
||||
|
||||
//
|
||||
bool hasOrderBlow = hasBearOBFVGs ||
|
||||
hasBullOBFVGs;
|
||||
if (hasOrderBlow)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
// Vlidate ...
|
||||
bool isValid =
|
||||
//
|
||||
(hasBullOBFVGs &&
|
||||
!hasBearOBFVGs &&
|
||||
bullOBFVGsCount > 1)
|
||||
//
|
||||
||
|
||||
//
|
||||
(hasBearOBFVGs &&
|
||||
!hasBullOBFVGs &&
|
||||
bearOBFVGsCount > 1)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (isValid)
|
||||
{
|
||||
//
|
||||
XOBFVG iOBFVG = tmpOBFVGs[i];
|
||||
iOBFVG.UpdateTo(NULL);
|
||||
|
||||
// //
|
||||
// if (iOBFVG.HasOB())
|
||||
// {
|
||||
// //
|
||||
// XCBaseObject *iObj;
|
||||
// drawer.CreateOrderBlock(
|
||||
// iOBFVG.ob,
|
||||
// iObj //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (stfState.HasSupplyZones())
|
||||
// {
|
||||
// //
|
||||
// for (int j = 0; j < stfState.CountSupplyZones(); j++)
|
||||
// {
|
||||
// //
|
||||
// XCSupplyZone *jZone = stfState.supplyZones[j];
|
||||
|
||||
// //
|
||||
// bool isInside = IsInsideDiff(
|
||||
// jZone,
|
||||
// iOBFVG.ob,
|
||||
// false //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (isInside)
|
||||
// {
|
||||
// //
|
||||
// XCSupplyZoneObject *iObj;
|
||||
// drawer.CreateSupplyZone(
|
||||
// jZone,
|
||||
// iObj //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (stfState.HasDemandZones())
|
||||
// {
|
||||
// //
|
||||
// for (int j = 0; j < stfState.CountDemandZones(); j++)
|
||||
// {
|
||||
// //
|
||||
// XCDemandZone *jZone = stfState.demandZones[j];
|
||||
|
||||
// //
|
||||
// bool isInside = IsInsideDiff(
|
||||
// jZone,
|
||||
// iOBFVG.ob,
|
||||
// false //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (isInside)
|
||||
// {
|
||||
// //
|
||||
// XCDemandZoneObject *iObj;
|
||||
// drawer.CreateDemandZone(
|
||||
// jZone,
|
||||
// iObj //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (stfState.HasSupportZones())
|
||||
// {
|
||||
// //
|
||||
// for (int j = 0; j < stfState.CountSupportZones(); j++)
|
||||
// {
|
||||
// //
|
||||
// XCSupportZone *jZone = stfState.supportZones[j];
|
||||
|
||||
// //
|
||||
// bool isInside = IsInsideDiff(
|
||||
// jZone,
|
||||
// iOBFVG.ob,
|
||||
// false //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (isInside)
|
||||
// {
|
||||
// //
|
||||
// XCSupportZoneObject *iObj;
|
||||
// drawer.CreateSupportZone(
|
||||
// jZone,
|
||||
// iObj //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (stfState.HasResistanceZones())
|
||||
// {
|
||||
// //
|
||||
// for (int j = 0; j < stfState.CountResistanceZones(); j++)
|
||||
// {
|
||||
// //
|
||||
// XCResistanceZone *jZone = stfState.resistanceZones[j];
|
||||
|
||||
// //
|
||||
// bool isInside = IsInsideDiff(
|
||||
// jZone,
|
||||
// iOBFVG.ob,
|
||||
// false //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (isInside)
|
||||
// {
|
||||
// //
|
||||
// XCResistanceZoneObject *iObj;
|
||||
// drawer.CreateResistanceZone(
|
||||
// jZone,
|
||||
// iObj //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
XCBaseObject *drawnObjects[];
|
||||
int drawnObjectsCount = drawer.DrawOBFVG(
|
||||
iOBFVG,
|
||||
drawnObjects,
|
||||
if (hasBullOBFVGs)
|
||||
{
|
||||
//
|
||||
true, // Draw Order Block ...
|
||||
true, // Draw Fair Value Gap ...
|
||||
false, // Draw Supply Zones ...
|
||||
false, // Draw Demand Zones ...
|
||||
false, // Draw Support Zones ...
|
||||
false // Draw Resistance Zones ...
|
||||
);
|
||||
Copy(
|
||||
bullOBFVGs,
|
||||
orderFlow //
|
||||
);
|
||||
}
|
||||
else if (hasBearOBFVGs)
|
||||
{
|
||||
//
|
||||
Copy(
|
||||
bearOBFVGs,
|
||||
orderFlow //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
iOBFVG.Clean();
|
||||
orderFlowDir =
|
||||
hasBullOBFVGs
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
result = ArraySize(orderFlow);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
has = IsValidSize(count);
|
||||
result = count;
|
||||
Clean(bullOBFVGs);
|
||||
Clean(bearOBFVGs);
|
||||
|
||||
//
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user