This commit is contained in:
2025-01-09 13:12:31 +03:30
parent a8ecc92e46
commit 0fd0889413
4 changed files with 388 additions and 376 deletions
+364
View File
@@ -9743,6 +9743,370 @@ double CalculateTarget(
return result; return result;
} }
/**
* Test Market for Detect Order Block FVG ...
*
* @param forDir: Direction
* @param bullishOrderBlocks: Detected Bullish Order Blocks ...
* @param bearishOrderBlocks: Detected Bearish Order Blocks ...
* @param orderBlockState: Order Block Detection POIState ...
* @param fairValueGapState: Fair Value Gap Detection POIState ...
* @param barIndex: Bar Index ...
*
* @return ( bool )
*/
bool DetectFVGOB(
ENUM_X_DIRECTION &forDir, // Test For Specified Direction ...
XFVGOrderBlock &bullishOrderBlocks[], // Bullish Order Blocks ...
XFVGOrderBlock &bearishOrderBlocks[], // Bearish Order Blocks ...
XPOIState &orderBlockState, // Order Block Detection TF POI(s) ...
XPOIState &fairValueGapState, // Fair Value Gap Detection TF POI(s) ...
int barIndex = 0 // Bar Index ...
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
forDir = X_DIRECTION_NONE;
//
// Validate Args ...
result =
orderBlockState.HasChild() &&
fairValueGapState.HasChild();
if (!result)
{
return result;
}
//
string symbol = orderBlockState.symbol;
ENUM_TIMEFRAMES period = orderBlockState.period;
//
// Retrieve Bars ...
XOHCL triggerCBar;
result = triggerCBar.Init(
symbol,
period,
barIndex //
);
//
// Select Order Blocks Which Has Big Changes ...
int count = 0;
datetime cTime = TimeCurrent();
//
XOHCL jBar;
result = jBar.Init(
fairValueGapState.symbol,
fairValueGapState.period,
barIndex //
);
if (!result)
{
return result;
}
double jBarLL = jBar.FindLowest(3, MODE_LOW);
double jBarHH = jBar.FindHighest(3, MODE_HIGH);
//
// Bullish ...
int bullishOrderBlocksCount = orderBlockState.CountBullishOrderBlocks();
count = bullishOrderBlocksCount;
if (IsValidSize(count))
{
//
for (int i = count - 1; i >= 0; i--)
{
//
XCFVG *iFVG = NULL;
XStateZones iStateZones;
XCOrderBlock *iOb = orderBlockState.bullishOrderBlocks[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.CountBullishFairValueGaps();
bool hasFVG = IsValidSize(fvgsCount);
if (!hasFVG)
{
continue;
}
//
// Detect an FVG for Order Block ...
for (int j = fvgsCount - 1; j >= 0; j--)
{
//
XCFVG *jFVG = fairValueGapState.bullishFairValueGaps[j];
//
bool isValid =
//
jFVG.IsBullish() &&
jBarLL > jFVG.Upper() &&
jBar.low > jFVG.Upper() &&
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)
{
continue;
}
// //
// double upper = MathMax(iOb.Upper(), iFVG.Upper());
// double lower = MathMin(iOb.Lower(), iFVG.Lower());
// datetime from = iFVG.From();
// //
// // Detect Price Zones ...
// // Based On Decision State ...
// bool hasStateZones = CalculateStateZones(
// iStateZones,
// decisionState,
// upper,
// lower,
// from //
// );
// result = hasStateZones;
// if (!result)
// {
// continue;
// }
//
XFVGOrderBlock iModel;
iModel.orderBlock = iOb;
iModel.fairValueGap = iFVG;
// iModel.stateZones = iStateZones;
//
AddRef(
iModel,
bullishOrderBlocks //
);
}
}
//
// Bearish ...
int bearishOrderBlocksCount = orderBlockState.CountBearishOrderBlocks();
count = bearishOrderBlocksCount;
if (IsValidSize(count))
{
//
for (int i = count - 1; i >= 0; i--)
{
//
XCFVG *iFVG = NULL;
XStateZones iStateZones;
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;
}
//
// Detect an FVG for Order Block ...
for (int j = fvgsCount - 1; j >= 0; j--)
{
//
XCFVG *jFVG = fairValueGapState.bearishFairValueGaps[j];
//
bool isValid =
//
jFVG.IsBearish() &&
jBarHH < jFVG.Lower() &&
jBar.high < jFVG.Lower() &&
jFVG.From() >= iOb.From() &&
((jFVG.Upper() > iOb.Lower() &&
jFVG.Lower() <= iOb.Lower()) ||
(jFVG.Upper() <= iOb.Upper() &&
jFVG.Lower() >= iOb.Lower()))
//
;
if (isValid)
{
//
jFVG.To(cTime);
iFVG = jFVG;
break;
}
}
//
hasFVG = iFVG != NULL;
result = hasFVG;
if (!result)
{
continue;
}
//
double upper = MathMax(iOb.Upper(), iFVG.Upper());
double lower = MathMin(iOb.Lower(), iFVG.Lower());
datetime from = iFVG.From();
// //
// // Detect Price Zones ...
// // Based On Decision State ...
// bool hasStateZones = CalculateStateZones(
// iStateZones,
// decisionState,
// upper,
// lower,
// from //
// );
// result = hasStateZones;
// if (!result)
// {
// continue;
// }
//
XFVGOrderBlock iModel;
iModel.orderBlock = iOb;
iModel.fairValueGap = iFVG;
// iModel.stateZones = iStateZones;
//
AddRef(
iModel,
bearishOrderBlocks //
);
}
}
//
// Check Order Blocks ...
bullishOrderBlocksCount = ArraySize(bullishOrderBlocks);
bool hasBullishOrderBlocks = IsValidSize(bullishOrderBlocksCount);
//
// Check Order Blocks ...
bearishOrderBlocksCount = ArraySize(bearishOrderBlocks);
bool hasBearishOrderBlocks = IsValidSize(bearishOrderBlocksCount);
//
result =
//
hasBullishOrderBlocks ||
hasBearishOrderBlocks
//
;
if (!result)
{
return result;
}
//
bool isBullish = hasBullishOrderBlocks && !hasBearishOrderBlocks;
bool isBearish = hasBearishOrderBlocks && !hasBullishOrderBlocks;
//
forDir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = forDir != X_DIRECTION_NONE;
if (!result)
{
return result;
}
//
return result;
}
// //
typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event, typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event,
XCBasePOI *param // XCBasePOI *param //
-356
View File
@@ -715,360 +715,4 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
return result; return result;
} }
//
//
bool TestPOIState(
ENUM_X_DIRECTION &forDir, // Test For Specified Direction ...
XFVGOrderBlock &bullishOrderBlocks[], // Bullish Order Blocks ...
XFVGOrderBlock &bearishOrderBlocks[], // Bearish Order Blocks ...
XPOIState &orderBlockState, // Order Block Detection TF POI(s) ...
XPOIState &fairValueGapState, // Fair Value Gap Detection TF POI(s) ...
XPOIState &decisionState, // Decision TF POI(s) ...
int barIndex = 0 // Bar Index ...
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
forDir = X_DIRECTION_NONE;
//
// Validate Args ...
result =
orderBlockState.HasChild() &&
fairValueGapState.HasChild() &&
decisionState.HasChild();
if (!result)
{
return result;
}
//
string symbol = orderBlockState.symbol;
ENUM_TIMEFRAMES period = orderBlockState.period;
//
// Retrieve Bars ...
XOHCL triggerCBar;
result = triggerCBar.Init(
symbol,
period,
barIndex //
);
//
// Select Order Blocks Which Has Big Changes ...
int count = 0;
datetime cTime = TimeCurrent();
//
XOHCL jBar;
result = jBar.Init(
fairValueGapState.symbol,
fairValueGapState.period,
barIndex //
);
if (!result)
{
return result;
}
double jBarLL = jBar.FindLowest(3, MODE_LOW);
double jBarHH = jBar.FindHighest(3, MODE_HIGH);
//
// Bullish ...
int bullishOrderBlocksCount = orderBlockState.CountBullishOrderBlocks();
count = bullishOrderBlocksCount;
if (IsValidSize(count))
{
//
for (int i = count - 1; i >= 0; i--)
{
//
XCFVG *iFVG = NULL;
XStateZones iStateZones;
XCOrderBlock *iOb = orderBlockState.bullishOrderBlocks[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.CountBullishFairValueGaps();
bool hasFVG = IsValidSize(fvgsCount);
if (!hasFVG)
{
continue;
}
//
// Detect an FVG for Order Block ...
for (int j = fvgsCount - 1; j >= 0; j--)
{
//
XCFVG *jFVG = fairValueGapState.bullishFairValueGaps[j];
//
bool isValid =
//
jFVG.IsBullish() &&
jBarLL > jFVG.Upper() &&
jBar.low > jFVG.Upper() &&
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)
{
continue;
}
// //
// double upper = MathMax(iOb.Upper(), iFVG.Upper());
// double lower = MathMin(iOb.Lower(), iFVG.Lower());
// datetime from = iFVG.From();
// //
// // Detect Price Zones ...
// // Based On Decision State ...
// bool hasStateZones = CalculateStateZones(
// iStateZones,
// decisionState,
// upper,
// lower,
// from //
// );
// result = hasStateZones;
// if (!result)
// {
// continue;
// }
//
XFVGOrderBlock iModel;
iModel.orderBlock = iOb;
iModel.fairValueGap = iFVG;
// iModel.stateZones = iStateZones;
//
AddRef(
iModel,
bullishOrderBlocks //
);
}
}
//
// Bearish ...
int bearishOrderBlocksCount = orderBlockState.CountBearishOrderBlocks();
count = bearishOrderBlocksCount;
if (IsValidSize(count))
{
//
for (int i = count - 1; i >= 0; i--)
{
//
XCFVG *iFVG = NULL;
XStateZones iStateZones;
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() &&
jBarHH < jFVG.Lower() &&
jBar.high < jFVG.Lower() &&
jFVG.From() >= iOb.From() &&
((jFVG.Upper() > iOb.Lower() &&
jFVG.Lower() <= iOb.Lower()) ||
(jFVG.Upper() <= iOb.Upper() &&
jFVG.Lower() >= iOb.Lower()))
//
;
if (isValid)
{
//
jFVG.To(cTime);
iFVG = jFVG;
break;
}
}
//
hasFVG = iFVG != NULL;
result = hasFVG;
if (!result)
{
continue;
}
//
double upper = MathMax(iOb.Upper(), iFVG.Upper());
double lower = MathMin(iOb.Lower(), iFVG.Lower());
datetime from = iFVG.From();
// //
// // Detect Price Zones ...
// // Based On Decision State ...
// bool hasStateZones = CalculateStateZones(
// iStateZones,
// decisionState,
// upper,
// lower,
// from //
// );
// result = hasStateZones;
// if (!result)
// {
// continue;
// }
//
XFVGOrderBlock iModel;
iModel.orderBlock = iOb;
iModel.fairValueGap = iFVG;
// iModel.stateZones = iStateZones;
//
AddRef(
iModel,
bearishOrderBlocks //
);
}
}
//
// Check Order Blocks ...
bullishOrderBlocksCount = ArraySize(bullishOrderBlocks);
bool hasBullishOrderBlocks = IsValidSize(bullishOrderBlocksCount);
//
// Check Order Blocks ...
bearishOrderBlocksCount = ArraySize(bearishOrderBlocks);
bool hasBearishOrderBlocks = IsValidSize(bearishOrderBlocksCount);
//
result =
//
hasBullishOrderBlocks ||
hasBearishOrderBlocks
//
;
if (!result)
{
return result;
}
//
bool isBullish = hasBullishOrderBlocks && !hasBearishOrderBlocks;
bool isBearish = hasBearishOrderBlocks && !hasBullishOrderBlocks;
//
forDir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = forDir != X_DIRECTION_NONE;
if (!result)
{
return result;
}
//
return result;
}
// //
@@ -398,13 +398,12 @@ bool DetectX121SMCXTWPVSiganlSetup(
ENUM_X_DIRECTION forDir; ENUM_X_DIRECTION forDir;
XFVGOrderBlock bullishOrderBlocks[]; XFVGOrderBlock bullishOrderBlocks[];
XFVGOrderBlock bearishOrderBlocks[]; XFVGOrderBlock bearishOrderBlocks[];
bool isTested = TestPOIState( bool isTested = DetectFVGOB(
forDir, forDir,
bullishOrderBlocks, bullishOrderBlocks,
bearishOrderBlocks, bearishOrderBlocks,
consolidationState, consolidationState,
analyseState, analyseState //
decisionState //
); );
// //
@@ -671,6 +670,10 @@ bool DetectX121SMCXTWPVSiganlTrigger(
double decisionVale = decisionConditions.x121Conditions.valesBuffer[1]; double decisionVale = decisionConditions.x121Conditions.valesBuffer[1];
double isNewDecisionVale = decisionConditions.x121Conditions.isNewVale; double isNewDecisionVale = decisionConditions.x121Conditions.isNewVale;
//
bool isTriggerRSICrossedOverOverSold = triggerConditions.x121Conditions.isRSICrossedOverOverSold;
bool isTriggerRSICrossedUnderOverBought = triggerConditions.x121Conditions.isRSICrossedUnderOverBought;
// //
bool isDecisionRSICrossedOverOverSold = decisionConditions.x121Conditions.isRSICrossedOverOverSold; bool isDecisionRSICrossedOverOverSold = decisionConditions.x121Conditions.isRSICrossedOverOverSold;
bool isDecisionRSICrossedUnderOverBought = decisionConditions.x121Conditions.isRSICrossedUnderOverBought; bool isDecisionRSICrossedUnderOverBought = decisionConditions.x121Conditions.isRSICrossedUnderOverBought;
@@ -716,8 +719,10 @@ bool DetectX121SMCXTWPVSiganlTrigger(
isBullish && isBullish &&
cBar.IsBullish() && cBar.IsBullish() &&
decisionVale < fvgOBUpper && decisionVale < fvgOBUpper &&
decisionVale > fvgOBLower && decisionVale > fvgOBLower
isDecisionRSICrossedOverOverSold; // &&
// isTriggerRSICrossedOverOverSold
;
// //
// Detect Bearish Conditions ... // Detect Bearish Conditions ...
@@ -725,8 +730,10 @@ bool DetectX121SMCXTWPVSiganlTrigger(
isBearish && isBearish &&
cBar.IsBearish() && cBar.IsBearish() &&
decisionPeak < fvgOBUpper && decisionPeak < fvgOBUpper &&
decisionPeak > fvgOBLower && decisionPeak > fvgOBLower
isDecisionRSICrossedUnderOverBought; // &&
// isTriggerRSICrossedUnderOverBought
;
// //
result = isBullish || result = isBullish ||
@@ -893,7 +900,8 @@ bool DetectX121SMCXTWPVSiganlTrigger(
// //
int AddX121SMCXTWPVConditionsIfNotExists( int AddX121SMCXTWPVConditionsIfNotExists(
X121SMCStrategyXTWPVSignalConditions &item, X121SMCStrategyXTWPVSignalConditions &item,
X121SMCStrategyXTWPVSignalConditions &items[] // X121SMCStrategyXTWPVSignalConditions &items[],
int maxAllowed = 10 //
) )
{ {
// //
@@ -946,6 +954,10 @@ int AddX121SMCXTWPVConditionsIfNotExists(
// //
// Remove Olds ... // Remove Olds ...
CleanupArray(
items,
maxAllowed //
);
// //
result = ArraySize(items); result = ArraySize(items);
@@ -583,14 +583,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
// //
mXTWPVConditions.Clean(); mXTWPVConditions.Clean();
//
// Try to Normalize Conditions Collection ...
int maxAllowed = 6;
CleanupArray(
mXTWPVConditionsCollection,
maxAllowed //
);
} }
} }
@@ -648,10 +640,10 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
// Check Broken Order Blocks and Remove them ... // Check Broken Order Blocks and Remove them ...
bool isBreaked = bool isBreaked =
isBullish isBullish
? (cBar.close < iLower || ? (cBar.high < iLower ||
pBar.close < iLower) pBar.high < iLower)
: (cBar.close > iUpper || : (cBar.low > iUpper ||
cBar.close > iUpper); cBar.low > iUpper);
if (isBreaked) if (isBreaked)
{ {
// //