From 974a516bec08f95754aea90e6b70f1ec1db61cd2 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 26 Jan 2025 20:10:44 +0330 Subject: [PATCH] last ... --- Documents/BKP/1/1.coes.mq5 | 230 +++ Helpers/x-saherelm.x121.helper.mq5 | 16 +- Helpers/x-saherelm.x121.xhk.helper.mq5 | 20 +- Libraries/x-saherelm.x-poi.lib.mq5 | 954 ++++++++++-- .../x-121.smc.market.cycle.helper.class.mq5 | 893 ++++++++++- X121SMCEA/Libraries/x-121.smc.lib.mq5 | 370 +++++ X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 | 5 +- .../Signals/x-121.smc.xhkpv.signal.lib.mq5 | 1324 +++++++++++++++++ .../Signals/x-121.smc.xobpv.signal.lib.mq5 | 242 ++- .../Strategy/x-121.smc.strategy.class.mq5 | 251 +++- 10 files changed, 4144 insertions(+), 161 deletions(-) create mode 100644 Documents/BKP/1/1.coes.mq5 create mode 100644 X121SMCEA/Signals/x-121.smc.xhkpv.signal.lib.mq5 diff --git a/Documents/BKP/1/1.coes.mq5 b/Documents/BKP/1/1.coes.mq5 new file mode 100644 index 00000000..ef24d3bf --- /dev/null +++ b/Documents/BKP/1/1.coes.mq5 @@ -0,0 +1,230 @@ + // + // Draw ... + // + + // + XCBaseObject *drawnObjects[]; + + // + if (hasBullishOBs) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + // + XCOrderBlock *iOb = conditions.bullishOBs[i]; + + // + XCBullishOrderBlockObject *iObObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + if (hasBearishOBs) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + // + XCOrderBlock *iOb = conditions.bearishOBs[i]; + + // + XCBearishOrderBlockObject *iObObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + if (hasBullishFVGs) + { + // + for (int i = 0; i < bullishFVGsCount; i++) + { + // + XCFVG *iFVG = conditions.bullishFVGs[i]; + + // + XCBullishFairValueGapObject *iFVGObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateBullishFairValueGap( + iFVG, + iFVGObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + } + + // + if (hasBearishFVGs) + { + // + for (int i = 0; i < bearishFVGsCount; i++) + { + // + XCFVG *iFVG = conditions.bearishFVGs[i]; + + // + XCBearishFairValueGapObject *iFVGObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateBearishFairValueGap( + iFVG, + iFVGObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + } + + // + if (hasSupportZones) + { + // + for (int i = 0; i < supportZonesCount; i++) + { + // + XCSupportZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateSupportZone( + conditions.supportZones[i], + iObj // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + if (hasResistanceZones) + { + // + for (int i = 0; i < resistanceZonesCount; i++) + { + // + XCResistanceZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateResistanceZone( + conditions.resistanceZones[i], + iObj // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + if (hasDemandZones) + { + // + for (int i = 0; i < demandZonesCount; i++) + { + // + XCDemandZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateDemandZone( + conditions.demandZones[i], + iObj // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + if (hasSupplyZones) + { + // + for (int i = 0; i < supplyZonesCount; i++) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateSupplyZone( + conditions.supplyZones[i], + iObj // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // + // diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index 26266a63..aae791b3 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -386,11 +386,11 @@ struct X121Conditions bool isRejectedDownRawHK; bool isRawHKBreakedUpSMHK; bool isRawHKClosedOverSMHK; - bool isSMHKSwitchedBearish; - bool isRawHKSwitchedBearish; bool isRawHKClosedUnderSMHK; bool isRawHKBreakedDownSMHK; bool isSMHKSwitchedToBullish; + bool isSMHKSwitchedToBearish; + bool isRawHKSwitchedToBearish; bool isRawHKSwitchedToBullish; // @@ -945,8 +945,8 @@ struct X121Conditions isRejectedDownRawHK = false; isRawHKBreakedUpSMHK = false; isRawHKClosedOverSMHK = false; - isSMHKSwitchedBearish = false; - isRawHKSwitchedBearish = false; + isSMHKSwitchedToBearish = false; + isRawHKSwitchedToBearish = false; isRawHKClosedUnderSMHK = false; isRawHKBreakedDownSMHK = false; isSMHKSwitchedToBullish = false; @@ -1321,8 +1321,8 @@ struct X121Conditions ToString("isRejectedDownRawHK", isRejectedDownRawHK, ignoreFalseConditions, separator) + ToString("isRawHKBreakedUpSMHK", isRawHKBreakedUpSMHK, ignoreFalseConditions, separator) + ToString("isRawHKClosedOverSMHK", isRawHKClosedOverSMHK, ignoreFalseConditions, separator) + - ToString("isSMHKSwitchedBearish", isSMHKSwitchedBearish, ignoreFalseConditions, separator) + - ToString("isRawHKSwitchedBearish", isRawHKSwitchedBearish, ignoreFalseConditions, separator) + + ToString("isSMHKSwitchedToBearish", isSMHKSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isRawHKSwitchedToBearish", isRawHKSwitchedToBearish, ignoreFalseConditions, separator) + ToString("isRawHKClosedUnderSMHK", isRawHKClosedUnderSMHK, ignoreFalseConditions, separator) + ToString("isRawHKBreakedDownSMHK", isRawHKBreakedDownSMHK, ignoreFalseConditions, separator) + ToString("isSMHKSwitchedToBullish", isSMHKSwitchedToBullish, ignoreFalseConditions, separator) + @@ -2206,8 +2206,8 @@ class XCX121Helper : public XCBase conditions.isRejectedDownRawHK = xhkConditions.isRejectedDownRawHK; conditions.isRawHKBreakedUpSMHK = xhkConditions.isRawHKBreakedUpSMHK; conditions.isRawHKClosedOverSMHK = xhkConditions.isRawHKClosedOverSMHK; - conditions.isSMHKSwitchedBearish = xhkConditions.isSMHKSwitchedBearish; - conditions.isRawHKSwitchedBearish = xhkConditions.isRawHKSwitchedBearish; + conditions.isSMHKSwitchedToBearish = xhkConditions.isSMHKSwitchedToBearish; + conditions.isRawHKSwitchedToBearish = xhkConditions.isRawHKSwitchedToBearish; conditions.isRawHKClosedUnderSMHK = xhkConditions.isRawHKClosedUnderSMHK; conditions.isRawHKBreakedDownSMHK = xhkConditions.isRawHKBreakedDownSMHK; conditions.isSMHKSwitchedToBullish = xhkConditions.isSMHKSwitchedToBullish; diff --git a/Helpers/x-saherelm.x121.xhk.helper.mq5 b/Helpers/x-saherelm.x121.xhk.helper.mq5 index 8112ebae..03160cf0 100644 --- a/Helpers/x-saherelm.x121.xhk.helper.mq5 +++ b/Helpers/x-saherelm.x121.xhk.helper.mq5 @@ -163,8 +163,8 @@ struct X121XHKConditions // bool isSMHKBearish; bool isRawHKBearish; - bool isSMHKSwitchedBearish; - bool isRawHKSwitchedBearish; + bool isSMHKSwitchedToBearish; + bool isRawHKSwitchedToBearish; // bool isClosedOverSMHK; @@ -246,8 +246,8 @@ struct X121XHKConditions // isSMHKBearish = false; isRawHKBearish = false; - isSMHKSwitchedBearish = false; - isRawHKSwitchedBearish = false; + isSMHKSwitchedToBearish = false; + isRawHKSwitchedToBearish = false; // isClosedOverSMHK = false; @@ -350,8 +350,8 @@ struct X121XHKConditions ToString("isRawHKSwitchedToBullish", isRawHKSwitchedToBullish, ignoreFalseConditions, separator) + ToString("isSMHKBearish", isSMHKBearish, ignoreFalseConditions, separator) + ToString("isRawHKBearish", isRawHKBearish, ignoreFalseConditions, separator) + - ToString("isSMHKSwitchedBearish", isSMHKSwitchedBearish, ignoreFalseConditions, separator) + - ToString("isRawHKSwitchedBearish", isRawHKSwitchedBearish, ignoreFalseConditions, separator) + + ToString("isSMHKSwitchedToBearish", isSMHKSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isRawHKSwitchedToBearish", isRawHKSwitchedToBearish, ignoreFalseConditions, separator) + ToString("isClosedOverSMHK", isClosedOverSMHK, ignoreFalseConditions, separator) + ToString("isClosedUnderSMHK", isClosedUnderSMHK, ignoreFalseConditions, separator) + ToString("isClosedOverRawHK", isClosedOverRawHK, ignoreFalseConditions, separator) + @@ -1211,9 +1211,9 @@ class XCX121XHKHelper : public XCBaseHelper bool isRawHKBearishPrev = rawHKOpenPrev > rawHKClosePrev; // - bool isSMHKSwitchedBearish = isSMHKBearish && + bool isSMHKSwitchedToBearish = isSMHKBearish && !isSMHKBearishPrev; - bool isRawHKSwitchedBearish = isRawHKBearish && + bool isRawHKSwitchedToBearish = isRawHKBearish && !isRawHKBearishPrev; // @@ -1297,8 +1297,8 @@ class XCX121XHKHelper : public XCBaseHelper conditions.isRawHKSwitchedToBullish = isRawHKSwitchedToBullish; conditions.isSMHKBearish = isSMHKBearish; conditions.isRawHKBearish = isRawHKBearish; - conditions.isSMHKSwitchedBearish = isSMHKSwitchedBearish; - conditions.isRawHKSwitchedBearish = isRawHKSwitchedBearish; + conditions.isSMHKSwitchedToBearish = isSMHKSwitchedToBearish; + conditions.isRawHKSwitchedToBearish = isRawHKSwitchedToBearish; conditions.isClosedOverSMHK = isClosedOverSMHK; conditions.isClosedUnderSMHK = isClosedUnderSMHK; conditions.isClosedOverRawHK = isClosedOverRawHK; diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 049be861..340b49ef 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -6483,6 +6483,79 @@ struct XFVGOrderBlock // }; +struct XBoxZone +{ + // + // Props ... + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + string type; + ENUM_X_DIRECTION dir; + + // + // Constructor ... + XBoxZone() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + dir = X_DIRECTION_NONE; + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + upper > 0 && + lower > 0 && + from < to && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } +}; + // // Extensions ... @@ -10618,7 +10691,7 @@ double CalculateTarget( * * @return ( int ) */ -int DetectDirectionOrderBlocks( +int DetectValidOrderBlocks( ENUM_X_DIRECTION forDir, XPOIState &source, XCOrderBlock *&orderBlocks[] // @@ -10681,10 +10754,13 @@ int DetectDirectionOrderBlocks( // // Check Order Block Validation ... isValid = IsValid( - iOB, forDir, cBar.symbol, - cBar.period // + cBar.period, + iOB.Upper(), + iOB.Lower(), + iOB.From(), + iOB.To() // ); if (isValid) { @@ -10717,10 +10793,13 @@ int DetectDirectionOrderBlocks( // // Check Order Block Validation ... isValid = IsValid( - iOB, forDir, cBar.symbol, - cBar.period // + cBar.period, + iOB.Upper(), + iOB.Lower(), + iOB.From(), + iOB.To() // ); if (isValid) { @@ -10740,6 +10819,690 @@ int DetectDirectionOrderBlocks( return result; } +/** + * Detect Valid Fair Value Gaps ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param source: XPOIState instance Reference ... + * + * @return ( int ) + */ +int DetectValidFairValueGaps( + ENUM_X_DIRECTION forDir, + XPOIState &source, + XCFVG *&fairValueGaps[] // +) +{ + // + int result = 0; + + // + Clean(fairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + HasDirection(forDir) + // + ; + if (!isValid) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + + // + XOHCL cBar; + bool isInited = cBar.Init( + source.symbol, + source.period, + 1 // + ); + if (!isInited) + { + return result; + } + + // + int count = 0; + + // + // Bullish ... + count = source.CountBullishFairValueGaps(); + isValid = IsValidSize(count) && + IsBullish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = source.bullishFairValueGaps[i]; + + // + // Update FVG Time ... + iFVG.To(cTime); + + // + // Check FVG Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iFVG.Upper(), + iFVG.Lower(), + iFVG.From(), + iFVG.To() // + ); + if (isValid) + { + // + Add( + iFVG, + fairValueGaps // + ); + } + } + } + + // + // Bearish ... + count = source.CountBearishFairValueGaps(); + isValid = IsValidSize(count) && + IsBearish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = source.bearishFairValueGaps[i]; + + // + // Update Order Block Time ... + iFVG.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iFVG.Upper(), + iFVG.Lower(), + iFVG.From(), + iFVG.To() // + ); + if (isValid) + { + // + Add( + iFVG, + fairValueGaps // + ); + } + } + } + + // + result = ArraySize(fairValueGaps); + + // + return result; +} + +/** + * Detect Valid Support Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidSupportZones( + XPOIState &source, + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCSupportZone *&supportZones[] // +) +{ + // + int result = 0; + + // + Clean(supportZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bullishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supportZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bullishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supportZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(supportZones); + + // + return result; +} + +/** + * Detect Valid Resistance Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidResistanceZones( + XPOIState &source, + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCResistanceZone *&resistanceZones[] // +) +{ + // + int result = 0; + + // + Clean(resistanceZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bearishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + resistanceZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bearishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + resistanceZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(resistanceZones); + + // + return result; +} + +/** + * Detect Valid Support Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidDemandZones( + XPOIState &source, + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCDemandZone *&demandZones[] // +) +{ + // + int result = 0; + + // + Clean(demandZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountDemandZones(); + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bullishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + demandZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bullishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + demandZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(demandZones); + + // + return result; +} + +/** + * Detect Valid Resistance Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidSupplyZones( + XPOIState &source, + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCSupplyZone *&supplyZones[] // +) +{ + // + int result = 0; + + // + Clean(supplyZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountSupplyZones(); + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bearishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supplyZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bearishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supplyZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(supplyZones); + + // + return result; +} + /** * Test Market for Detect Order Block FVG ... * @@ -11123,7 +11886,10 @@ bool HasBreakerBar( ENUM_X_DIRECTION forDir, string symbol, ENUM_TIMEFRAMES period, - XCZone *zone // + double upper, + double lower, + datetime from, + datetime to // ) { // @@ -11137,10 +11903,16 @@ bool HasBreakerBar( // result = // - zone != NULL && - IsValid(zone.To()) && - IsValid(zone.From()) && - HasDirection(forDir); + upper > 0 && + lower > 0 && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + HasDirection(forDir) + // + ; if (!result) { return result; @@ -11150,7 +11922,7 @@ bool HasBreakerBar( result = fromBar.Init( symbol, period, - zone.From() // + from // ); if (!result) { @@ -11161,7 +11933,7 @@ bool HasBreakerBar( result = toBar.Init( symbol, period, - zone.To() // + to // ); if (!result) { @@ -11172,10 +11944,6 @@ bool HasBreakerBar( int toIndex = toBar.Index(); int fromIndex = fromBar.Index(); - // - double upper = zone.Upper(); - double lower = zone.Lower(); - // // Detect Zone BreakerBar ... for (int i = fromIndex; i >= toIndex; i--) @@ -11227,21 +11995,23 @@ bool HasBreakerBar( } /** - * Check a Zone is Valid for Specified Direction ... + * Validate Specified Order Block ... * - * @param toBar: XOHCL instance Reference ... - * @param fromBar: XOHCL instance Reference ... - * @param breakerBar: XOHCL instance Reference ... * @param forDir: ENUM_X_DIRECTION member ... + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... * * @return ( bool ) */ bool IsValid( - XOHCL &toBar, - XOHCL &fromBar, - XOHCL &breakerBar, ENUM_X_DIRECTION forDir, - XCZone *zone // + string symbol, + ENUM_TIMEFRAMES period, + double upper, + double lower, + datetime from, + datetime to, + bool ignoreBreakerBar = false // ) { // @@ -11249,11 +12019,13 @@ bool IsValid( // result = - // - zone != NULL && - toBar.IsValid() && - fromBar.IsValid() && - breakerBar.IsValid() && + upper > 0 && + lower > 0 && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && HasDirection(forDir) // ; @@ -11262,15 +12034,65 @@ bool IsValid( return result; } + // + XOHCL toBar; + XOHCL fromBar; + XOHCL breakerBar; + + // + if (!ignoreBreakerBar) + { + // + result = HasBreakerBar( + toBar, + fromBar, + breakerBar, + forDir, + symbol, + period, + upper, + lower, + from, + to // + ); + if (!result) + { + return result; + } + } + else + { + // + result = toBar.Init( + symbol, + period, + to // + ); + if (!result) + { + return result; + } + + // + result = fromBar.Init( + symbol, + period, + from // + ); + if (!result) + { + return result; + } + + // + breakerBar = fromBar; + } + // int toIndex = toBar.Index(); int fromIndex = fromBar.Index(); int breakerIndex = breakerBar.Index(); - // - double upper = zone.Upper(); - double lower = zone.Lower(); - // bool isBreaked = false; for (int i = breakerIndex - 1; i >= toIndex; i--) @@ -11316,72 +12138,6 @@ bool IsValid( return result; } -/** - * Validate Specified Order Block ... - * - * @param forDir: ENUM_X_DIRECTION member ... - * @param symbol: String ... - * @param period: ENUM_TIMEFRAMES member ... - * - * @return ( bool ) - */ -bool IsValid( - XCOrderBlock *orderBlock, - ENUM_X_DIRECTION forDir, - string symbol, - ENUM_TIMEFRAMES period // -) -{ - // - bool result = false; - - // - result = - // - IsValid(symbol) && - IsValid(period) && - orderBlock != NULL && - HasDirection(forDir) && - orderBlock.IsValid() - // - ; - if (!result) - { - return result; - } - - // - XOHCL toBar; - XOHCL fromBar; - XOHCL breakerBar; - result = HasBreakerBar( - toBar, - fromBar, - breakerBar, - forDir, - symbol, - period, - (XCZone *)orderBlock // - ); - if (!result) - { - return result; - } - - // - // Validate Zone Touch ... - result = IsValid( - toBar, - fromBar, - breakerBar, - forDir, - (XCZone *)orderBlock // - ); - - // - return result; -} - /** * Get Oldest Zone ... * diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index e6e98d90..c648d692 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -572,7 +572,7 @@ class XC121SMCCycleHelper : public XCBase /** * Detect Order Blocks ... * - * @return ( int ) + * @return ( bool ) */ bool DetectOrderBlocks( XCOrderBlock *&bullishOrderBlocks[], @@ -597,14 +597,14 @@ class XC121SMCCycleHelper : public XCBase } // - int bullOBsCount = DetectDirectionOrderBlocks( + int bullOBsCount = DetectValidOrderBlocks( X_DIRECTION_BULLISH, state, bullishOrderBlocks // ); // - int bearOBsCount = DetectDirectionOrderBlocks( + int bearOBsCount = DetectValidOrderBlocks( X_DIRECTION_BEARISH, state, bearishOrderBlocks // @@ -618,6 +618,611 @@ class XC121SMCCycleHelper : public XCBase return result; } + /** + * Detect Fair Value Gaps ... + * + * @return ( bool ) + */ + bool DetectFairValueGaps( + XCFVG *&bullishFairValueGaps[], + XCFVG *&bearishFairValueGaps[] // + ) + { + // + bool result = false; + + // + Clean(bullishFairValueGaps); + Clean(bearishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild(); + if (!isValid) + { + return result; + } + + // + int bullFVGsCount = DetectValidFairValueGaps( + X_DIRECTION_BULLISH, + state, + bullishFairValueGaps // + ); + + // + int bearFVGsCount = DetectValidFairValueGaps( + X_DIRECTION_BEARISH, + state, + bearishFairValueGaps // + ); + + // + result = IsValidSize(bullFVGsCount + + bearFVGsCount); + + // + return result; + } + + /** + * Detect Support Zones ... + * + * @return ( bool ) + */ + bool DetectSupportZones( + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCSupportZone *&supportZones[] // + ) + { + // + bool result = false; + + // + Clean(supportZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int supportZonesCount = DetectValidSupportZones( + state, + bullishOrderBlocks, + bullishFairValueGaps, + supportZones // + ); + + // + result = IsValidSize(supportZonesCount); + + // + return result; + } + + /** + * Detect Resistance Zones ... + * + * @return ( bool ) + */ + bool DetectResistanceZones( + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCResistanceZone *&resistanceZones[] // + ) + { + // + bool result = false; + + // + Clean(resistanceZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int resistanceZonesCount = DetectValidResistanceZones( + state, + bearishOrderBlocks, + bearishFairValueGaps, + resistanceZones // + ); + + // + result = IsValidSize(resistanceZonesCount); + + // + return result; + } + + /** + * Detect Demand Zones ... + * + * @return ( bool ) + */ + bool DetectDemandZones( + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCDemandZone *&demandZones[] // + ) + { + // + bool result = false; + + // + Clean(demandZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int demandZonesCount = DetectValidDemandZones( + state, + bullishOrderBlocks, + bullishFairValueGaps, + demandZones // + ); + + // + result = IsValidSize(demandZonesCount); + + // + return result; + } + + /** + * Detect Supply Zones ... + * + * @return ( bool ) + */ + bool DetectSupplyZones( + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCSupplyZone *&supplyZones[] // + ) + { + // + bool result = false; + + // + Clean(supplyZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int supplyZonesCount = DetectValidSupplyZones( + state, + bearishOrderBlocks, + bearishFairValueGaps, + supplyZones // + ); + + // + result = IsValidSize(supplyZonesCount); + + // + return result; + } + + /** + * Get Cycle State and Update it ... + * + * @param state: X121SMCCycleState instance Reference ... + * + * @return ( bool ) + */ + bool GetCycleState(X121SMCCycleState &state) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + state.symbol = symbol; + state.period = period; + + // + datetime cTime = TimeCurrent(); + + // + // Detect Order Block ... + + // + bool hasBullishOBs = state.HasBullishOBs(); + int bullishOBsCount = state.CountBullishOBs(); + + // + bool hasBearishOBs = state.HasBearishOBs(); + int bearishOBsCount = state.CountBearishOBs(); + + // + bool hasOBs = hasBullishOBs && + hasBearishOBs; + if (!hasOBs) + { + // + XCOrderBlock *bullishOBs[]; + XCOrderBlock *bearishOBs[]; + hasOBs = DetectOrderBlocks( + bullishOBs, + bearishOBs // + ); + + // + if (hasOBs && + !hasBullishOBs) + { + // + Copy( + bullishOBs, + state.bullishOBs // + ); + } + + // + if (hasOBs && + !hasBearishOBs) + { + // + Copy( + bearishOBs, + state.bearishOBs // + ); + } + + // + hasBullishOBs = state.HasBullishOBs(); + bullishOBsCount = state.CountBullishOBs(); + + // + hasBearishOBs = state.HasBearishOBs(); + bearishOBsCount = state.CountBearishOBs(); + } + + // + // Update Order Blocks Time ... + if (hasOBs) + { + // + if (hasBullishOBs) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + state.bullishOBs[i].To(cTime); + } + } + + // + if (hasBearishOBs) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + state.bearishOBs[i].To(cTime); + } + } + } + + // + // Detect Fair Value Gap ... + + // + bool hasBullishFVGs = state.HasBullishFVGs(); + int bullishFVGsCount = state.CountBullishFVGs(); + + // + bool hasBearishFVGs = state.HasBearishFVGs(); + int bearishFVGsCount = state.CountBearishFVGs(); + + // + bool hasFVGs = hasBullishFVGs && + hasBearishFVGs; + if (!hasFVGs) + { + // + XCFVG *bullishFVGs[]; + XCFVG *bearishFVGs[]; + hasFVGs = DetectFairValueGaps( + bullishFVGs, + bearishFVGs // + ); + + // + if (hasFVGs && + !hasBullishFVGs) + { + // + Copy( + bullishFVGs, + state.bullishFVGs // + ); + } + + // + if (hasFVGs && + !hasBearishFVGs) + { + // + Copy( + bearishFVGs, + state.bearishFVGs // + ); + } + + // + hasBullishFVGs = state.HasBullishFVGs(); + bullishFVGsCount = state.CountBullishFVGs(); + + // + hasBearishFVGs = state.HasBearishFVGs(); + bearishFVGsCount = state.CountBearishFVGs(); + } + + // + // Update Fair Value Gaps Time ... + if (hasFVGs) + { + // + if (hasBullishFVGs) + { + // + for (int i = 0; i < bullishFVGsCount; i++) + { + state.bullishFVGs[i].To(cTime); + } + } + + // + if (hasBearishFVGs) + { + // + for (int i = 0; i < bearishFVGsCount; i++) + { + state.bearishFVGs[i].To(cTime); + } + } + } + + // + // Detect Support Zones ... + + // + bool hasSupportZones = state.HasSupportZones(); + int supportZonesCount = state.CountSupportZones(); + + // + if (!hasSupportZones) + { + // + XCSupportZone *supportZones[]; + hasSupportZones = DetectSupportZones( + state.bullishOBs, + state.bullishFVGs, + supportZones // + ); + + // + if (hasSupportZones) + { + // + Copy( + supportZones, + state.supportZones // + ); + + // + supportZonesCount = state.CountSupportZones(); + } + } + + // + // Update Support Zones Time ... + if (hasSupportZones) + { + // + for (int i = 0; i < supportZonesCount; i++) + { + state.supportZones[i].To(cTime); + } + } + + // + // Detect Demand Zones ... + + // + bool hasDemandZones = state.HasDemandZones(); + int demandZonesCount = state.CountDemandZones(); + + // + if (!hasDemandZones) + { + // + XCDemandZone *demandZones[]; + hasDemandZones = DetectDemandZones( + state.bullishOBs, + state.bullishFVGs, + demandZones // + ); + + // + if (hasDemandZones) + { + // + Copy( + demandZones, + state.demandZones // + ); + + // + demandZonesCount = state.CountDemandZones(); + } + } + + // + // Update Support Zones Time ... + if (hasDemandZones) + { + // + for (int i = 0; i < demandZonesCount; i++) + { + state.demandZones[i].To(cTime); + } + } + + // + // Detect Resistance Zones ... + + // + bool hasResistanceZones = state.HasResistanceZones(); + int resistanceZonesCount = state.CountResistanceZones(); + + // + if (!hasResistanceZones) + { + // + XCResistanceZone *resistanceZones[]; + hasResistanceZones = DetectResistanceZones( + state.bearishOBs, + state.bearishFVGs, + resistanceZones // + ); + + // + if (hasResistanceZones) + { + // + for (int i = 0; i < ArraySize(resistanceZones); i++) + { + resistanceZones[i].To(cTime); + } + + // + Copy( + resistanceZones, + state.resistanceZones // + ); + + // + resistanceZonesCount = state.CountResistanceZones(); + } + } + + // + // Update Resistance Zones Time ... + if (hasResistanceZones) + { + // + for (int i = 0; i < resistanceZonesCount; i++) + { + state.resistanceZones[i].To(cTime); + } + } + + // + // Detect Supply Zones ... + + // + bool hasSupplyZones = state.HasSupplyZones(); + int supplyZonesCount = state.CountSupplyZones(); + + // + if (!hasSupplyZones) + { + // + XCSupplyZone *supplyZones[]; + hasSupplyZones = DetectSupplyZones( + state.bearishOBs, + state.bearishFVGs, + supplyZones // + ); + + // + if (hasSupplyZones) + { + // + Copy( + supplyZones, + state.supplyZones // + ); + + // + supplyZonesCount = state.CountSupplyZones(); + } + } + + // + // Update Resistance Zones Time ... + if (hasSupplyZones) + { + // + for (int i = 0; i < supplyZonesCount; i++) + { + state.supplyZones[i].To(cTime); + } + } + + // + result = state.IsValid(); + + // + return result; + } + /** * Retrieve Cycle Conditions ... * @@ -688,6 +1293,288 @@ class XC121SMCCycleHelper : public XCBase // // Tools ... + /** + * Draw Cycle State ... + * + * @param state: X121SMCCyleState instance Reference ... + * + * @return ( int ) + */ + int DrawCycleState( + X121SMCCycleState &state, + XCBaseObject *&drawnObjects[] // + ) + { + // + int result = 0; + + // + // Order Blocks ... + + // + // Bullish ... + bool hasBullishOBs = state.HasBullishOBs(); + int bullishOBsCount = state.CountBullishOBs(); + if (hasBullishOBs) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bullishOBs[i]; + + // + XCBullishOrderBlockObject *iObObj; + bool isCreated = mPOIDrawer + .CreateBullishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + // Bearish ... + bool hasBearishOBs = state.HasBearishOBs(); + int bearishOBsCount = state.CountBearishOBs(); + if (hasBearishOBs) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bearishOBs[i]; + + // + XCBearishOrderBlockObject *iObObj; + bool isCreated = mPOIDrawer + .CreateBearishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish ... + bool hasBullishFVGs = state.HasBullishFVGs(); + int bullishFVGsCount = state.CountBullishFVGs(); + if (hasBullishFVGs) + { + // + for (int i = 0; i < bullishFVGsCount; i++) + { + // + XCFVG *iFVG = state.bullishFVGs[i]; + + // + XCBullishFairValueGapObject *iFVGObj; + bool isCreated = mPOIDrawer + .CreateBullishFairValueGap( + iFVG, + iFVGObj // + ); + if (isCreated) + { + // + iFVGObj.ZoneColor(clrLime); + + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + } + + // + // Bearish ... + bool hasBearishFVGs = state.HasBearishFVGs(); + int bearishFVGsCount = state.CountBearishFVGs(); + if (hasBearishFVGs) + { + // + for (int i = 0; i < bearishFVGsCount; i++) + { + // + XCFVG *iFVG = state.bearishFVGs[i]; + + // + XCBearishFairValueGapObject *iFVGObj; + bool isCreated = mPOIDrawer + .CreateBearishFairValueGap( + iFVG, + iFVGObj // + ); + if (isCreated) + { + // + iFVGObj.ZoneColor(clrRed); + + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + } + + // + // Support Zones ... + bool hasSupportZones = state.HasSupportZones(); + int supportZonesCount = state.CountSupportZones(); + if (hasSupportZones) + { + // + for (int i = 0; i < supportZonesCount; i++) + { + // + XCSupportZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateSupportZone( + state.supportZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrDarkSeaGreen); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // Resistance Zones ... + bool hasResistanceZones = state.HasResistanceZones(); + int resistanceZonesCount = state.CountResistanceZones(); + if (hasResistanceZones) + { + // + for (int i = 0; i < resistanceZonesCount; i++) + { + // + XCResistanceZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateResistanceZone( + state.resistanceZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrSaddleBrown); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // Demand Zones ... + bool hasDemandZones = state.HasDemandZones(); + int demandZonesCount = state.CountDemandZones(); + if (hasDemandZones) + { + // + for (int i = 0; i < demandZonesCount; i++) + { + // + XCDemandZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateDemandZone( + state.demandZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrDarkTurquoise); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // Supply Zones ... + bool hasSupplyZones = state.HasSupplyZones(); + int supplyZonesCount = state.CountSupplyZones(); + if (hasSupplyZones) + { + // + for (int i = 0; i < supplyZonesCount; i++) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateSupplyZone( + state.supplyZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrChocolate); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + // // Virtuals ... diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index a8be496f..08f22528 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -36,6 +36,7 @@ const string X121SMCStrategyToken = "X121SMC"; // const string X121SMCXToken = "X121X"; +const string X121SMCXHKPVToken = "X121XHKPV"; const string X121SMCXOBPVToken = "X121XOBPV"; // @@ -45,6 +46,7 @@ enum ENUM_X_121_SMC_PROVIDERS // X_121_SMC_PROVIDER_NONE, X_121_SMC_PROVIDER_X, + X_121_SMC_PROVIDER_XHKPV, X_121_SMC_PROVIDER_XOBPV, }; @@ -612,6 +614,365 @@ struct X121SMCGuard } }; +// +// Model Cycle State ... +struct X121SMCCycleState +{ + // + // Props ... + string symbol; + ENUM_TIMEFRAMES period; + + // + // Bullish ... + XCFVG *bullishFVGs[]; + XCOrderBlock *bullishOBs[]; + XCDemandZone *demandZones[]; + XCSupportZone *supportZones[]; + + // + // Bearish ... + XCFVG *bearishFVGs[]; + XCOrderBlock *bearishOBs[]; + XCSupplyZone *supplyZones[]; + XCResistanceZone *resistanceZones[]; + + // + // Constructor ... + X121SMCCycleState() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + + // + Clean(bullishFVGs); + Clean(bullishOBs); + Clean(demandZones); + Clean(supportZones); + + // + Clean(bearishFVGs); + Clean(bearishOBs); + Clean(supplyZones); + Clean(resistanceZones); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) && + ( + // + (HasBullishOBs() && + (HasBullishFVGs() || + HasSupportZones() || + HasDemandZones())) + // + || + (HasBearishOBs() && + (HasSupplyZones() || + HasBearishFVGs() || + HasResistanceZones())) + // + ) + // + ; + + // + return result; + } + + // + int CountBullishOBs() + { + return ArraySize(bullishOBs); + } + + // + bool HasBullishOBs() + { + return IsValidSize(CountBullishOBs()); + } + + // + int CountBearishOBs() + { + return ArraySize(bearishOBs); + } + + // + bool HasBearishOBs() + { + return IsValidSize(CountBearishOBs()); + } + + // + int CountSupportZones() + { + return ArraySize(supportZones); + } + + // + bool HasSupportZones() + { + return IsValidSize(CountSupportZones()); + } + + // + int CountResistanceZones() + { + return ArraySize(resistanceZones); + } + + // + bool HasResistanceZones() + { + return IsValidSize(CountResistanceZones()); + } + + // + int CountDemandZones() + { + return ArraySize(demandZones); + } + + // + bool HasDemandZones() + { + return IsValidSize(CountDemandZones()); + } + + // + int CountSupplyZones() + { + return ArraySize(supplyZones); + } + + // + bool HasSupplyZones() + { + return IsValidSize(CountSupplyZones()); + } + + // + int CountBullishFVGs() + { + return ArraySize(bullishFVGs); + } + + // + bool HasBullishFVGs() + { + return IsValidSize(CountBullishFVGs()); + } + + // + int CountBearishFVGs() + { + return ArraySize(bearishFVGs); + } + + // + bool HasBearishFVGs() + { + return IsValidSize(CountBearishFVGs()); + } + + // +}; + +bool DetectPriceInsideBox( + XBoxZone &box, + X121Conditions &xConditions, + X121SMCCycleState &state // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + string symbol = state.symbol; + ENUM_TIMEFRAMES period = state.period; + + // + box.symbol = symbol; + box.period = period; + + // + result = state.IsValid(); + if (!result) + { + return result; + } + + // + // Detect Price Inside Order Block ... + + // + bool hasBullishOBs = state.HasBullishOBs(); + int bullishOBsCount = state.CountBullishOBs(); + + // + bool hasBearishOBs = state.HasBearishOBs(); + int bearishOBsCount = state.CountBearishOBs(); + + // + bool hasOBs = + // + hasBullishOBs || + hasBearishOBs + // + ; + result = hasOBs; + if (!result) + { + return result; + } + + // + bool hasPriceInsideOB = false; + XCOrderBlock *priceInsideOB = NULL; + ENUM_X_DIRECTION boxDir = X_DIRECTION_NONE; + + // + if (hasBullishOBs && + !hasPriceInsideOB) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bullishOBs[i]; + + // + bool isInside = IsPriceInsideZone( + xConditions.valesBuffer[1], + (XCZone *)iOb // + ); + if (isInside) + { + // + priceInsideOB = iOb; + hasPriceInsideOB = true; + boxDir = X_DIRECTION_BULLISH; + break; + } + } + } + + // + if (hasBearishOBs && + !hasPriceInsideOB) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bearishOBs[i]; + + // + bool isInside = IsPriceInsideZone( + xConditions.peaksBuffer[1], + (XCZone *)iOb // + ); + if (isInside) + { + // + priceInsideOB = iOb; + hasPriceInsideOB = true; + boxDir = X_DIRECTION_BEARISH; + break; + } + } + } + + // + bool hasBullishFVG = state.HasBullishFVGs(); + bool hasBearishFVG = state.HasBearishFVGs(); + bool hasDemandZones = state.HasDemandZones(); + bool hasSupplyZones = state.HasSupplyZones(); + bool hasSupportZones = state.HasSupportZones(); + bool hasResistanceZones = state.HasResistanceZones(); + + // + bool hasBullishZones = + // + hasBullishFVG || + hasDemandZones || + hasSupportZones + // + ; + + // + bool hasBearishZones = + // + hasBearishFVG || + hasSupplyZones || + hasResistanceZones + // + ; + + // + bool hasPropperZones = + // + IsBullish(boxDir) + ? hasBullishZones + : IsBearish(boxDir) + ? hasBearishZones + : false + // + ; + + // + if (!hasPropperZones && + hasPriceInsideOB) + { + // + box.to = priceInsideOB.To(); + box.from = priceInsideOB.From(); + box.upper = priceInsideOB.Upper(); + box.lower = priceInsideOB.Lower(); + } + else if (hasPropperZones && + hasPriceInsideOB) + { + // + // Detect Validate Zones ... + } + + // + result = box.IsValid(); + + // + return result; +} + /** * Add Guard to Collection ... * @@ -704,6 +1065,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) result = X121SMCXToken; break; + // + case X_121_SMC_PROVIDER_XHKPV: + result = X121SMCXHKPVToken; + break; + // case X_121_SMC_PROVIDER_XOBPV: result = X121SMCXOBPVToken; @@ -737,6 +1103,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_X; } + else if (Contains(X121SMCXHKPVToken, value)) + { + result = X_121_SMC_PROVIDER_XHKPV; + } else if (Contains(X121SMCXOBPVToken, value)) { result = X_121_SMC_PROVIDER_XOBPV; diff --git a/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 index 8d9578f3..ea6d22ad 100644 --- a/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 @@ -900,7 +900,10 @@ bool DetectX121SMCXSignalSetup( forDir, priceInsideOB.GetSymbol(), priceInsideOB.GetPeriod(), - (XCZone *)priceInsideOB // + priceInsideOB.Upper(), + priceInsideOB.Lower(), + priceInsideOB.From(), + priceInsideOB.To() // ); if (hasBreakerBar) { diff --git a/X121SMCEA/Signals/x-121.smc.xhkpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xhkpv.signal.lib.mq5 new file mode 100644 index 00000000..cc9c0af6 --- /dev/null +++ b/X121SMCEA/Signals/x-121.smc.xhkpv.signal.lib.mq5 @@ -0,0 +1,1324 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: X +// Description: provide all Signalling functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +// #include "../../Libraries/x-trade.lib" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXHKPVSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + X121SMCCycleState state; + + // + // Constructor ... + X121SMCStrategyXHKPVSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + pivot = 0; + point = 0; + + // + state.Clean(); + } + + // +}; + +// +// Signaller Data Sources ... +X121SMCStrategyXHKPVSignalConditions mXHKPVConditions; +X121SMCStrategyXHKPVSignalConditions mXHKPVConditionsCollection[]; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXHKPVSignalSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXHKPVSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 3; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + // Detect Trend ... + + // + // Consolidation ... + ENUM_X_DIRECTION consolidationTrendDir; + bool hasConsolidationTrend = + consolidationCycleHelper + .DetectMarketStructure( + consolidationTrendDir // + ); + bool hasConsolidationBullishTrend = + hasConsolidationTrend && + IsBullish(consolidationTrendDir); + bool hasConsolidationBearishTrend = + hasConsolidationTrend && + IsBearish(consolidationTrendDir); + + // + // Verification ... + ENUM_X_DIRECTION verificationTrendDir; + bool hasVerificationTrend = + verificationCycleHelper + .DetectMarketStructure( + verificationTrendDir // + ); + bool hasVerificationBullishTrend = + hasVerificationTrend && + IsBullish(verificationTrendDir); + bool hasVerificationBearishTrend = + hasVerificationTrend && + IsBearish(verificationTrendDir); + + // + // Analyse ... + ENUM_X_DIRECTION analyseTrendDir; + bool hasAnalyseTrend = + analyseCycleHelper + .DetectMarketStructure( + analyseTrendDir // + ); + bool hasAnalyseBullishTrend = + hasAnalyseTrend && + IsBullish(analyseTrendDir); + bool hasAnalyseBearishTrend = + hasAnalyseTrend && + IsBearish(analyseTrendDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionTrendDir; + bool hasDecisionTrend = + decisionCycleHelper + .DetectMarketStructure( + decisionTrendDir // + ); + bool hasDecisionBullishTrend = + hasDecisionTrend && + IsBullish(decisionTrendDir); + bool hasDecisionBearishTrend = + hasDecisionTrend && + IsBearish(decisionTrendDir); + + // + // Detect Bar State ... + + // + // PinBar ... + ENUM_X_DIRECTION cBarPinDir; + bool isCBarPin = decisionCycleHelper + .mBarAnalyser + .IsPinBar( + cBar, + cBarPinDir, + 1 // + ); + bool isCBarBullishPin = + isCBarPin && + IsBullish(cBarPinDir); + bool isCBarBearishPin = + isCBarPin && + IsBearish(cBarPinDir); + + // + // Engulf ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = decisionCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // Extended ... + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = decisionCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // Extended ... + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarMomentumDir); + + // + // Reject ... + ENUM_X_DIRECTION cBarRejectDir; + bool isCBarRejected = decisionCycleHelper + .mBarAnalyser + .IsRejectionBar( + cBar, + cBarRejectDir, + 0 // Extended ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarRejectDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarRejectDir); + + // + // Pull Back ... + ENUM_X_DIRECTION cBarPullbackDir; + bool isCBarPullbacked = + decisionCycleHelper + .mBarAnalyser + .HasPullBack( + cBarPullbackDir, + cBar // + ); + bool isCBarBullishPullbacked = + isCBarPullbacked && + IsBullish(cBarPullbackDir); + bool isCBarBearishPullbacked = + isCBarPullbacked && + IsBearish(cBarPullbackDir); + + // + // HH/LL Break ... + + // + bool isCBarBreaksUpHH = IsBarBreak( + hh, + X_DIRECTION_BULLISH, + cBar // + ); + + // + bool isCBarBreaksDownLL = IsBarBreak( + hh, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // Bars Pattern and Power and Pressures ... + + // + bool hasCBarBullishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBullishPattern( + cBar, + 2 // + ); + + // + bool hasCBarBearishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBearishPattern( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPower = + decisionCycleHelper + .mBarAnalyser + .HasBullishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPower = + decisionCycleHelper + .mBarAnalyser + .HasBearishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBullishPressure( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBearishPressure( + cBar, + 2 // + ); + + // + // Bar Checking Summary ... + + // + // Bullish ... + bool isCBarBullishFormed = + // + ( + // + hasCBarBullishPattern && + isCBarHasBullishPower && + isCBarHasBullishPressure + // + ) + // + || + // + ( + // + isCBarBullishPin || + isCBarBreaksUpHH || + isCBarBullishEngulfed || + isCBarBullishMomentum || + isCBarBullishRejected + // + ) + // + ; + + // + // Bearish ... + bool isCBarBearishFormed = + // + ( + // + hasCBarBearishPattern && + isCBarHasBearishPower && + isCBarHasBearishPressure + // + ) + // + || + // + ( + // + isCBarBearishPin || + isCBarBreaksDownLL || + isCBarBearishEngulfed || + isCBarBearishMomentum || + isCBarBearishRejected + // + ) + // + ; + + // + // Detect Cycle State ... + + // + visionCycleHelper.GetCycleState(conditions.state); + + // + // + // + + // // + // bool hasPriceInsideOB = false; + // XCOrderBlock *priceInsideOB = NULL; + + // // + // if (!hasPriceInsideOB && + // hasBullishOBs) + // { + // // + // for (int i = 0; i < bullishOBsCount; i++) + // { + // // + // XCOrderBlock *iOb = conditions.bullishOBs[i]; + + // // + // bool isInside = IsPriceInsideZone( + // decisionXConditions.valesBuffer[1], + // (XCZone *)iOb // + // ); + // if (isInside) + // { + // // + // hasPriceInsideOB = true; + // priceInsideOB = iOb; + // break; + // } + // } + // } + + // // + // if (!hasPriceInsideOB && + // hasBearishOBs) + // { + // // + // for (int i = 0; i < bearishOBsCount; i++) + // { + // // + // XCOrderBlock *iOb = conditions.bearishOBs[i]; + + // // + // bool isInside = IsPriceInsideZone( + // decisionXConditions.peaksBuffer[1], + // (XCZone *)iOb // + // ); + // if (isInside) + // { + // // + // hasPriceInsideOB = true; + // priceInsideOB = iOb; + // break; + // } + // } + // } + + // // + // XStateZones obState; + // bool hasOBState = false; + // XOHCL priceInsideOBBreakerBar; + // if (hasPriceInsideOB) + // { + // // + // XOHCL toBar; + // XOHCL fromBar; + // ENUM_X_DIRECTION forDir = + // priceInsideOB.IsBullish() + // ? X_DIRECTION_BULLISH + // : X_DIRECTION_BEARISH; + // bool hasBreakerBar = HasBreakerBar( + // toBar, + // fromBar, + // priceInsideOBBreakerBar, + // forDir, + // priceInsideOB.GetSymbol(), + // priceInsideOB.GetPeriod(), + // priceInsideOB.Upper(), + // priceInsideOB.Lower(), + // priceInsideOB.From(), + // priceInsideOB.To() // + // ); + // if (hasBreakerBar) + // { + // // + // CalculateStateZones( + // obState, + // analyseState, + // priceInsideOB.Upper(), + // priceInsideOB.Lower(), + // priceInsideOBBreakerBar.time // + // ); + // } + + // // + // hasOBState = obState.IsValid(); + // } + + // + // Draw ... + XCBaseObject *drawnObjects[]; + int drawnObjectsCount = visionCycleHelper.DrawCycleState( + conditions.state, + drawnObjects // + ); + if (IsValidSize(drawnObjectsCount)) + { + Print("Drawn Objects ..."); + } + + // + // + // + + // + // Summarize Conditions ... + + // + bool isCondition1Bullish = + // + isCBarBullishFormed && + // + false + // + ; + + // + bool isCondition1Bearish = + // + isCBarBearishFormed && + // + false + // + ; + + // + bool hasCondition1 = isCondition1Bullish || + isCondition1Bearish; + if (hasCondition1) + { + // + ENUM_X_DIRECTION pzDir = + isCondition1Bullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double point = GetEntry( + conditions.symbol, + pzDir // + ); + + // + // Manipulate Conditions Point ... + + // + conditions.point = point; + + // + // Manipulate Conditions Pivot ... + + // + conditions.pivot = + isCondition1Bullish + ? triggerXConditions.valesBuffer[1] + : triggerXConditions.peaksBuffer[1]; + } + + // + // + // + + // + isBullish = + // + isCondition1Bullish + // + ; + + // + isBearish = + // + isCondition1Bearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Arrays ... + ArrayFree(triggerPoiEvents); + ArrayFree(triggerCycleEvents); + ArrayFree(decisionPoiEvents); + ArrayFree(decisionCycleEvents); + ArrayFree(analysePoiEvents); + ArrayFree(analyseCycleEvents); + ArrayFree(verificationPoiEvents); + ArrayFree(verificationCycleEvents); + ArrayFree(consolidationPoiEvents); + ArrayFree(consolidationCycleEvents); + ArrayFree(visionPoiEvents); + ArrayFree(visionCycleEvents); + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Cleanup Arrays ... + ArrayFree(triggerPoiEvents); + ArrayFree(triggerCycleEvents); + ArrayFree(decisionPoiEvents); + ArrayFree(decisionCycleEvents); + ArrayFree(analysePoiEvents); + ArrayFree(analyseCycleEvents); + ArrayFree(verificationPoiEvents); + ArrayFree(verificationCycleEvents); + ArrayFree(consolidationPoiEvents); + ArrayFree(consolidationCycleEvents); + ArrayFree(visionPoiEvents); + ArrayFree(visionCycleEvents); + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXHKPVSignalTrigger( + // + X121SMCStrategyXHKPVSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXHKPVConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + // Slopes ... + + // + bool isRsiSlopeBullish = decisionXHKPVConditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionXHKPVConditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionXHKPVConditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionXHKPVConditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionXHKPVConditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionXHKPVConditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionXHKPVConditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionXHKPVConditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionXHKPVConditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionXHKPVConditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionXHKPVConditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionXHKPVConditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionXHKPVConditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionXHKPVConditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isStrSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapMidSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isStrSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapMidSlopeBearish && + isVwapSlowSlopeBearish; + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish // && + // isPointBreaked && + // isSlopesBullish + // + ; + + // + isBearish = + // + isBearish // && + // isPointBreaked && + // isSlopesBearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup Arrays ... + ArrayFree(decisionPoiEvents); + ArrayFree(decisionCycleEvents); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + double iAtr = 0; // decisionConditions.x121Conditions.atrBuffer[1]; + iAtr *= 1.5; + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - iAtr + : slsMax + iAtr; + double risk = MathAbs(entry - sl); + + // + // Filling Conditions Props ... + conditions.sl = sl; + // conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup Arrays ... + ArrayFree(decisionPoiEvents); + ArrayFree(decisionCycleEvents); + + // + return result; +} + +// +// Detect Guards ... +bool DetectX121SMCXHKPVGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + string provider = ToString(X_121_SMC_PROVIDER_X); + + // + result = DetectX121SMCGuards( + provider, + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + true, // CloseOnTPNear Guard ... + true, // CloseLongsOnBearishTrend Guard ... + true, // CloseShortsOnBullishTrend Guard ... + true, // CloseAllWeekend Guard ... + true, // PartialCloseOnTrendChange Guard ... + true, // TrailStop Guard ... + true, // TrailTarget Guard ... + true // Hedge Guard ... + // + ); + + // + return result; +} + +// +// Add Conditions to Conditions Collection ... +int AddX121SMCXHKPVConditionsIfNotExists( + X121SMCStrategyXHKPVSignalConditions &item, + X121SMCStrategyXHKPVSignalConditions &items[], + int maxAllowed = 10 // +) +{ + // + int result = 0; + + // + bool isSetuped = IsValid(item.setupTime) && + HasDirection(item.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(items); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXHKPVSignalConditions tmpItems[]; + Copy( + items, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(item.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXHKPVSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = item.dir == iItem.dir && + item.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + items, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + item, + items // + ); + + // + // Remove Olds ... + CleanupArray( + items, + maxAllowed // + ); + + // + result = ArraySize(items); + + // + return result; +} + +// diff --git a/X121SMCEA/Signals/x-121.smc.xobpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xobpv.signal.lib.mq5 index 23f60d85..3544e464 100644 --- a/X121SMCEA/Signals/x-121.smc.xobpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xobpv.signal.lib.mq5 @@ -23,8 +23,8 @@ // Imports ... // #include "../../Libraries/x-trade.lib" #include "../Classes/x-121.smc.market.cycle.helper.class.mq5" -#include "../Libraries/x-121.smc.lib.mq5" #include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" // // Definitions ... @@ -900,7 +900,10 @@ bool DetectX121SMCXOBPVSignalSetup( forDir, priceInsideOB.GetSymbol(), priceInsideOB.GetPeriod(), - (XCZone *)priceInsideOB // + priceInsideOB.Upper(), + priceInsideOB.Lower(), + priceInsideOB.From(), + priceInsideOB.To() // ); if (hasBreakerBar) { @@ -918,13 +921,204 @@ bool DetectX121SMCXOBPVSignalSetup( hasOBState = obState.IsValid(); } + // + // DRAW ... + // + + // // + // XCBaseObject *drawnObjects[]; + + // // + // if (hasBullishOrderBlocks) + // { + // // + // for (int i = 0; i < bullishOrderBlocksCount; i++) + // { + // // + // XCOrderBlock *iOb = conditions.bullishOBs[i]; + + // // + // XCBullishOrderBlockObject *iObObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBullishOrderBlock( + // iOb, + // iObObj // + // ); + // if (isCreated) + // { + // // + // Add( + // (XCBaseObject *)iObObj, + // drawnObjects // + // ); + // } + // } + // } + + // // + // if (hasBearishOrderBlocks) + // { + // // + // for (int i = 0; i < bearishOrderBlocksCount; i++) + // { + // // + // XCOrderBlock *iOb = conditions.bearishOBs[i]; + + // // + // XCBearishOrderBlockObject *iObObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBearishOrderBlock( + // iOb, + // iObObj // + // ); + // if (isCreated) + // { + // // + // Add( + // (XCBaseObject *)iObObj, + // drawnObjects // + // ); + // } + // } + // } + + // // + // if (hasPriceInsideOB) + // { + // // + // bool isBullish = priceInsideOB.IsBullish(); + + // // + // bool isCreated = false; + // XCBaseObject *priceInsideOBObj = NULL; + // if (isBullish) + // { + // // + // XCBullishOrderBlockObject *iObj; + // isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBullishOrderBlock( + // priceInsideOB, + // iObj // + // ); + // if (isCreated) + // { + // // + // iObj.ZoneColor(clrYellow); + + // // + // priceInsideOBObj = (XCBaseObject *)iObj; + // } + // } + // else + // { + // // + // XCBearishOrderBlockObject *iObj; + // isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBearishOrderBlock( + // priceInsideOB, + // iObj // + // ); + // if (isCreated) + // { + // // + // iObj.ZoneColor(clrOrange); + + // // + // priceInsideOBObj = (XCBaseObject *)iObj; + // } + // } + + // // + // if (isCreated) + // { + // // + // Add( + // priceInsideOBObj, + // drawnObjects // + // ); + // } + // } + + // + // if (hasOldestBullishOB) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBullishOrderBlock( + // oldestBullishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // // + // if (hasYoungestBullishOB) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBullishOrderBlock( + // youngestBullishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // // + // if (hasOldestBearishOB) + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBearishOrderBlock( + // oldestBearishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // // + // if (hasYoungestBearishOB) + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBearishOrderBlock( + // youngestBearishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // + // + // + // bool isSameCyclesPeak = // triggerXOBPVConditions.peaksBuffer[1] == decisionXOBPVConditions.peaksBuffer[1] && decisionXOBPVConditions.peaksBuffer[1] == analyseXOBPVConditions.peaksBuffer[1] && - analyseXOBPVConditions.peaksBuffer[1] == verificationXOBPVConditions.peaksBuffer[1] && - verificationXOBPVConditions.peaksBuffer[1] == consolidationXOBPVConditions.peaksBuffer[1] + analyseXOBPVConditions.peaksBuffer[1] == verificationXOBPVConditions.peaksBuffer[1] + // && + // verificationXOBPVConditions.peaksBuffer[1] == consolidationXOBPVConditions.peaksBuffer[1] // ; @@ -933,14 +1127,15 @@ bool DetectX121SMCXOBPVSignalSetup( // triggerXOBPVConditions.valesBuffer[1] == decisionXOBPVConditions.valesBuffer[1] && decisionXOBPVConditions.valesBuffer[1] == analyseXOBPVConditions.valesBuffer[1] && - analyseXOBPVConditions.valesBuffer[1] == verificationXOBPVConditions.valesBuffer[1] && - verificationXOBPVConditions.valesBuffer[1] == consolidationXOBPVConditions.valesBuffer[1] + analyseXOBPVConditions.valesBuffer[1] == verificationXOBPVConditions.valesBuffer[1] + // && + // verificationXOBPVConditions.valesBuffer[1] == consolidationXOBPVConditions.valesBuffer[1] // ; // bool hasSameCyclesPV = - hasOBState && + // hasOBState && hasPriceInsideOB && (isSameCyclesPeak || isSameCyclesVale); @@ -1404,7 +1599,7 @@ bool DetectX121SMCXOBPVGuards( true, // TrailStop Guard ... true, // TrailTarget Guard ... true // Hedge Guard ... - // + // ); // @@ -1491,34 +1686,3 @@ int AddX121SMCXOBPVConditionsIfNotExists( } // -// Draw Conditions ... -int DrawX121SMCXOBPVConditions( - X121SMCStrategyXOBPVSignalConditions &conditions, - XCBaseObject *&drawnObjects[], - XCPOIDrawer *drawer // -) -{ - // - int result = 0; - - // - Clean(drawnObjects); - - // - if (drawer == NULL) - { - return result; - } - - // - bool isSetuped = conditions.IsSetuped(); - if (!isSetuped) - { - return result; - } - - // - return result; -} - -// diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 5d462480..6ab96508 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -28,6 +28,7 @@ // #include "../Signals/x-121.smc.x.signal.lib.mq5" +#include "../Signals/x-121.smc.xhkpv.signal.lib.mq5" #include "../Signals/x-121.smc.xobpv.signal.lib.mq5" // @@ -43,6 +44,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // Props ... bool useXSignal; + bool useXHKPVSignal; bool useXOBPVSignal; // @@ -67,6 +69,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // ArrayFree(mXConditionsCollection); + ArrayFree(mXHKPVConditionsCollection); ArrayFree(mXOBPVConditionsCollection); } @@ -194,6 +197,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // bool hasXSignal = false; + bool hasXHKPVSignal = false; bool hasXOBPVSignal = false; // @@ -205,6 +209,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy hasSignal = hasXSignal; } + // + // XHKPV Signal ... + if (useXHKPVSignal && !hasSignal) + { + // + hasXHKPVSignal = DetectXHKPVSignal(conditions); + hasSignal = hasXHKPVSignal; + } + // // XOBPV Signal ... if (useXOBPVSignal && !hasSignal) @@ -386,6 +399,23 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy ); } + // + // XHKPV Guard Detection ... + if (useXHKPVSignal) + { + // + bool hasGuard = DetectX121SMCXHKPVGuards( + guards, + positions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + } + // // XPZ Guard Detection ... if (useXOBPVSignal) @@ -676,6 +706,224 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } + // + // XHKPV Signal ... + bool DetectXHKPVSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XHKPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXHKPVConditions.setupTime; + bool isSetuped = mXHKPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXHKPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXHKPVSignalSetup( + symbol, + period, + mXHKPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXHKPVConditions.dir; + setupTime = mXHKPVConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXHKPVConditionsIfNotExists( + mXHKPVConditions, + mXHKPVConditionsCollection // + ); + + // + mXHKPVConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mXHKPVConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXHKPVSignalConditions mTmpConditions[]; + Copy( + mXHKPVConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXHKPVSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXHKPVSignalTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mXHKPVConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mXHKPVConditionsCollection, + selectedIndex, + 1 // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; + } + // // XOBPV Signal ... bool DetectXOBPVSignal( @@ -910,7 +1158,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy { // useXSignal = false; - useXOBPVSignal = true; + useXHKPVSignal = true; + useXOBPVSignal = false; // string symbol = GetSymbol();