This commit is contained in:
2025-01-07 02:57:14 +03:30
parent 65b7a2ca7f
commit 3d95220cc7
3 changed files with 392 additions and 22 deletions
+157
View File
@@ -2280,6 +2280,80 @@ class XCOrderBlock : public XCBarZone
return result; return result;
} }
/**
* Check Order Block Validation ...
*
* @return ( bool )
*/
bool IsValidOrderBlock()
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
XOHCL breakerBar;
result = DetectBreakerBar(breakerBar);
if (!result)
{
return result;
}
int breakerBarIndex = breakerBar.Index();
//
XOHCL huntedBar;
bool isHunted = IsHunted(huntedBar);
result = !isHunted;
if (!result)
{
return result;
}
//
bool isBullish = IsBullish();
//
for (int i = breakerBarIndex - 1; i >= 0; i--)
{
//
XOHCL iBar;
result = iBar.Init(
breakerBar.symbol,
breakerBar.period,
i //
);
if (!result)
{
continue;
}
//
double price =
isBullish
? iBar.low
: iBar.high;
//
result =
isBullish
? price > Upper()
: price < Lower();
if (!result)
{
return result;
}
}
//
return result;
}
// //
// Overrides ... // Overrides ...
@@ -6050,6 +6124,89 @@ struct XMarketStructure
// //
}; };
struct XFVGOrderBlock
{
//
// Props ...
XCOrderBlock *orderBlock;
XCFVG *fairValueGap;
//
XFVGOrderBlock()
{
Clean();
}
/**
* Cleanup Model ...
*/
void Clean()
{
//
orderBlock = NULL;
fairValueGap = NULL;
}
/**
* Validate Model ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
orderBlock != NULL &&
fairValueGap != NULL &&
((orderBlock.IsBullish() &&
fairValueGap.IsBullish()) ||
((orderBlock.IsBearish() &&
fairValueGap.IsBearish())))
//
;
//
return result;
}
/**
* Get Model Direction ...
*
* @param dir: ENUM_X_DIRECTION member ...
*
* @return ( bool )
*/
bool GetDirection(
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
result = IsValid();
if (!result)
{
return result;
}
//
dir = orderBlock.IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
};
// //
// Extensions ... // Extensions ...
+220 -20
View File
@@ -720,11 +720,13 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
// //
bool TestPOIState( bool TestPOIState(
XCPOIDrawer *drawer, XCPOIDrawer *drawer,
ENUM_X_DIRECTION forDir, // Test For Specified Direction ... ENUM_X_DIRECTION &forDir, // Test For Specified Direction ...
XPOIState &biggerState, // Bigger TF POI(s) ... XFVGOrderBlock &bullishOrderBlocks[], // Bullish Order Blocks ...
XPOIState &midState, // Mid TF POI(s) ... XFVGOrderBlock &bearishOrderBlocks[], // Bearish Order Blocks ...
XPOIState &triggerState, // Trigger TF POI(s) ... XPOIState &orderBlockState, // Order Block Detection TF POI(s) ...
int barIndex = 0 // Bar Index ... XPOIState &fairValueGapState, // Fair Value Gap Detection TF POI(s) ...
XPOIState &triggerState, // Trigger TF POI(s) ...
int barIndex = 0 // Bar Index ...
) )
{ {
// //
@@ -736,13 +738,15 @@ bool TestPOIState(
barIndex = 0; barIndex = 0;
} }
//
forDir = X_DIRECTION_NONE;
// //
// Validate Args ... // Validate Args ...
result = result =
drawer != NULL && drawer != NULL &&
HasDirection(forDir) && orderBlockState.HasChild() &&
biggerState.HasChild() && fairValueGapState.HasChild() &&
midState.HasChild() &&
triggerState.HasChild(); triggerState.HasChild();
if (!result) if (!result)
{ {
@@ -750,8 +754,8 @@ bool TestPOIState(
} }
// //
string symbol = biggerState.symbol; string symbol = orderBlockState.symbol;
ENUM_TIMEFRAMES period = biggerState.period; ENUM_TIMEFRAMES period = orderBlockState.period;
// //
// Retrieve Bars ... // Retrieve Bars ...
@@ -769,8 +773,7 @@ bool TestPOIState(
// //
// Bullish ... // Bullish ...
XCOrderBlock *bullishOrderBlocks[]; int bullishOrderBlocksCount = orderBlockState.CountBullishOrderBlocks();
int bullishOrderBlocksCount = biggerState.CountBullishOrderBlocks();
count = bullishOrderBlocksCount; count = bullishOrderBlocksCount;
if (IsValidSize(count)) if (IsValidSize(count))
{ {
@@ -778,7 +781,8 @@ bool TestPOIState(
for (int i = count - 1; i >= 0; i--) for (int i = count - 1; i >= 0; i--)
{ {
// //
XCOrderBlock *iOb = biggerState.bullishOrderBlocks[i]; XCFVG *iFVG = NULL;
XCOrderBlock *iOb = orderBlockState.bullishOrderBlocks[i];
iOb.To(cTime); iOb.To(cTime);
// //
@@ -794,10 +798,74 @@ bool TestPOIState(
// Detect Order Block is Hunted Or Not ... // Detect Order Block is Hunted Or Not ...
XOHCL huntedBar; XOHCL huntedBar;
bool isHunted = iOb.IsHunted(huntedBar); bool isHunted = iOb.IsHunted(huntedBar);
if (isHunted) { if (isHunted)
{
continue; continue;
} }
//
// Check Validation of Order Block ...
bool isValid = iOb.IsValidOrderBlock();
if (!isValid)
{
continue;
}
//
// Check Order Block Has Fair Value Gap ...
int fvgsCount = fairValueGapState.CountBullishFairValueGaps();
bool hasFVG = IsValidSize(fvgsCount);
if (!hasFVG)
{
continue;
}
//
for (int j = fvgsCount - 1; j >= 0; j--)
{
//
XCFVG *jFVG = fairValueGapState.bullishFairValueGaps[j];
//
bool isValid =
//
jFVG.IsBullish()
// &&
// jFVG.From() > iOb.From() &&
// ((jFVG.Upper() > iOb.Upper() &&
// jFVG.Lower() <= iOb.Upper()) ||
// (jFVG.Upper() <= iOb.Upper() &&
// jFVG.Lower() >= iOb.Lower()))
//
;
if (isValid)
{
//
jFVG.To(cTime);
iFVG = jFVG;
break;
}
}
//
hasFVG = iFVG != NULL;
result = hasFVG;
if (!result)
{
return result;
}
//
XFVGOrderBlock iModel;
iModel.orderBlock = iOb;
iModel.fairValueGap = iFVG;
//
AddRef(
iModel,
bullishOrderBlocks //
);
// //
XCBullishOrderBlockObject *iOBObject; XCBullishOrderBlockObject *iOBObject;
bool isInited = drawer.CreateBullishOrderBlock( bool isInited = drawer.CreateBullishOrderBlock(
@@ -817,15 +885,13 @@ bool TestPOIState(
); );
if (isInited) if (isInited)
{ {
Print("");
} }
} }
} }
// //
// Bearish ... // Bearish ...
XCOrderBlock *bearishOrderBlocks[]; int bearishOrderBlocksCount = orderBlockState.CountBearishOrderBlocks();
int bearishOrderBlocksCount = biggerState.CountBearishOrderBlocks();
count = bearishOrderBlocksCount; count = bearishOrderBlocksCount;
if (IsValidSize(count)) if (IsValidSize(count))
{ {
@@ -833,15 +899,127 @@ bool TestPOIState(
for (int i = count - 1; i >= 0; i--) for (int i = count - 1; i >= 0; i--)
{ {
// //
XCOrderBlock *iOb = biggerState.bearishOrderBlocks[i]; XCFVG *iFVG = NULL;
XCOrderBlock *iOb = orderBlockState.bearishOrderBlocks[i];
iOb.To(cTime);
//
// Find Exit Bar of Bullish OrderBlock Upper ...
XOHCL breakerBar;
bool hasBreakerBar = iOb.DetectBreakerBar(breakerBar);
if (!hasBreakerBar)
{
continue;
}
//
// Detect Order Block is Hunted Or Not ...
XOHCL huntedBar;
bool isHunted = iOb.IsHunted(huntedBar);
if (isHunted)
{
continue;
}
//
// Check Validation of Order Block ...
bool isValid = iOb.IsValidOrderBlock();
if (!isValid)
{
continue;
}
//
// Check Order Block Has Fair Value Gap ...
int fvgsCount = fairValueGapState.CountBearishFairValueGaps();
bool hasFVG = IsValidSize(fvgsCount);
if (!hasFVG)
{
continue;
}
//
for (int j = fvgsCount - 1; j >= 0; j--)
{
//
XCFVG *jFVG = fairValueGapState.bearishFairValueGaps[j];
//
bool isValid =
//
jFVG.IsBearish()
// &&
// jFVG.From() > iOb.From() &&
// jFVG.Upper() > iOb.Lower() &&
// jFVG.Lower() <= iOb.Lower()
//
;
if (isValid)
{
//
jFVG.To(cTime);
iFVG = jFVG;
break;
}
}
//
hasFVG = iFVG != NULL;
result = hasFVG;
if (!result)
{
return result;
}
//
XFVGOrderBlock iModel;
iModel.orderBlock = iOb;
iModel.fairValueGap = iFVG;
//
AddRef(
iModel,
bullishOrderBlocks //
);
//
XCBearishOrderBlockObject *iOBObject;
bool isInited = drawer.CreateBearishOrderBlock(
iOb,
iOBObject //
);
if (isInited)
{
}
//
XCOHCLObject *iBarObj;
isInited = drawer.CreateBar(
breakerBar,
iBarObj,
cTime //
);
if (isInited)
{
}
} }
} }
//
// Check Order Blocks ...
bullishOrderBlocksCount = ArraySize(bullishOrderBlocks);
bool hasBullishOrderBlocks = IsValidSize(bullishOrderBlocksCount);
//
// Check Order Blocks ...
bearishOrderBlocksCount = ArraySize(bearishOrderBlocks);
bool hasBearishOrderBlocks = IsValidSize(bearishOrderBlocksCount);
// //
result = result =
// //
IsValidSize(bullishOrderBlocksCount) || hasBullishOrderBlocks ||
IsValidSize(bearishOrderBlocksCount) hasBearishOrderBlocks
// //
; ;
if (!result) if (!result)
@@ -849,6 +1027,28 @@ bool TestPOIState(
return result; return result;
} }
//
bool isBullish = hasBullishOrderBlocks && !hasBearishOrderBlocks;
bool isBearish = hasBearishOrderBlocks && !hasBullishOrderBlocks;
bool isAll = hasBullishOrderBlocks && hasBearishOrderBlocks;
//
forDir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: isAll
? X_DIRECTION_ALL
: X_DIRECTION_NONE;
//
result = forDir != X_DIRECTION_NONE;
if (!result)
{
return result;
}
// //
return result; return result;
} }
@@ -48,6 +48,11 @@ struct X121SMCStrategyXTWPVSignalConditions
datetime setupTime; datetime setupTime;
datetime triggerTime; datetime triggerTime;
//
// ENUM_X_DIRECTION orderBlockDir;
// XCOrderBlock *bullishOrderBlocks[];
// XCOrderBlock *bearishOrderBlocks[];
// //
// Constructor ... // Constructor ...
X121SMCStrategyXTWPVSignalConditions() X121SMCStrategyXTWPVSignalConditions()
@@ -163,6 +168,9 @@ struct X121SMCStrategyXTWPVSignalConditions
void ExtensionClean() void ExtensionClean()
{ {
// //
// Clean(bullishOrderBlocks);
// Clean(bearishOrderBlocks);
// orderBlockDir = X_DIRECTION_NONE;
} }
// //
@@ -381,9 +389,14 @@ bool DetectX121SMCXTWPVSiganlSetup(
// Setup Conditions ... // Setup Conditions ...
// //
bool isBullishTested = TestPOIState( ENUM_X_DIRECTION forDir;
XFVGOrderBlock bullishOrderBlocks[];
XFVGOrderBlock bearishOrderBlocks[];
bool isTested = TestPOIState(
drawer, drawer,
X_DIRECTION_BULLISH, forDir,
bullishOrderBlocks,
bearishOrderBlocks,
consolidationState, consolidationState,
analyseState, analyseState,
decisionState // decisionState //