From 9e351773cabfc2e8e1a88f93c4dfa96b27f27ff5 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 18 Feb 2025 09:57:46 +0330 Subject: [PATCH] last ... --- Documents/BKP/Test.mq5 | Bin 0 -> 8908 bytes .../BKP/x-121.smc.xwz.signal.class copy.mq5 | 2725 ++++++++++++ Documents/BKP/x-121.smc.xwz.signal.class.mq5 | 2725 ++++++++++++ .../BKP/x-121.smc.xwz.signal.lib copy.mq5 | 3749 +++++++++++++++++ Documents/BKP/x-121.smc.xwz.signal.lib.mq5 | 3560 ++++++++++++++++ .../Signals/x-121.smc.xwz.signal.class.mq5 | 145 +- .../Signals/x-121.smc.xwz.signal.lib.mq5 | 667 ++- 7 files changed, 13316 insertions(+), 255 deletions(-) create mode 100644 Documents/BKP/Test.mq5 create mode 100644 Documents/BKP/x-121.smc.xwz.signal.class copy.mq5 create mode 100644 Documents/BKP/x-121.smc.xwz.signal.class.mq5 create mode 100644 Documents/BKP/x-121.smc.xwz.signal.lib copy.mq5 create mode 100644 Documents/BKP/x-121.smc.xwz.signal.lib.mq5 diff --git a/Documents/BKP/Test.mq5 b/Documents/BKP/Test.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..35310c1d7897c65f69a75c1fa52b0a57dfe45e04 GIT binary patch literal 8908 zcmd5>Yfl?T6uqA-^*^krgiJ{TPSp=>+DHWR0f{6QP@*V`5MUFWI=16SC~5lF+nzJm z*E6#_yV$OqTC4T!Ywp}R_so5a|Nd)7c4S+=TZ3a;zLu|`&5nGQOkT)PTGGbvQ|U@y zuH-jq;C_tr3cr24c_{DYgZzN6SATqtwAsga1G&SP9eFD^7(bIovWxS3d4TIzct640 zOrFaHv}&(dqgWe`KZZUd`N`pRD?Aj9F7S8=g!<582YU4IJHeMka)j%EYV&`t)o)XTvh2cAd|xS75~$qwQBUfQGx?!+08z!g0u?@V@C*WH_>F zLLWMD>$NR5ep8Mx!YM{LfDdTm>J_ffFxnAxJ8(Mg&PKJFm5o4L=$**(VPXs)$2iYA z^3oq?vTaR-GpR{;dhL#6GXBMJYpW9RV`zhMqftb9`5wX2t9_#VY!Oen@#)Bv&du31tGs0-`dCV7+zVosw;E|T(35*gtC7b1{B}jMSoic{=k}8F*qiybS%7+?+$XVePVx!FYV_q6%lq{QuFUgMfoTz*|^eW5k2 z&BOYzqI{2&F^shmnLQm>Io*BEen9 ziCe>At*Ui2t7q!VDk`j*S=-tUcUV`)s2GB^8KxabAud`$^X_My9yQk09qj0DPuXku zYSm(Q)?T`KbX}j(l!aVfT&X(FH4y7MAE32}^|UsY;MrC!B}CLDStdee>G^%ctr zeJ!oJjkCx|WomskQc82fF&|5HXGf!Te$U5vHXpk7wP)qKDO;44ydx`9`fnnB(v~_y z`!c;Q$>nzmE*q|CPTO0bo5WV%cI&4G8~CWch1E%`7UPrG)b@u>zO|b9R$0O`y5sh< ziYRA}k@OVIv+aG%e?HZ$+;;a;W9kSs$VhYkiJN_h$Z0{Y#yy*#wbf`V>+D-?Q~KE# zh_!8W*v8Qi{hsa=rX?Od5kB6IiGkPm{ub zXqdy&>#%-J*_PfaZNEkJZD8H$KO%7ioKI)= 2) + { + prevBullishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBearishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBearishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + + // + hasLastBullishConsolidationZone = lastBullishConsolidationZone.IsValid(); + hasLastBearishConsolidationZone = lastBearishConsolidationZone.IsValid(); + hasPrevBullishConsolidationZone = prevBullishConsolidationZone.IsValid(); + hasPrevBearishConsolidationZone = prevBearishConsolidationZone.IsValid(); + + // + isLastBullishConsolidationZoneInsidePivot = + // + hasLastBullishConsolidationZone && + (lastBullishConsolidationZone.lower < point && + lastBullishConsolidationZone.upper > pivot) + // + ; + isPrevBullishConsolidationZoneInsidePivot = + // + hasPrevBullishConsolidationZone && + (prevBullishConsolidationZone.lower < point && + prevBullishConsolidationZone.upper > pivot) + // + ; + + // + isLastBearishConsolidationZoneInsidePivot = + // + hasLastBearishConsolidationZone && + (lastBearishConsolidationZone.upper > point && + lastBearishConsolidationZone.lower < pivot) + // + ; + isPrevBearishConsolidationZoneInsidePivot = + // + hasPrevBearishConsolidationZone && + (prevBearishConsolidationZone.upper > point && + prevBearishConsolidationZone.lower < pivot) + // + ; + } + + // + bool isConsolidationZonePassed = + isBullish + // + ? (point > 0 && + pivot > 0 && + pivot < point && + hasPrevBullishConsolidationZone && + point > prevBullishConsolidationZone.upper && + (isLastBullishConsolidationZoneInsidePivot || + isPrevBullishConsolidationZoneInsidePivot)) + : (point > 0 && + pivot > 0 && + pivot > point && + hasPrevBearishConsolidationZone && + point < prevBearishConsolidationZone.lower && + (isLastBearishConsolidationZoneInsidePivot || + isPrevBearishConsolidationZoneInsidePivot)) + // + ; + + // + result = hasConditions && + hasRewardAmount && + isPriorityPassed && + trend == conditionsDir; // && + // isConsolidationZonePassed; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + mConditions.pivot = pivot; + mConditions.point = point; + mConditions.reward = reward; + mConditions.target = target; + mConditions.setupTime = cTime; + mConditions.priority = priority; + mConditions.dir = conditionsDir; + mConditions.amountPercent = amountPercent; + + // + mConditions.UpdateTo(cTime); + + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + + // + return result; + } + + // + // Detect Trigger Conditions ... + bool DetectSignalTrigger( + // + X121SMCStrategyXWZSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 30 + // + ) + { + // + bool result = false; + + // + result = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + if (!result) + { + return result; + } + + // + 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) + { + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish && + isPointBreaked && + cBar.IsBullish() + // + ; + + // + isBearish = + // + isBearish && + isPointBreaked && + cBar.IsBearish() + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionState.Clean(); + decisionConditions.Clean(); + decisionXConditions.Clean(); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + // Manipulate SL Based on Consolidation Zones ... + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + // TODO: Add Consolidation Zone for SLs ... + + // + double iAtr = decisionXConditions.atrBuffer[1]; + iAtr *= 2; + + // + 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.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionState.Clean(); + decisionConditions.Clean(); + decisionXConditions.Clean(); + + // + return result; + } + + // + // Detect Guards ... + bool DetectGuards( + // + X121SMCGuard &guards[], + const XPosition &positions[], + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // + ) + { + // + bool result = false; + + // + Clean(guards); + + // + bool isCycleHelpersValid = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + + // + result = isCycleHelpersValid; + if (!result) + { + return result; + } + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + string symbol = decisionCycleHelper.GetSymbol(); + ENUM_TIMEFRAMES period = decisionCycleHelper.GetPeriod(); + string provider = ToString(X_121_SMC_PROVIDER_XWZ); + + // + XPosition ownPositions[]; + XPosition ownLongPositions[]; + XPosition ownShortPositions[]; + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + bool isOwn = iPosition + .IsFiltersPassed( + symbol, + provider, + NULL, + X_POSITION_TYPE_ALL, + iPosition.magic // + ); + if (isOwn) + { + // + AddRef( + iPosition, + ownPositions // + ); + + // + bool isLong = IsLong(positions[i].type); + if (isLong) + { + // + AddRef( + iPosition, + ownLongPositions // + ); + } + else + { + // + AddRef( + iPosition, + ownShortPositions // + ); + } + } + } + + // + count = ArraySize(ownPositions); + + // + int longsCount = ArraySize(ownLongPositions); + bool hasLongs = IsValidSize(longsCount); + + // + int shortsCount = ArraySize(ownShortPositions); + bool hasShorts = IsValidSize(shortsCount); + + // + result = IsValidSize(count); + if (!result) + { + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + return result; + } + + // + // + // + + // + // Get Global and Common Guards ... + + // + ENUM_X_121_SMC_GUARD_ACTIONS ignoreGuards[1] = { + X_121_SMC_GUARD_ACTION_TRAIL_STOP // + }; + result = DetectX121SMCGuards( + provider, + guards, + positions, + decisionCycleHelper, + analyseCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + ignoreGuards + // + ); + + // + // + // + + // + // Get Custom Implemented Guards ... + + // + // Here we Are Sure there is Positions to Guard ... + // based on Current Provider ... + + // + // Detect Required Data for Analyse Market to Guard Positions ... + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + // + result = HasChild(guards); + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + // + zBar.Clean(); + result = HasChild(guards); + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + result = HasChild(guards); + return result; + } + + // + XOHCL ppBar; + result = ppBar.Init( + symbol, + period, + ppIndex // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + result = HasChild(guards); + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + result = HasChild(guards); + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + + // + analyseConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + + // + analyseConditions.Clean(); + + // + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + consolidationConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // + // + + // + // Detect Consolidation Zone ... + + // + XBoxZone lastBullishBox; + XBoxZone prevLastBullishBox; + bool hasLastBullishBox = false; + bool hasPrevLastBullishBox = false; + XConsolidationZone lastBullishZone; + bool isLastBullishAbovePrev = false; + bool isLastBullishBelowPrev = false; + XConsolidationZone prevLastBullishZone; + + // + XBoxZone lastBearishBox; + XBoxZone prevLastBearishBox; + bool hasLastBearishBox = false; + bool hasPrevLastBearishBox = false; + XConsolidationZone lastBearishZone; + bool isLastBearishAbovePrev = false; + bool isLastBearishBelowPrev = false; + XConsolidationZone prevLastBearishZone; + + // + int bullishConsolidationZonesCount = 0; + int bearishConsolidationZonesCount = 0; + bool hasBullishConsolidationZones = false; + bool hasBearishConsolidationZones = false; + XConsolidationZone bullishConsolidationZones[]; + XConsolidationZone bearishConsolidationZones[]; + bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones(); + int consolidationZonesCount = decisionCycleHelper.CountConsolidationZones(); + if (hasConsolidationZones) + { + // + bullishConsolidationZonesCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BULLISH, + bullishConsolidationZones // + ); + hasBullishConsolidationZones = IsValidSize(bullishConsolidationZonesCount); + + // + bearishConsolidationZonesCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + bearishConsolidationZones // + ); + hasBearishConsolidationZones = IsValidSize(bearishConsolidationZonesCount); + + // + // + // + + // + if (hasBullishConsolidationZones && + bullishConsolidationZonesCount >= 2) + { + // + lastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 1]; + prevLastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 2]; + + // + hasLastBullishBox = ToBox( + lastBullishBox, + lastBullishZone // + ); + hasPrevLastBullishBox = ToBox( + prevLastBullishBox, + prevLastBullishZone // + ); + + // + isLastBullishAbovePrev = hasLastBullishBox && + hasPrevLastBullishBox && + IsBoxAbove( + lastBullishBox, + prevLastBullishBox // + ); + + // + isLastBullishBelowPrev = hasLastBullishBox && + hasPrevLastBullishBox && + IsBoxBelow( + lastBullishBox, + prevLastBullishBox // + ); + } + + // + if (hasBearishConsolidationZones && + bearishConsolidationZonesCount >= 2) + { + // + lastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 1]; + prevLastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 2]; + + // + hasLastBearishBox = ToBox( + lastBearishBox, + lastBearishZone // + ); + hasPrevLastBearishBox = ToBox( + prevLastBearishBox, + prevLastBearishZone // + ); + + // + isLastBearishAbovePrev = hasLastBearishBox && + hasPrevLastBearishBox && + IsBoxAbove( + lastBearishBox, + prevLastBearishBox // + ); + + // + isLastBearishBelowPrev = hasLastBearishBox && + hasPrevLastBearishBox && + IsBoxBelow( + lastBearishBox, + prevLastBearishBox // + ); + } + + // + } + + // + // Detect High Probability Swings ... + bool isSwingLow = + // + cBar.low > pBar.low && + ppBar.low > pBar.low && + // + zBar.low > pBar.low + // + ; + bool isSwingHigh = + // + cBar.high < pBar.high && + ppBar.high < pBar.high && + // + zBar.high < pBar.high + // + ; + bool isStrongSwingLow = + pBar.IsBullish() && + pBar.GetLowShadow() >= pBar.GetBody() * 2; + bool isStrongSwingHigh = + pBar.IsBearish() && + pBar.GetHighShadow() >= pBar.GetBody() * 2; + + // + bool isStrongSwingLowAboveLastBullishBox = + isStrongSwingLow && + hasLastBullishBox && + pBar.low > lastBullishBox.upper; + + // + bool isStrongSwingHighBelowLastBearishBox = + isStrongSwingHigh && + hasLastBearishBox && + pBar.high < lastBearishBox.lower; + + // + // Here We Have all Requirements for Guarding Positions ... + + // + // Available Guards: + // X_121_SMC_GUARD_ACTION_NONE + // X_121_SMC_GUARD_ACTION_CLOSE + // X_121_SMC_GUARD_ACTION_CLOSE_ALL + // X_121_SMC_GUARD_ACTION_CLOSE_LONGS + // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS + // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE + // X_121_SMC_GUARD_ACTION_TRAIL_STOP + // X_121_SMC_GUARD_ACTION_TRAIL_TARGET + // X_121_SMC_GUARD_ACTION_HEDGE + + // + // X_121_SMC_GUARD_ACTION_CLOSE: + // Close Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_ALL: + // Close All Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_LONGS: + // Close All Long Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS: + // Close All Short Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE: + // Partial Close Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_TRAIL_STOP: + // Trail Stop Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_TRAIL_TARGET: + // Trail Target Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_HEDGE: + // Hedge all Positions on Specified Conditions ... + + // + // Cleanup Collections ... + + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(visionCycleEvents); + Clean(decisionPoiEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + decisionConditions.Clean(); + consolidationState.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishBox.Clean(); + lastBearishBox.Clean(); + lastBullishZone.Clean(); + lastBearishZone.Clean(); + prevLastBullishBox.Clean(); + prevLastBearishBox.Clean(); + prevLastBullishZone.Clean(); + prevLastBearishZone.Clean(); + + // + count = ArraySize(guards); + result = IsValidSize(count); + + // + return result; + } + + // + // + // + + // + // Add Conditions to Conditions Collection ... + int AddConditionsIfNotExists( + int maxAllowed = 10 // + ) + { + // + int result = 0; + + // + bool isSetuped = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(mConditionsCollection); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXWZSignalConditions tmpItems[]; + Copy( + mConditionsCollection, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(mConditions.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXWZSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = mConditions.dir == iItem.dir && + mConditions.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + mConditionsCollection, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + mConditions, + mConditionsCollection // + ); + + // + // Remove Olds ... + CleanupArray( + mConditionsCollection, + maxAllowed // + ); + + // + result = ArraySize(mConditionsCollection); + + // + return result; + } + + // + // Draw Functions ... + // + + // + void RemoveDraws() + { + mObjects.Clear(); + } + + // + void RemoveWorkingZoneDraws() + { + mWorkingZoneObjects.Clear(); + } + + // + void DrawOrderBlock( + XCOrderBlock *ob, + XCPOIDrawer *drawer, + bool forWorkingZone = false // + ) + { + // + if (ob == NULL || + drawer == NULL) + { + return; + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + + // + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + color forColor = IsBullish(forDir) + ? bullishColor + : bearishColor; + + // + // Draw Order Block ... + XCBaseObject *obj; + bool isCreated = drawer.CreateOrderBlock( + ob, + obj // + ); + if (isCreated) + { + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = ob.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (isStarted) + { + // + datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); + + // + XCOHCLObject *obj; + bool isCreated = drawer.CreateBar( + startedBar, + obj, + to // + ); + if (isCreated) + { + // + obj.BodyColor(clrYellow); + obj.HighShadowColor(clrYellow); + obj.LowShadowColor(clrYellow); + + // + obj.BodyStyle(STYLE_SOLID); + obj.HighShadowStyle(STYLE_SOLID); + obj.LowShadowStyle(STYLE_SOLID); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + string startVLineName = "Start_" + ob.GetTag(); + + // + CChartObjectVLine *startVLine; + startVLine = new CChartObjectVLine(); + isCreated = startVLine.Create( + chartID, + startVLineName, + subWindow, + startedBar.time // + ); + if (isCreated) + { + // + startVLine.Color(forColor); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } + } + } + } + + // + void DrawFairValueGap( + XCFVG *fvg, + XCPOIDrawer *drawer, + bool forWorkingZone = false // + ) + { + // + if (fvg == NULL || + drawer == NULL) + { + return; + } + + // + ENUM_X_DIRECTION forDir = fvg.GetDirection(); + + // + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + color forColor = IsBullish(forDir) + ? bullishColor + : bearishColor; + + // + // Draw Order Block ... + XCBaseObject *obj; + bool isCreated = drawer.CreateFairValueGap( + fvg, + obj // + ); + if (isCreated) + { + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = fvg.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (isStarted) + { + // + datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); + + // + XCOHCLObject *obj; + bool isCreated = drawer.CreateBar( + startedBar, + obj, + to // + ); + if (isCreated) + { + // + obj.BodyColor(clrYellow); + obj.HighShadowColor(clrYellow); + obj.LowShadowColor(clrYellow); + + // + obj.BodyStyle(STYLE_SOLID); + obj.HighShadowStyle(STYLE_SOLID); + obj.LowShadowStyle(STYLE_SOLID); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + string startVLineName = "Start_" + fvg.GetTag(); + + // + CChartObjectVLine *startVLine; + startVLine = new CChartObjectVLine(); + isCreated = startVLine.Create( + chartID, + startVLineName, + subWindow, + startedBar.time // + ); + if (isCreated) + { + // + startVLine.Color(forColor); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } + } + } + } + + // + void DrawWorkingZone( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + bool hasWorkingZone = conditions.HasWorkingZone(); + if (!hasWorkingZone) + { + return; + } + + // + string prefix = "WKZ_" + conditions.workingZone.symbol + ToString(conditions.workingZone.period) + "_"; + string tag = prefix + ToString(conditions.workingZone.upper) + "_" + ToString(conditions.workingZone.lower); + string suffix = ToMD5(tag); + + // + string upperName = prefix + "_Upper_" + suffix; + string lowerName = prefix + "_Lower_" + suffix; + string zoneUpperName = prefix + "_ZoneUpper_" + suffix; + string zoneLowerName = prefix + "_ZoneLower_" + suffix; + + // + string q1Name = prefix + "_Q1_" + suffix; + string q2Name = prefix + "_Q2_" + suffix; + string q3Name = prefix + "_Q3_" + suffix; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + bool isCreated = false; + + // + // Check For Trend Approced ... + bool isTrendApproved = conditions.HasOrderBlock() && + conditions.HasFairValueGap(); + if (isTrendApproved) + { + // + DrawOrderBlock( + conditions.orderBlock, + drawer, + true // + ); + + // + DrawFairValueGap( + conditions.fairValueGap, + drawer, + true // + ); + } + + // + XCSupplyZoneObject *iSupObj; + isCreated = drawer.CreateSupplyZone( + conditions.supplyZone, + iSupObj // + ); + if (isCreated) + { + mWorkingZoneObjects.Add(iSupObj); + } + + // + XCDemandZoneObject *iDemObj; + isCreated = drawer.CreateDemandZone( + conditions.demandZone, + iDemObj // + ); + if (isCreated) + { + mWorkingZoneObjects.Add(iDemObj); + } + + // + // Lower ... + CChartObjectTrend *lowerHLine; + lowerHLine = new CChartObjectTrend(); + isCreated = lowerHLine.Create( + chartID, + lowerName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.lower, + conditions.workingZone.to, + conditions.workingZone.lower // + ); + if (isCreated) + { + // + lowerHLine.Color(clrLime); + mWorkingZoneObjects.Add(lowerHLine); + } + + // + CChartObjectTrend *upperHLine; + upperHLine = new CChartObjectTrend(); + isCreated = upperHLine.Create( + chartID, + upperName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.upper, + conditions.workingZone.to, + conditions.workingZone.upper // + ); + if (isCreated) + { + // + upperHLine.Color(clrLime); + mWorkingZoneObjects.Add(upperHLine); + } + + // + CChartObjectTrend *zoneLowerHLine; + zoneLowerHLine = new CChartObjectTrend(); + isCreated = zoneLowerHLine.Create( + chartID, + zoneLowerName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.zoneLower, + conditions.workingZone.to, + conditions.workingZone.zoneLower // + ); + if (isCreated) + { + // + zoneLowerHLine.Color(clrRed); + mWorkingZoneObjects.Add(zoneLowerHLine); + } + + // + CChartObjectTrend *zoneUpperHLine; + zoneUpperHLine = new CChartObjectTrend(); + isCreated = zoneUpperHLine.Create( + chartID, + zoneUpperName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.zoneUpper, + conditions.workingZone.to, + conditions.workingZone.zoneUpper // + ); + if (isCreated) + { + // + zoneUpperHLine.Color(clrRed); + mWorkingZoneObjects.Add(zoneUpperHLine); + } + + // + CChartObjectTrend *quarter1HLine; + quarter1HLine = new CChartObjectTrend(); + isCreated = quarter1HLine.Create( + chartID, + q1Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter1, + conditions.workingZone.to, + conditions.workingZone.quarter1 // + ); + if (isCreated) + { + // + quarter1HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter1HLine); + } + + // + CChartObjectTrend *quarter2HLine; + quarter2HLine = new CChartObjectTrend(); + isCreated = quarter2HLine.Create( + chartID, + q2Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter2, + conditions.workingZone.to, + conditions.workingZone.quarter2 // + ); + if (isCreated) + { + // + quarter2HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter2HLine); + } + + // + CChartObjectTrend *quarter3HLine; + quarter3HLine = new CChartObjectTrend(); + isCreated = quarter3HLine.Create( + chartID, + q3Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter3, + conditions.workingZone.to, + conditions.workingZone.quarter3 // + ); + if (isCreated) + { + // + quarter3HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter3HLine); + } + + // + } + + // + void DrawConditions( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer, + bool forceClean = false // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + if (forceClean) + { + mObjects.Clear(); + } + + // + bool isCreated = false; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + + // + // Start Zones ... + bool hasStartZones = conditions.HasStartZones(); + if (hasStartZones) + { + // + int count = conditions.CountStartZones(); + for (int i = 0; i < count; i++) + { + // + bool isBullish = conditions.startZones[i].IsBullish(); + + // + bool hasOB = conditions.startZones[i].HasOB(); + if (hasOB) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateOrderBlock( + // conditions.startZones[i].ob, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawOrderBlock( + conditions.startZones[i].ob, + drawer // + ); + } + + // + bool hasFVG = conditions.startZones[i].HasFVG(); + if (hasFVG) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateFairValueGap( + // conditions.startZones[i].fvg, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawFairValueGap( + conditions.startZones[i].fvg, + drawer // + ); + } + + // // + // bool hasSupply = conditions.startZones[i].HasSupply(); + // if (hasSupply) + // { + // // + // XCSupplyZoneObject *iObj; + // isCreated = drawer.CreateSupplyZone( + // conditions.startZones[i].supply, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // // + // bool hasDemand = conditions.startZones[i].HasDemand(); + // if (hasDemand) + // { + // // + // XCDemandZoneObject *iObj; + // isCreated = drawer.CreateDemandZone( + // conditions.startZones[i].demand, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // // + // bool hasSupport = conditions.startZones[i].HasSupport(); + // if (hasSupport) + // { + // // + // XCSupportZoneObject *iObj; + // isCreated = drawer.CreateSupportZone( + // conditions.startZones[i].support, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // // + // bool hasResistance = conditions.startZones[i].HasResistance(); + // if (hasResistance) + // { + // // + // XCResistanceZoneObject *iObj; + // isCreated = drawer.CreateResistanceZone( + // conditions.startZones[i].resistance, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // + // + // + + // + string bName = ""; + int arrowCode = 0; + string bSuffix = ""; + color arrowColor = clrNONE; + ENUM_X_PRICE bPrice = X_PRICE_CLOSE; + + // + bool hasSwingBar = conditions.startZones[i].swingBar.IsValid(); + if (hasSwingBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].swingBar.GetTag()); + bName = + (isBullish + ? "SWING_LOW" + : "SWING_HIGH") + + "_" + bSuffix; + arrowCode = 159; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].swingBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasBreakerBar = conditions.startZones[i].breakerBar.IsValid(); + if (hasBreakerBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].breakerBar.GetTag()); + bName = + (isBullish + ? "BULL_BREAKER" + : "BEAR_BREAKER") + + "_" + bSuffix; + arrowCode = + isBullish + ? 71 + : 72; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].breakerBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasMomentumBar = conditions.startZones[i].momentumBar.IsValid(); + if (hasMomentumBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].momentumBar.GetTag()); + bName = + (isBullish + ? "BULL_MOMENTUM" + : "BEAR_MOMENTUM") + + "_" + bSuffix; + arrowCode = + isBullish + ? 233 + : 234; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].momentumBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasRejectionBar = conditions.startZones[i].rejectionBar.IsValid(); + if (hasRejectionBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].rejectionBar.GetTag()); + bName = + (isBullish + ? "BULL_REJECTION" + : "BEAR_REJECTION") + + "_" + bSuffix; + arrowCode = + isBullish + ? 241 + : 242; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].rejectionBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasAppliedBox = conditions.startZones[i].appliedBox.IsValid(); + if (hasAppliedBox) + { + // + arrowColor = + IsBullish(conditions.startZones[i].appliedBox.dir) + ? bullishColor + : bearishColor; + + // + XCBoxObject *iObj; + isCreated = drawer.CreateBox( + conditions.startZones[i].appliedBox, + iObj // + ); + + // + if (isCreated) + { + // + iObj.BoxWidth(2); + iObj.BoxColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + } + } + } + + // + protected: + // + + // + private: + // + // Props ... + CArrayObj mObjects; + CArrayObj mWorkingZoneObjects; + + /** + * Initialize ... + */ + void Init() + { + } + + /** + * DeInitialize ... + */ + void DeInit() + { + // + RemoveDraws(); + mConditions.Clean(); + RemoveWorkingZoneDraws(); + Clean(mConditionsCollection); + } + + // + // Helpers ... + + // + bool CalculateRiskReward( + ENUM_X121SMC_XWZ_PRIORITY priority, + double &reward, + double &amountPercent // + ) + { + // + bool result = false; + + // + reward = 0; + amountPercent = 0; + + // + result = priority != X121SMC_XWZ_PRIORITY_NONE; + if (!result) + { + return result; + } + + // + switch (priority) + { + // + case X121SMC_XWZ_PRIORITY_STRONG_HIGH: + // + reward = 6; + amountPercent = 2; + break; + + // + case X121SMC_XWZ_PRIORITY_HIGH: + // + reward = 4; + amountPercent = 2; + break; + + // + case X121SMC_XWZ_PRIORITY_REGULAR: + // + reward = 3; + amountPercent = 1.5; + break; + + // + case X121SMC_XWZ_PRIORITY_LOW: + // + reward = 2; + amountPercent = 1; + break; + + // + case X121SMC_XWZ_PRIORITY_WEAK: + // + reward = 1; + amountPercent = 0.5; + break; + } + + // + result = + // + reward > 0 && + amountPercent > 0 + // + ; + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.xwz.signal.class.mq5 b/Documents/BKP/x-121.smc.xwz.signal.class.mq5 new file mode 100644 index 00000000..24a476f0 --- /dev/null +++ b/Documents/BKP/x-121.smc.xwz.signal.class.mq5 @@ -0,0 +1,2725 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XWZ +// 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 "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" +#include "./x-121.smc.xwz.signal.lib.mq5" + +// +// Definition ... +class XCX121SMCXWZSignalDetector : public XCBase +{ + // + public: + // + // Props ... + X121SMCStrategyXWZSignalConditions mConditions; + X121SMCStrategyXWZSignalConditions mConditionsCollection[]; + + // + // Constructor(s) ... + XCX121SMCXWZSignalDetector() + { + Init(); + } + + // + // Deconstructor ... + ~XCX121SMCXWZSignalDetector() + { + DeInit(); + } + + // + // + // + + // + // Detect Setup Conditions ... + bool DetectSignalSetup( + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // + ) + { + // + bool result = false; + + // + // Validate Cycle Helpers ... + result = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + 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; + + // + mConditions.symbol = symbol; + mConditions.period = period; + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + double target = 0; + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + // Check Working Zone ... + bool hasWorkingZone = mConditions.HasWorkingZone(); + if (!hasWorkingZone) + { + // + hasWorkingZone = mConditions.ExtractWorkingZone( + visionState, + consolidationState, + analyseState, + zIndex // + ); + } + + // + result = hasWorkingZone; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + mConditions.UpdateTo(cTime); + + // + // Check Working Zone still Alive ... + ENUM_X_DIRECTION destroyedDir = X_DIRECTION_NONE; + bool isWorkingZoneDestroyed = mConditions + .IsWorkingZoneDestroyed( + destroyedDir, + zIndex, + decisionState.period // + ); + if (isWorkingZoneDestroyed) + { + RemoveWorkingZoneDraws(); + } + + // + result = !isWorkingZoneDestroyed; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + // Detecting Trend ... + ENUM_X_DIRECTION trend; + bool hasTrend = mConditions.DetectTrend( + trend, + period // + ); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + result = hasTrend; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + // bool hasStartZone = mConditions.DetectStartZones( + // trend, + // consolidationState, + // analyseState, + // decisionState, + // decisionCycleHelper // + // ); + + // + mConditions.UpdateTo(cTime); + + // + // Detect Condition Priority ... + ENUM_X121SMC_XWZ_PRIORITY bullishPriority; + ENUM_X121SMC_XWZ_PRIORITY bearishPriority; + mConditions.DetectPriority( + bullishPriority, + bearishPriority // + ); + + // + bool canLookupLong = bullishPriority != X121SMC_XWZ_PRIORITY_NONE && + bullishPriority != X121SMC_XWZ_PRIORITY_WEAK; + bool canLookupShort = bearishPriority != X121SMC_XWZ_PRIORITY_NONE && + bearishPriority != X121SMC_XWZ_PRIORITY_WEAK; + bool isPriorityPassed = + hasBullishTrend + ? canLookupLong + : hasBearishTrend + ? canLookupShort + : false; + + // + // Here we are Make sure we have Correct: + // - WorkSpace ... + // - Trend ... + // - What we looking for: Long or Short ... + // - Priority ... + + // + double pivot = 0; + double point = 0; + ENUM_X_DIRECTION conditionsDir = X_DIRECTION_NONE; + + // + // Detect Start Zone Conditions ... + bool hasConditions = mConditions + .HasConditions( + pivot, + point, + conditionsDir, + decisionState, + zIndex, + decisionState.period // + ); + result = hasConditions; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + return result; + } + + // + isBullish = IsBullish(conditionsDir); + isBearish = IsBearish(conditionsDir); + + // + double reward; + double amountPercent; + ENUM_X121SMC_XWZ_PRIORITY priority = + isBullish + ? bullishPriority + : bearishPriority; + bool hasRewardAmount = CalculateRiskReward( + priority, + reward, + amountPercent // + ); + + // + // Apply Traget ... + switch (priority) + { + // + case X121SMC_XWZ_PRIORITY_STRONG_HIGH: + // + target = + isBullish + ? mConditions.workingZone.quarter3 + : mConditions.workingZone.quarter1; + break; + + // + case X121SMC_XWZ_PRIORITY_HIGH: + // + target = + isBullish + ? mConditions.workingZone.quarter3 + : mConditions.workingZone.quarter1; + break; + + // + case X121SMC_XWZ_PRIORITY_REGULAR: + // + target = + isBullish + ? mConditions.workingZone.quarter2 + : mConditions.workingZone.quarter2; + break; + + // + case X121SMC_XWZ_PRIORITY_LOW: + // + target = + isBullish + ? mConditions.workingZone.quarter1 + : mConditions.workingZone.quarter3; + break; + + // + default: + target = 0; + break; + } + + // + bool hasLastBullishConsolidationZone = false; + bool hasLastBearishConsolidationZone = false; + bool hasPrevBullishConsolidationZone = false; + bool hasPrevBearishConsolidationZone = false; + XConsolidationZone lastBullishConsolidationZone; + XConsolidationZone lastBearishConsolidationZone; + XConsolidationZone prevBullishConsolidationZone; + XConsolidationZone prevBearishConsolidationZone; + bool isLastBullishConsolidationZoneInsidePivot = false; + bool isPrevBullishConsolidationZoneInsidePivot = false; + bool isLastBearishConsolidationZoneInsidePivot = false; + bool isPrevBearishConsolidationZoneInsidePivot = false; + bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones(); + if (hasConsolidationZones) + { + // + int cZCount = 0; + XConsolidationZone tmp[]; + + // + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BULLISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBullishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBullishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBearishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBearishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + + // + hasLastBullishConsolidationZone = lastBullishConsolidationZone.IsValid(); + hasLastBearishConsolidationZone = lastBearishConsolidationZone.IsValid(); + hasPrevBullishConsolidationZone = prevBullishConsolidationZone.IsValid(); + hasPrevBearishConsolidationZone = prevBearishConsolidationZone.IsValid(); + + // + isLastBullishConsolidationZoneInsidePivot = + // + hasLastBullishConsolidationZone && + (lastBullishConsolidationZone.lower < point && + lastBullishConsolidationZone.upper > pivot) + // + ; + isPrevBullishConsolidationZoneInsidePivot = + // + hasPrevBullishConsolidationZone && + (prevBullishConsolidationZone.lower < point && + prevBullishConsolidationZone.upper > pivot) + // + ; + + // + isLastBearishConsolidationZoneInsidePivot = + // + hasLastBearishConsolidationZone && + (lastBearishConsolidationZone.upper > point && + lastBearishConsolidationZone.lower < pivot) + // + ; + isPrevBearishConsolidationZoneInsidePivot = + // + hasPrevBearishConsolidationZone && + (prevBearishConsolidationZone.upper > point && + prevBearishConsolidationZone.lower < pivot) + // + ; + } + + // + bool isConsolidationZonePassed = + isBullish + // + ? (point > 0 && + pivot > 0 && + pivot < point && + hasPrevBullishConsolidationZone && + point > prevBullishConsolidationZone.upper && + (isLastBullishConsolidationZoneInsidePivot || + isPrevBullishConsolidationZoneInsidePivot)) + : (point > 0 && + pivot > 0 && + pivot > point && + hasPrevBearishConsolidationZone && + point < prevBearishConsolidationZone.lower && + (isLastBearishConsolidationZoneInsidePivot || + isPrevBearishConsolidationZoneInsidePivot)) + // + ; + + // + result = hasConditions && + hasRewardAmount && + isPriorityPassed && + trend == conditionsDir; // && + // isConsolidationZonePassed; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + mConditions.pivot = pivot; + mConditions.point = point; + mConditions.reward = reward; + mConditions.target = target; + mConditions.setupTime = cTime; + mConditions.priority = priority; + mConditions.dir = conditionsDir; + mConditions.amountPercent = amountPercent; + + // + mConditions.UpdateTo(cTime); + + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + + // + return result; + } + + // + // Detect Trigger Conditions ... + bool DetectSignalTrigger( + // + X121SMCStrategyXWZSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 30 + // + ) + { + // + bool result = false; + + // + result = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + if (!result) + { + return result; + } + + // + 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) + { + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish && + isPointBreaked && + cBar.IsBullish() + // + ; + + // + isBearish = + // + isBearish && + isPointBreaked && + cBar.IsBearish() + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionState.Clean(); + decisionConditions.Clean(); + decisionXConditions.Clean(); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + // Manipulate SL Based on Consolidation Zones ... + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + // TODO: Add Consolidation Zone for SLs ... + + // + double iAtr = decisionXConditions.atrBuffer[1]; + iAtr *= 2; + + // + 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.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionState.Clean(); + decisionConditions.Clean(); + decisionXConditions.Clean(); + + // + return result; + } + + // + // Detect Guards ... + bool DetectGuards( + // + X121SMCGuard &guards[], + const XPosition &positions[], + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // + ) + { + // + bool result = false; + + // + Clean(guards); + + // + bool isCycleHelpersValid = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + + // + result = isCycleHelpersValid; + if (!result) + { + return result; + } + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + string symbol = decisionCycleHelper.GetSymbol(); + ENUM_TIMEFRAMES period = decisionCycleHelper.GetPeriod(); + string provider = ToString(X_121_SMC_PROVIDER_XWZ); + + // + XPosition ownPositions[]; + XPosition ownLongPositions[]; + XPosition ownShortPositions[]; + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + bool isOwn = iPosition + .IsFiltersPassed( + symbol, + provider, + NULL, + X_POSITION_TYPE_ALL, + iPosition.magic // + ); + if (isOwn) + { + // + AddRef( + iPosition, + ownPositions // + ); + + // + bool isLong = IsLong(positions[i].type); + if (isLong) + { + // + AddRef( + iPosition, + ownLongPositions // + ); + } + else + { + // + AddRef( + iPosition, + ownShortPositions // + ); + } + } + } + + // + count = ArraySize(ownPositions); + + // + int longsCount = ArraySize(ownLongPositions); + bool hasLongs = IsValidSize(longsCount); + + // + int shortsCount = ArraySize(ownShortPositions); + bool hasShorts = IsValidSize(shortsCount); + + // + result = IsValidSize(count); + if (!result) + { + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + return result; + } + + // + // + // + + // + // Get Global and Common Guards ... + + // + ENUM_X_121_SMC_GUARD_ACTIONS ignoreGuards[1] = { + X_121_SMC_GUARD_ACTION_TRAIL_STOP // + }; + result = DetectX121SMCGuards( + provider, + guards, + positions, + decisionCycleHelper, + analyseCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + ignoreGuards + // + ); + + // + // + // + + // + // Get Custom Implemented Guards ... + + // + // Here we Are Sure there is Positions to Guard ... + // based on Current Provider ... + + // + // Detect Required Data for Analyse Market to Guard Positions ... + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + // + result = HasChild(guards); + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + // + zBar.Clean(); + result = HasChild(guards); + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + result = HasChild(guards); + return result; + } + + // + XOHCL ppBar; + result = ppBar.Init( + symbol, + period, + ppIndex // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + result = HasChild(guards); + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + result = HasChild(guards); + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + + // + analyseConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + + // + analyseConditions.Clean(); + + // + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + consolidationConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // + // + + // + // Detect Consolidation Zone ... + + // + XBoxZone lastBullishBox; + XBoxZone prevLastBullishBox; + bool hasLastBullishBox = false; + bool hasPrevLastBullishBox = false; + XConsolidationZone lastBullishZone; + bool isLastBullishAbovePrev = false; + bool isLastBullishBelowPrev = false; + XConsolidationZone prevLastBullishZone; + + // + XBoxZone lastBearishBox; + XBoxZone prevLastBearishBox; + bool hasLastBearishBox = false; + bool hasPrevLastBearishBox = false; + XConsolidationZone lastBearishZone; + bool isLastBearishAbovePrev = false; + bool isLastBearishBelowPrev = false; + XConsolidationZone prevLastBearishZone; + + // + int bullishConsolidationZonesCount = 0; + int bearishConsolidationZonesCount = 0; + bool hasBullishConsolidationZones = false; + bool hasBearishConsolidationZones = false; + XConsolidationZone bullishConsolidationZones[]; + XConsolidationZone bearishConsolidationZones[]; + bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones(); + int consolidationZonesCount = decisionCycleHelper.CountConsolidationZones(); + if (hasConsolidationZones) + { + // + bullishConsolidationZonesCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BULLISH, + bullishConsolidationZones // + ); + hasBullishConsolidationZones = IsValidSize(bullishConsolidationZonesCount); + + // + bearishConsolidationZonesCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + bearishConsolidationZones // + ); + hasBearishConsolidationZones = IsValidSize(bearishConsolidationZonesCount); + + // + // + // + + // + if (hasBullishConsolidationZones && + bullishConsolidationZonesCount >= 2) + { + // + lastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 1]; + prevLastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 2]; + + // + hasLastBullishBox = ToBox( + lastBullishBox, + lastBullishZone // + ); + hasPrevLastBullishBox = ToBox( + prevLastBullishBox, + prevLastBullishZone // + ); + + // + isLastBullishAbovePrev = hasLastBullishBox && + hasPrevLastBullishBox && + IsBoxAbove( + lastBullishBox, + prevLastBullishBox // + ); + + // + isLastBullishBelowPrev = hasLastBullishBox && + hasPrevLastBullishBox && + IsBoxBelow( + lastBullishBox, + prevLastBullishBox // + ); + } + + // + if (hasBearishConsolidationZones && + bearishConsolidationZonesCount >= 2) + { + // + lastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 1]; + prevLastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 2]; + + // + hasLastBearishBox = ToBox( + lastBearishBox, + lastBearishZone // + ); + hasPrevLastBearishBox = ToBox( + prevLastBearishBox, + prevLastBearishZone // + ); + + // + isLastBearishAbovePrev = hasLastBearishBox && + hasPrevLastBearishBox && + IsBoxAbove( + lastBearishBox, + prevLastBearishBox // + ); + + // + isLastBearishBelowPrev = hasLastBearishBox && + hasPrevLastBearishBox && + IsBoxBelow( + lastBearishBox, + prevLastBearishBox // + ); + } + + // + } + + // + // Detect High Probability Swings ... + bool isSwingLow = + // + cBar.low > pBar.low && + ppBar.low > pBar.low && + // + zBar.low > pBar.low + // + ; + bool isSwingHigh = + // + cBar.high < pBar.high && + ppBar.high < pBar.high && + // + zBar.high < pBar.high + // + ; + bool isStrongSwingLow = + pBar.IsBullish() && + pBar.GetLowShadow() >= pBar.GetBody() * 2; + bool isStrongSwingHigh = + pBar.IsBearish() && + pBar.GetHighShadow() >= pBar.GetBody() * 2; + + // + bool isStrongSwingLowAboveLastBullishBox = + isStrongSwingLow && + hasLastBullishBox && + pBar.low > lastBullishBox.upper; + + // + bool isStrongSwingHighBelowLastBearishBox = + isStrongSwingHigh && + hasLastBearishBox && + pBar.high < lastBearishBox.lower; + + // + // Here We Have all Requirements for Guarding Positions ... + + // + // Available Guards: + // X_121_SMC_GUARD_ACTION_NONE + // X_121_SMC_GUARD_ACTION_CLOSE + // X_121_SMC_GUARD_ACTION_CLOSE_ALL + // X_121_SMC_GUARD_ACTION_CLOSE_LONGS + // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS + // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE + // X_121_SMC_GUARD_ACTION_TRAIL_STOP + // X_121_SMC_GUARD_ACTION_TRAIL_TARGET + // X_121_SMC_GUARD_ACTION_HEDGE + + // + // X_121_SMC_GUARD_ACTION_CLOSE: + // Close Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_ALL: + // Close All Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_LONGS: + // Close All Long Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS: + // Close All Short Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE: + // Partial Close Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_TRAIL_STOP: + // Trail Stop Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_TRAIL_TARGET: + // Trail Target Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_HEDGE: + // Hedge all Positions on Specified Conditions ... + + // + // Cleanup Collections ... + + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(visionCycleEvents); + Clean(decisionPoiEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + decisionConditions.Clean(); + consolidationState.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishBox.Clean(); + lastBearishBox.Clean(); + lastBullishZone.Clean(); + lastBearishZone.Clean(); + prevLastBullishBox.Clean(); + prevLastBearishBox.Clean(); + prevLastBullishZone.Clean(); + prevLastBearishZone.Clean(); + + // + count = ArraySize(guards); + result = IsValidSize(count); + + // + return result; + } + + // + // + // + + // + // Add Conditions to Conditions Collection ... + int AddConditionsIfNotExists( + int maxAllowed = 10 // + ) + { + // + int result = 0; + + // + bool isSetuped = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(mConditionsCollection); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXWZSignalConditions tmpItems[]; + Copy( + mConditionsCollection, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(mConditions.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXWZSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = mConditions.dir == iItem.dir && + mConditions.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + mConditionsCollection, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + mConditions, + mConditionsCollection // + ); + + // + // Remove Olds ... + CleanupArray( + mConditionsCollection, + maxAllowed // + ); + + // + result = ArraySize(mConditionsCollection); + + // + return result; + } + + // + // Draw Functions ... + // + + // + void RemoveDraws() + { + mObjects.Clear(); + } + + // + void RemoveWorkingZoneDraws() + { + mWorkingZoneObjects.Clear(); + } + + // + void DrawOrderBlock( + XCOrderBlock *ob, + XCPOIDrawer *drawer, + bool forWorkingZone = false // + ) + { + // + if (ob == NULL || + drawer == NULL) + { + return; + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + + // + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + color forColor = IsBullish(forDir) + ? bullishColor + : bearishColor; + + // + // Draw Order Block ... + XCBaseObject *obj; + bool isCreated = drawer.CreateOrderBlock( + ob, + obj // + ); + if (isCreated) + { + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = ob.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (isStarted) + { + // + datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); + + // + XCOHCLObject *obj; + bool isCreated = drawer.CreateBar( + startedBar, + obj, + to // + ); + if (isCreated) + { + // + obj.BodyColor(clrYellow); + obj.HighShadowColor(clrYellow); + obj.LowShadowColor(clrYellow); + + // + obj.BodyStyle(STYLE_SOLID); + obj.HighShadowStyle(STYLE_SOLID); + obj.LowShadowStyle(STYLE_SOLID); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + string startVLineName = "Start_" + ob.GetTag(); + + // + CChartObjectVLine *startVLine; + startVLine = new CChartObjectVLine(); + isCreated = startVLine.Create( + chartID, + startVLineName, + subWindow, + startedBar.time // + ); + if (isCreated) + { + // + startVLine.Color(forColor); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } + } + } + } + + // + void DrawFairValueGap( + XCFVG *fvg, + XCPOIDrawer *drawer, + bool forWorkingZone = false // + ) + { + // + if (fvg == NULL || + drawer == NULL) + { + return; + } + + // + ENUM_X_DIRECTION forDir = fvg.GetDirection(); + + // + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + color forColor = IsBullish(forDir) + ? bullishColor + : bearishColor; + + // + // Draw Order Block ... + XCBaseObject *obj; + bool isCreated = drawer.CreateFairValueGap( + fvg, + obj // + ); + if (isCreated) + { + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = fvg.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (isStarted) + { + // + datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); + + // + XCOHCLObject *obj; + bool isCreated = drawer.CreateBar( + startedBar, + obj, + to // + ); + if (isCreated) + { + // + obj.BodyColor(clrYellow); + obj.HighShadowColor(clrYellow); + obj.LowShadowColor(clrYellow); + + // + obj.BodyStyle(STYLE_SOLID); + obj.HighShadowStyle(STYLE_SOLID); + obj.LowShadowStyle(STYLE_SOLID); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + string startVLineName = "Start_" + fvg.GetTag(); + + // + CChartObjectVLine *startVLine; + startVLine = new CChartObjectVLine(); + isCreated = startVLine.Create( + chartID, + startVLineName, + subWindow, + startedBar.time // + ); + if (isCreated) + { + // + startVLine.Color(forColor); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } + } + } + } + + // + void DrawWorkingZone( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + bool hasWorkingZone = conditions.HasWorkingZone(); + if (!hasWorkingZone) + { + return; + } + + // + string prefix = "WKZ_" + conditions.workingZone.symbol + ToString(conditions.workingZone.period) + "_"; + string tag = prefix + ToString(conditions.workingZone.upper) + "_" + ToString(conditions.workingZone.lower); + string suffix = ToMD5(tag); + + // + string upperName = prefix + "_Upper_" + suffix; + string lowerName = prefix + "_Lower_" + suffix; + string zoneUpperName = prefix + "_ZoneUpper_" + suffix; + string zoneLowerName = prefix + "_ZoneLower_" + suffix; + + // + string q1Name = prefix + "_Q1_" + suffix; + string q2Name = prefix + "_Q2_" + suffix; + string q3Name = prefix + "_Q3_" + suffix; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + bool isCreated = false; + + // + // Check For Trend Approced ... + bool isTrendApproved = conditions.HasOrderBlock() && + conditions.HasFairValueGap(); + if (isTrendApproved) + { + // + DrawOrderBlock( + conditions.orderBlock, + drawer, + true // + ); + + // + DrawFairValueGap( + conditions.fairValueGap, + drawer, + true // + ); + } + + // + XCSupplyZoneObject *iSupObj; + isCreated = drawer.CreateSupplyZone( + conditions.supplyZone, + iSupObj // + ); + if (isCreated) + { + mWorkingZoneObjects.Add(iSupObj); + } + + // + XCDemandZoneObject *iDemObj; + isCreated = drawer.CreateDemandZone( + conditions.demandZone, + iDemObj // + ); + if (isCreated) + { + mWorkingZoneObjects.Add(iDemObj); + } + + // + // Lower ... + CChartObjectTrend *lowerHLine; + lowerHLine = new CChartObjectTrend(); + isCreated = lowerHLine.Create( + chartID, + lowerName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.lower, + conditions.workingZone.to, + conditions.workingZone.lower // + ); + if (isCreated) + { + // + lowerHLine.Color(clrLime); + mWorkingZoneObjects.Add(lowerHLine); + } + + // + CChartObjectTrend *upperHLine; + upperHLine = new CChartObjectTrend(); + isCreated = upperHLine.Create( + chartID, + upperName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.upper, + conditions.workingZone.to, + conditions.workingZone.upper // + ); + if (isCreated) + { + // + upperHLine.Color(clrLime); + mWorkingZoneObjects.Add(upperHLine); + } + + // + CChartObjectTrend *zoneLowerHLine; + zoneLowerHLine = new CChartObjectTrend(); + isCreated = zoneLowerHLine.Create( + chartID, + zoneLowerName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.zoneLower, + conditions.workingZone.to, + conditions.workingZone.zoneLower // + ); + if (isCreated) + { + // + zoneLowerHLine.Color(clrRed); + mWorkingZoneObjects.Add(zoneLowerHLine); + } + + // + CChartObjectTrend *zoneUpperHLine; + zoneUpperHLine = new CChartObjectTrend(); + isCreated = zoneUpperHLine.Create( + chartID, + zoneUpperName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.zoneUpper, + conditions.workingZone.to, + conditions.workingZone.zoneUpper // + ); + if (isCreated) + { + // + zoneUpperHLine.Color(clrRed); + mWorkingZoneObjects.Add(zoneUpperHLine); + } + + // + CChartObjectTrend *quarter1HLine; + quarter1HLine = new CChartObjectTrend(); + isCreated = quarter1HLine.Create( + chartID, + q1Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter1, + conditions.workingZone.to, + conditions.workingZone.quarter1 // + ); + if (isCreated) + { + // + quarter1HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter1HLine); + } + + // + CChartObjectTrend *quarter2HLine; + quarter2HLine = new CChartObjectTrend(); + isCreated = quarter2HLine.Create( + chartID, + q2Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter2, + conditions.workingZone.to, + conditions.workingZone.quarter2 // + ); + if (isCreated) + { + // + quarter2HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter2HLine); + } + + // + CChartObjectTrend *quarter3HLine; + quarter3HLine = new CChartObjectTrend(); + isCreated = quarter3HLine.Create( + chartID, + q3Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter3, + conditions.workingZone.to, + conditions.workingZone.quarter3 // + ); + if (isCreated) + { + // + quarter3HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter3HLine); + } + + // + } + + // + void DrawConditions( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer, + bool forceClean = false // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + if (forceClean) + { + mObjects.Clear(); + } + + // + bool isCreated = false; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + + // + // Start Zones ... + bool hasStartZones = conditions.HasStartZones(); + if (hasStartZones) + { + // + int count = conditions.CountStartZones(); + for (int i = 0; i < count; i++) + { + // + bool isBullish = conditions.startZones[i].IsBullish(); + + // + bool hasOB = conditions.startZones[i].HasOB(); + if (hasOB) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateOrderBlock( + // conditions.startZones[i].ob, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawOrderBlock( + conditions.startZones[i].ob, + drawer // + ); + } + + // + bool hasFVG = conditions.startZones[i].HasFVG(); + if (hasFVG) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateFairValueGap( + // conditions.startZones[i].fvg, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawFairValueGap( + conditions.startZones[i].fvg, + drawer // + ); + } + + // // + // bool hasSupply = conditions.startZones[i].HasSupply(); + // if (hasSupply) + // { + // // + // XCSupplyZoneObject *iObj; + // isCreated = drawer.CreateSupplyZone( + // conditions.startZones[i].supply, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // // + // bool hasDemand = conditions.startZones[i].HasDemand(); + // if (hasDemand) + // { + // // + // XCDemandZoneObject *iObj; + // isCreated = drawer.CreateDemandZone( + // conditions.startZones[i].demand, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // // + // bool hasSupport = conditions.startZones[i].HasSupport(); + // if (hasSupport) + // { + // // + // XCSupportZoneObject *iObj; + // isCreated = drawer.CreateSupportZone( + // conditions.startZones[i].support, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // // + // bool hasResistance = conditions.startZones[i].HasResistance(); + // if (hasResistance) + // { + // // + // XCResistanceZoneObject *iObj; + // isCreated = drawer.CreateResistanceZone( + // conditions.startZones[i].resistance, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } + + // + // + // + + // + string bName = ""; + int arrowCode = 0; + string bSuffix = ""; + color arrowColor = clrNONE; + ENUM_X_PRICE bPrice = X_PRICE_CLOSE; + + // + bool hasSwingBar = conditions.startZones[i].swingBar.IsValid(); + if (hasSwingBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].swingBar.GetTag()); + bName = + (isBullish + ? "SWING_LOW" + : "SWING_HIGH") + + "_" + bSuffix; + arrowCode = 159; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].swingBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasBreakerBar = conditions.startZones[i].breakerBar.IsValid(); + if (hasBreakerBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].breakerBar.GetTag()); + bName = + (isBullish + ? "BULL_BREAKER" + : "BEAR_BREAKER") + + "_" + bSuffix; + arrowCode = + isBullish + ? 71 + : 72; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].breakerBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasMomentumBar = conditions.startZones[i].momentumBar.IsValid(); + if (hasMomentumBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].momentumBar.GetTag()); + bName = + (isBullish + ? "BULL_MOMENTUM" + : "BEAR_MOMENTUM") + + "_" + bSuffix; + arrowCode = + isBullish + ? 233 + : 234; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].momentumBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasRejectionBar = conditions.startZones[i].rejectionBar.IsValid(); + if (hasRejectionBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].rejectionBar.GetTag()); + bName = + (isBullish + ? "BULL_REJECTION" + : "BEAR_REJECTION") + + "_" + bSuffix; + arrowCode = + isBullish + ? 241 + : 242; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].rejectionBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasAppliedBox = conditions.startZones[i].appliedBox.IsValid(); + if (hasAppliedBox) + { + // + arrowColor = + IsBullish(conditions.startZones[i].appliedBox.dir) + ? bullishColor + : bearishColor; + + // + XCBoxObject *iObj; + isCreated = drawer.CreateBox( + conditions.startZones[i].appliedBox, + iObj // + ); + + // + if (isCreated) + { + // + iObj.BoxWidth(2); + iObj.BoxColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + } + } + } + + // + protected: + // + + // + private: + // + // Props ... + CArrayObj mObjects; + CArrayObj mWorkingZoneObjects; + + /** + * Initialize ... + */ + void Init() + { + } + + /** + * DeInitialize ... + */ + void DeInit() + { + // + RemoveDraws(); + mConditions.Clean(); + RemoveWorkingZoneDraws(); + Clean(mConditionsCollection); + } + + // + // Helpers ... + + // + bool CalculateRiskReward( + ENUM_X121SMC_XWZ_PRIORITY priority, + double &reward, + double &amountPercent // + ) + { + // + bool result = false; + + // + reward = 0; + amountPercent = 0; + + // + result = priority != X121SMC_XWZ_PRIORITY_NONE; + if (!result) + { + return result; + } + + // + switch (priority) + { + // + case X121SMC_XWZ_PRIORITY_STRONG_HIGH: + // + reward = 6; + amountPercent = 2; + break; + + // + case X121SMC_XWZ_PRIORITY_HIGH: + // + reward = 4; + amountPercent = 2; + break; + + // + case X121SMC_XWZ_PRIORITY_REGULAR: + // + reward = 3; + amountPercent = 1.5; + break; + + // + case X121SMC_XWZ_PRIORITY_LOW: + // + reward = 2; + amountPercent = 1; + break; + + // + case X121SMC_XWZ_PRIORITY_WEAK: + // + reward = 1; + amountPercent = 0.5; + break; + } + + // + result = + // + reward > 0 && + amountPercent > 0 + // + ; + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.xwz.signal.lib copy.mq5 b/Documents/BKP/x-121.smc.xwz.signal.lib copy.mq5 new file mode 100644 index 00000000..9a7025d0 --- /dev/null +++ b/Documents/BKP/x-121.smc.xwz.signal.lib copy.mq5 @@ -0,0 +1,3749 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XWZ +// 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" + +// +enum ENUM_X121SMC_XWZ_PRIORITY +{ + X121SMC_XWZ_PRIORITY_NONE, + X121SMC_XWZ_PRIORITY_WEAK, + X121SMC_XWZ_PRIORITY_LOW, + X121SMC_XWZ_PRIORITY_REGULAR, + X121SMC_XWZ_PRIORITY_HIGH, + X121SMC_XWZ_PRIORITY_STRONG_HIGH, +}; + +// +struct X121SMCXWZZone +{ + // + // Props ... + XCFVG *fvg; + XCOrderBlock *ob; + XCSupplyZone *supply; + XCDemandZone *demand; + XCSupportZone *support; + XCResistanceZone *resistance; + + // + XOHCL swingBar; + XOHCL breakerBar; + XOHCL momentumBar; + XOHCL rejectionBar; + XBoxZone appliedBox; + + // + // Constructor ... + X121SMCXWZZone() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + ZeroMemory(ob); + ZeroMemory(fvg); + ZeroMemory(supply); + ZeroMemory(demand); + ZeroMemory(support); + ZeroMemory(resistance); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + bool IsValid() + { + // + return HasOB() && + HasFVG() && + HasDirection(); + } + + // + bool AsBox(XBoxZone &box) + { + // + bool result = false; + + // + box.Clean(); + + // + result = IsValid() && + HasDirection(); + if (!result) + { + return result; + } + + // + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + ob // + ); + result = hasOBBox; + if (!result) + { + // + box.Clean(); + obBox.Clean(); + return result; + } + + // + box = obBox; + + // + obBox.Clean(); + + // + bool hasOB = HasOB(); + bool hasFVG = HasFVG(); + bool hasSupply = HasSupply(); + bool hasDemand = HasDemand(); + bool hasSupport = HasSupport(); + bool hasResistance = HasResistance(); + + // + // OB Compared since box used obBox ... + + // + if (hasFVG) + { + // + if (fvg.Upper() > box.upper) + { + box.upper = fvg.Upper(); + } + + // + if (fvg.Lower() < box.lower) + { + box.lower = fvg.Lower(); + } + } + + // + result = box.IsValid(); + + // + return result; + } + + // + bool HasOB() + { + return ob != NULL && + ob.IsValid(); + } + + // + bool HasFVG() + { + return fvg != NULL && + fvg.IsValid(); + } + + // + bool HasSupply() + { + return supply != NULL && + supply.IsValid(); + } + + // + bool HasDemand() + { + return demand != NULL && + demand.IsValid(); + } + + // + bool HasSupport() + { + return support != NULL && + support.IsValid(); + } + + // + bool HasResistance() + { + return resistance != NULL && + resistance.IsValid(); + } + + // + bool IsBullish() + { + // + return HasOB() && + ob.IsBullish() && + HasFVG() && + fvg.IsBullish(); + } + + // + bool IsBearish() + { + // + return HasOB() && + ob.IsBearish() && + HasFVG() && + fvg.IsBearish(); + } + + // + bool HasDirection() + { + return IsBullish() || + IsBearish(); + } + + // + bool ValidateZone( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = IsValid() && + HasDirection(); + if (!result) + { + return result; + } + + // + string symbol = ob.GetSymbol(); + if (forPeriod == NULL) + { + forPeriod = ob.GetPeriod(); + } + ENUM_X_DIRECTION forDir = GetDirection(); + + // + XOHCL cBar; + result = cBar.Init( + symbol, + forPeriod, + barIndex + 1 // + ); + if (!result) + { + // + cBar.Clean(); + return result; + } + + // + bool isBreaked = + IsBullish(forDir) + ? cBar.close < ob.Lower() || + cBar.close < fvg.Lower() + : cBar.close > ob.Upper() || + cBar.close > fvg.Upper(); + result = !isBreaked; + + // + cBar.Clean(); + + // + return result; + } + + // + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + bool hasDirection = HasDirection(); + if (!hasDirection) + { + return result; + } + + // + bool isBullish = IsBullish(); + + // + result = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + // + bool IsPriceInside( + XBoxZone &box, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL, + bool forceOB = false, + bool forceFVG = false // + ) + { + // + bool result = false; + + // + box.Clean(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = IsValid() && + HasOB() && + HasFVG() && + HasDirection(); + if (!result) + { + return result; + } + + // + string symbol = ob.GetSymbol(); + if (forPeriod == NULL) + { + forPeriod = ob.GetPeriod(); + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + bool isBullish = IsBullish(forDir); + + // + // Check Start Bars ... + + // + XOHCL obStartedBar; + ENUM_X_DIRECTION obStartedDir; + bool isOBStarted = ob.IsStarted( + forDir, + obStartedBar, + obStartedDir // + ); + result = isOBStarted; + if (!result) + { + return result; + } + + // + XOHCL fvgStartedBar; + ENUM_X_DIRECTION fvgStartedDir; + bool isFVGStarted = fvg.IsStarted( + forDir, + fvgStartedBar, + fvgStartedDir // + ); + result = isFVGStarted; + if (!result) + { + return result; + } + + // + // Retrieve Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + bool isPriceInsideOB = X121SMCXWZCheckPriceInside( + zBar, + cBar, + ob.Upper(), + ob.Lower() // + ); + + // + // isBullish + // ? ( + // // + // pBar.close > ob.Upper() && + // cBar.low <= ob.Upper() && + // cBar.close <= ob.Upper() && + // zBar.open <= ob.Upper() + // // + // ) + // : ( + // // + // pBar.close < ob.Lower() && + // cBar.high >= ob.Lower() && + // cBar.close >= ob.Lower() && + // zBar.open >= ob.Lower() + // // + // ); + + // + bool isPriceInsideFVG = X121SMCXWZCheckPriceInside( + zBar, + cBar, + fvg.Upper(), + fvg.Lower() // + ); + + // + // isBullish + // ? ( + // // + // pBar.close > fvg.Upper() && + // cBar.low <= fvg.Upper() && + // cBar.close <= fvg.Upper() && + // zBar.open <= fvg.Upper() + // // + // ) + // : ( + // // + // pBar.close < fvg.Lower() && + // cBar.high >= fvg.Lower() && + // cBar.close >= fvg.Lower() && + // zBar.open >= fvg.Lower() + // // + // ); + + // + if ((forceOB && forceFVG) || + (!forceOB && !forceFVG)) + { + // + result = + isPriceInsideOB || + isPriceInsideFVG; + } + else if (forceOB) + { + result = isPriceInsideOB; + } + else if (forceFVG) + { + result = isPriceInsideFVG; + } + + // + if (result) + { + // + if (isPriceInsideOB && !isPriceInsideFVG) + { + // + result = ToBox( + box, + ob // + ); + } + else if (isPriceInsideFVG && !isPriceInsideOB) + { + // + result = ToBox( + box, + fvg // + ); + } + else if (isPriceInsideOB && isPriceInsideFVG) + { + result = AsBox(box); + } + } + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + bool HasInsideConditions( + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + XBoxZone zoneBox; + bool hasBox = AsBox(zoneBox); + + // + result = hasBox && + IsValid() && + HasDirection() && + state.IsValid() && + state.HasChild(); + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + string symbol = zoneBox.symbol; + if (!IsValid(forPeriod)) + { + forPeriod = zoneBox.period; + } + datetime cTime = iTime( + symbol, + forPeriod, + barIndex // + ); + + // + ENUM_X_DIRECTION forDir = zoneBox.dir; + bool isBullish = IsBullish(forDir); + + // + int count = 0; + bool has = false; + + // + XBoxZone supResBoxes[]; + int supresBoxesCount = 0; + bool hasSupResBoxes = false; + + // + has = state.HasSupportZones(); + if (has) + { + // + count = state.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + zoneBox // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + ZeroMemory(iZone); + } + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + has = state.HasResistanceZones(); + if (has) + { + // + count = state.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + zoneBox // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + ZeroMemory(iZone); + } + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + result = hasSupResBoxes; + if (!result) + { + // + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + for (int i = 0; i < supresBoxesCount; i++) + { + // + XBoxZone iBox = supResBoxes[i]; + + // + bool hasBoxConditions = HasBoxConitions( + iBox, + state, + barIndex, + forPeriod // + ); + if (hasBoxConditions) + { + // + appliedBox = iBox; + result = true; + iBox.Clean(); + break; + } + + // + iBox.Clean(); + } + + // + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + Clean(supResBoxes); + + // + return result; + } + + // + bool HasBoxConitions( + XBoxZone &box, + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = box.IsValid() && + IsValid() && + HasDirection(); + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + string symbol = box.symbol; + if (forPeriod == NULL) + { + forPeriod = box.period; + } + ENUM_X_DIRECTION forDir = box.dir; + bool isBullish = IsBullish(forDir); + + // + // Detect Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + zBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382); + + // + double fiboUpDown = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BEARISH // + ); + double fiboDownUp = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BULLISH // + ); + + // + bool hasFiboToUpPressure = + fiboDownUp > 0 && + fiboDownUp <= pBar.GetDown(); + bool hasFiboToDownPressure = + fiboUpDown > 0 && + fiboUpDown >= pBar.GetUp(); + + // + double appliedPrice = + isBullish + ? box.upper + : box.lower; + + // + // Check Swing Low ... + bool isSwingLow = + // + pBar.low < ppBar.low && + pBar.low < cBar.low && + zBar.open > pBar.low && + // + appliedPrice > pBar.low && + appliedPrice < pBar.GetDown() + // + ; + bool isPressuredSwingLow = + isSwingLow && + hasFiboToUpPressure; + bool isPressuredStrongSwingLow = + pBar.IsBullish() && + isPressuredSwingLow; + + // + bool isSwingHigh = + // + pBar.high > ppBar.high && + pBar.high > cBar.high && + zBar.open < pBar.high && + // + appliedPrice < pBar.high && + appliedPrice > pBar.GetUp() + // + ; + bool isPressuredSwingHigh = + isSwingHigh && + hasFiboToDownPressure; + bool isPressuredStrongSwingHigh = + pBar.IsBearish() && + isPressuredSwingHigh; + + // + bool hasValidSwing = + isBullish + ? isSwingLow + : isSwingHigh; + bool hasValidPressuredSwing = + isBullish + ? isPressuredSwingLow + : isPressuredSwingHigh; + bool hasValidPressuredStrongSwing = + isBullish + ? isPressuredStrongSwingLow + : isPressuredStrongSwingHigh; + if (hasValidSwing) + { + swingBar = pBar; + } + if (hasValidPressuredSwing) + { + swingBar = pBar; + } + if (hasValidPressuredStrongSwing) + { + swingBar = pBar; + } + + // + bool isCBarBreaked = IsBarBreak( + appliedPrice, + forDir, + cBar // + ); + if (isCBarBreaked) + { + breakerBar = cBar; + } + bool isPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarBreaked && isPBarBreaked) + { + breakerBar = pBar; + } + else + { + isPBarBreaked = false; + } + bool isPPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarBreaked && + !isPBarBreaked && + isPPBarBreaked) + { + breakerBar = ppBar; + } + else + { + isPPBarBreaked = false; + } + bool isBoxBreaked = isCBarBreaked || + isPBarBreaked || + isPPBarBreaked; + + // + bool isCBarRejected = IsBarReject( + appliedPrice, + forDir, + cBar // + ); + if (isCBarRejected) + { + rejectionBar = cBar; + } + bool isPBarRejected = IsBarReject( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarRejected && isPBarRejected) + { + rejectionBar = pBar; + } + else + { + isPBarRejected = false; + } + bool isPPBarRejected = IsBarReject( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarRejected && + !isPBarRejected && + isPPBarRejected) + { + rejectionBar = ppBar; + } + else + { + isPPBarRejected = false; + } + bool isBoxRejected = isCBarRejected || + isPBarRejected || + isPPBarRejected; + + // + result = + // + isBoxBreaked || + isBoxRejected || + hasValidPressuredSwing + // + ; + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + else + { + appliedBox = box; + } + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + return result; + } + + // +}; + +// +struct X121SMCXWZWorkingZone +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + double zoneUpper; + double zoneLower; + + // + double quarter1; + double quarter2; + double quarter3; + + // + datetime to; + datetime from; + + // + XOHCL swingBar; + XOHCL breakerBar; + XOHCL momentumBar; + XOHCL rejectionBar; + XBoxZone appliedBox; + + // + X121SMCXWZWorkingZone() + { + Clean(); + } + + // + void Clean() + { + // + upper = 0; + lower = 0; + quarter1 = 0; + quarter2 = 0; + quarter3 = 0; + zoneLower = 0; + zoneUpper = 0; + + // + from = NULL; + symbol = NULL; + period = NULL; + + // + CleanConditionBars(); + + // + ZeroMemory(this); + } + + // + void CleanConditionBars() + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + bool IsValid() + { + // + bool result = false; + + // + result = + lower > 0 && + upper > 0 && + quarter1 > 0 && + quarter2 > 0 && + quarter3 > 0 && + upper > lower && + zoneLower > 0 && + zoneUpper > 0 && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + zoneUpper > upper && + zoneLower < lower; + + // + return result; + } + + // + bool IsDestroyed( + ENUM_X_DIRECTION &destroyedDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + destroyedDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + return result; + } + + // + bool isUpperBreaked = + bar.high > zoneUpper && + bar.close > zoneUpper; + + // + bool isLowerBreaked = + bar.low < zoneLower && + bar.close < zoneLower; + + // + result = isUpperBreaked || + isLowerBreaked; + if (result) + { + // + destroyedDir = + isUpperBreaked + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + // +}; + +// +// Definitions ... +struct X121SMCStrategyXWZSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + double reward; + double amountPercent; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + ENUM_X121SMC_XWZ_PRIORITY priority; + + // + // Working Zone ... + XCFVG *fairValueGap; + XCOrderBlock *orderBlock; + XCSupplyZone *supplyZone; + XCDemandZone *demandZone; + X121SMCXWZWorkingZone workingZone; + + // + // X121SMCXWZZone startZone; + X121SMCXWZZone startZones[]; + + // + // Constructor ... + X121SMCStrategyXWZSignalConditions() + { + 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(); + + // + ZeroMemory(this); + } + + /** + * 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; + + // + target = 0; + reward = 0; + amountPercent = 0; + + // + ZeroMemory(supplyZone); + + // + ZeroMemory(demandZone); + + // + ZeroMemory(orderBlock); + + // + ZeroMemory(fairValueGap); + + // + // startZone.Clean(); + Clean(startZones); + + // + workingZone.Clean(); + } + + // + // + // + + // + bool HasWorkingZone() + { + return workingZone.IsValid(); + } + + // + bool HasOrderBlock() + { + return orderBlock != NULL && + orderBlock.IsValid(); + } + + // + bool HasFairValueGap() + { + return fairValueGap != NULL && + fairValueGap.IsValid(); + } + + // + bool HasSupplyZone() + { + return supplyZone != NULL && + supplyZone.IsValid(); + } + + // + bool HasDemandZone() + { + return demandZone != NULL && + demandZone.IsValid(); + } + + // + bool HasStartZones() + { + return HasChild(startZones); + } + + // + int CountStartZones() + { + return ArraySize(startZones); + } + + // + void UpdateTo(datetime value = NULL) + { + // + value = NormalizeTime(value); + + // + bool hasSupplyZone = HasSupplyZone(); + if (hasSupplyZone) + { + supplyZone.To(value); + } + + // + bool hasDemandZone = HasDemandZone(); + if (hasDemandZone) + { + demandZone.To(value); + } + + // + bool hasOrderBlock = HasOrderBlock(); + if (hasOrderBlock) + { + orderBlock.To(value); + } + + // + bool hasFairValueGap = HasFairValueGap(); + if (hasFairValueGap) + { + fairValueGap.To(value); + } + + // + // Working Zone ... + bool hasWorkingZone = HasWorkingZone(); + if (hasWorkingZone) + { + workingZone.to = value; + } + + // + // Start Zone ... + bool hasStartZones = HasStartZones(); + if (hasStartZones) + { + // + int count = CountStartZones(); + for (int i = 0; i < count; i++) + { + // + bool hasOB = startZones[i].HasOB(); + if (hasOB) + { + startZones[i].ob.To(value); + } + + // + bool hasFVG = startZones[i].HasFVG(); + if (hasFVG) + { + startZones[i].fvg.To(value); + } + + // + bool hasSupply = startZones[i].HasSupply(); + if (hasSupply) + { + startZones[i].supply.To(value); + } + + // + bool hasDemand = startZones[i].HasDemand(); + if (hasDemand) + { + startZones[i].demand.To(value); + } + + // + bool hasSupport = startZones[i].HasSupport(); + if (hasSupport) + { + startZones[i].support.To(value); + } + + // + bool hasResistance = startZones[i].HasResistance(); + if (hasResistance) + { + startZones[i].resistance.To(value); + } + } + } + } + + // + // + // + + // + // Working Zone is an Area which + // we decide to trade inside it ... + bool ExtractWorkingZone( + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &stfState, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + int zIndex = barIndex; + + // + result = !HasWorkingZone(); + if (!result) + { + return result; + } + + // + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + // + Clean(); + return result; + } + + // + datetime cTime = iTime( + symbol, + period, + zIndex // + ); + + // + result = + // + htfState.IsValid() && + htfState.HasChild() && + htfState.HasSupplyZones() && + htfState.HasDemandZones() && + // + mtfState.IsValid() && + mtfState.HasChild() && + mtfState.HasSupplyZones() && + mtfState.HasDemandZones() && + // + stfState.IsValid() && + stfState.HasChild() + // + ; + if (!result) + { + return result; + } + + // + // Retrieve Highest Supply Zone ... + int hSupplyIDX = GetHighest(htfState.supplyZones); + int lDemandIDX = GetLowest(htfState.demandZones); + + // + result = + // + IsValidIndex(hSupplyIDX) && + IsValidIndex(lDemandIDX) + // + ; + if (!result) + { + return result; + } + + // + supplyZone = htfState.supplyZones[hSupplyIDX]; + demandZone = htfState.demandZones[lDemandIDX]; + + // + result = + // + supplyZone != NULL && + demandZone != NULL && + supplyZone.IsValid() && + demandZone.IsValid() + // + ; + if (!result) + { + // + Clean(); + return result; + } + + // + // Check Validation of Supply and Demand Zones ... + lDemandIDX = GetLowest(mtfState.demandZones); + hSupplyIDX = GetHighest(mtfState.supplyZones); + result = IsValidIndex(lDemandIDX) && + IsValidIndex(hSupplyIDX); + if (!result) + { + // + Clean(); + return result; + } + + // + // Validate Supply and Demand ... + bool isMTFHSupplyInside = + IsInside( + mtfState.supplyZones[hSupplyIDX], + supplyZone); + bool isMTFLDemandInside = + IsInside( + mtfState.demandZones[lDemandIDX], + demandZone // + ); + if (isMTFHSupplyInside && + !isMTFLDemandInside) + { + demandZone = mtfState.demandZones[lDemandIDX]; + } + else if (!isMTFHSupplyInside && + isMTFLDemandInside) + { + supplyZone = mtfState.supplyZones[hSupplyIDX]; + } + else if (isMTFHSupplyInside && + isMTFLDemandInside) + { + // + supplyZone = mtfState.supplyZones[hSupplyIDX]; + demandZone = mtfState.demandZones[lDemandIDX]; + } + + // + // Check Zones Validation ... + bool hasTrend = + supplyZone != NULL && + supplyZone.IsValid() && + demandZone != NULL && + demandZone.IsValid(); + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + datetime from = MathMax( + supplyZone.From(), + demandZone.From()); + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + // Detect Trend ... + ENUM_X_DIRECTION trend = X_DIRECTION_NONE; + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = zIndex; i < fromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + period, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + hasTrend = + // + IsValid(supplyTouch) || + IsValid(demandTouch) + // + ; + if (hasTrend) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + // Check Trend ... + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + bool hasBullishTrend = IsBullish(trend); + bool hasBearishTrend = IsBearish(trend); + + // + // Find Order Block and FVG for Trend Approve ... + + // + bool isBullishTrendApproved = false; + bool isBearishTrendApproved = false; + + // + // Now We Have to Detect at least One OrderBlock with FVG ... + // for Trend Approvement ... + bool hasOrderBlock = HasOrderBlock(); + bool hasFairValueGap = HasFairValueGap(); + if (!hasOrderBlock && + !hasFairValueGap) + { + // + int count = 0; + bool has = false; + + // + XCFVG *fvg = NULL; + XCOrderBlock *ob = NULL; + + // + has = mtfState.HasBullishOrderBlocks(); + count = mtfState.CountBullishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bullishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > demandZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + demandZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBullishFairValueGaps(); + count = stfState.CountBullishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bullishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + isBullishTrendApproved = hasOrderBlock && + hasFairValueGap; + } + + // + if (!isBullishTrendApproved) + { + // + has = mtfState.HasBearishOrderBlocks(); + count = mtfState.CountBearishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bearishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > supplyZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + supplyZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBearishFairValueGaps(); + count = stfState.CountBearishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bearishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + isBearishTrendApproved = hasOrderBlock && + hasFairValueGap; + } + } + } + + // + // Check Trend Approved ... + bool isTrendApproved = + hasOrderBlock && + hasFairValueGap && + (isBullishTrendApproved || + isBearishTrendApproved); + result = isTrendApproved; + if (!result) + { + // + Clean(); + return result; + } + + // + // Prepare Working Zone ... + workingZone.symbol = symbol; + workingZone.period = period; + + // + workingZone.upper = supplyZone.Lower(); + workingZone.zoneUpper = supplyZone.Upper(); + + // + workingZone.lower = demandZone.Upper(); + workingZone.zoneLower = demandZone.Lower(); + + // + workingZone.from = from; + + // + double upper = workingZone.upper; + double range = + workingZone.upper - workingZone.lower; + double ranegPercent = range / 100; + double quarterValue = ranegPercent * 25; + + // + workingZone.quarter1 = upper - (quarterValue * 1); + workingZone.quarter2 = upper - (quarterValue * 2); + workingZone.quarter3 = upper - (quarterValue * 3); + + // + result = workingZone.IsValid(); + if (!result) + { + Clean(); + } + + // + return result; + } + + // + bool IsWorkingZoneDestroyed( + ENUM_X_DIRECTION &destroyedDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + destroyedDir = X_DIRECTION_NONE; + + // + result = workingZone.IsValid(); + if (!result) + { + return result; + } + + // + result = workingZone.IsDestroyed( + destroyedDir, + barIndex, + forPeriod // + ); + + // + return result; + } + + // + bool DetectTrend( + ENUM_X_DIRECTION &trend, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (forPeriod == NULL) + { + forPeriod = period; + } + + // + trend = X_DIRECTION_NONE; + + // + result = HasWorkingZone(); + if (!result) + { + return result; + } + + // + int FromIndex = iBarShift( + symbol, + forPeriod, + workingZone.from // + ); + + // + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = barIndex; i < FromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + forPeriod, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + result = + // + IsValid(supplyTouch) || + IsValid(demandTouch) + // + ; + if (result) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + return result; + } + + // + bool DetectStartZones( + ENUM_X_DIRECTION forDir, + XPOIState &obState, + XPOIState &fvgState, + XPOIState &otherState, + XC121SMCCycleHelper *cycleHelper // + ) + { + // + bool result = false; + + // + result = obState.IsValid() && + obState.HasChild() && + fvgState.IsValid() && + fvgState.HasChild() && + otherState.IsValid() && + otherState.HasChild() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + int idx = -1; + int count = 0; + int has = false; + + // + X121SMCXWZZone startZone; + X121SMCXWZZone lastStartZone; + bool hasLastStartZone = HasStartZones(); + if (hasLastStartZone) + { + // + int startZonesCount = CountStartZones(); + lastStartZone = startZones[startZonesCount - 1]; + } + + // + if (isBullish) + { + // + has = obState.HasBullishOrderBlocks(); + if (has) + { + // + count = obState.CountBullishOrderBlocks(); + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = obState.bullishOrderBlocks[i]; + + // + bool isFromPassed = + !hasLastStartZone + ? true + : iOB.From() > lastStartZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(iOB); + continue; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + continue; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = iOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Validate Zone Iverse Breake ... + XOHCL breakedBar; + ENUM_X_DIRECTION breakedDir; + bool isBreaked = iOB.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + bool isPlacePassed = + !IsInsideDiff( + iOB, + demandZone // + ) && + (!hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsAbove( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsAbove( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + )); + if (!isPlacePassed) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Attache OB ... + startZone.ob = iOB; + + // + // Now we Have to Find Specified FVG ... + has = fvgState.HasBullishFairValueGaps(); + if (has) + { + // + int jCount = fvgState.CountBullishFairValueGaps(); + for (int j = 0; j < jCount; j++) + { + // + XCFVG *jFVG = fvgState.bullishFairValueGaps[j]; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + isStarted = jFVG.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + continue; + } + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + isActivated = jFVG.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Validate Zone Iverse Breake ... + breakedBar.Clean(); + breakedDir = X_DIRECTION_NONE; + bool isBreaked = jFVG.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + isPlacePassed = + // + !IsInsideDiff( + jFVG, + demandZone // + ) && + IsAboveDiff( + jFVG, + iOB, + true // Ignore Inside ... + ) + // + ; + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + } + + // + startZone.fvg = jFVG; + } + } + + // + startedBar.Clean(); + activatedBar.Clean(); + } + } + } + else + { + // + has = obState.HasBearishOrderBlocks(); + if (has) + { + // + count = obState.CountBearishOrderBlocks(); + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = obState.bearishOrderBlocks[i]; + + // + bool isFromPassed = + !hasLastStartZone + ? true + : iOB.From() > lastStartZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(iOB); + continue; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + continue; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = iOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Validate Zone Iverse Breake ... + XOHCL breakedBar; + ENUM_X_DIRECTION breakedDir; + bool isBreaked = iOB.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + bool isPlacePassed = + !IsInsideDiff( + iOB, + supplyZone // + ) && + (!hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsBelow( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsBelow( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + )); + if (!isPlacePassed) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Attache OB ... + startZone.ob = iOB; + + // + // Now we Have to Find Specified FVG ... + has = fvgState.HasBearishFairValueGaps(); + if (has) + { + // + int jCount = fvgState.CountBearishFairValueGaps(); + for (int j = 0; j < jCount; j++) + { + // + XCFVG *jFVG = fvgState.bearishFairValueGaps[j]; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + isStarted = jFVG.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + continue; + } + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + isActivated = jFVG.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Validate Zone Iverse Breake ... + breakedBar.Clean(); + breakedDir = X_DIRECTION_NONE; + bool isBreaked = jFVG.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + isPlacePassed = + // + !IsInsideDiff( + jFVG, + supplyZone // + ) && + IsBelowDiff( + jFVG, + iOB, + true // Ignore Inside ... + ) + // + ; + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + } + + // + startZone.fvg = jFVG; + } + } + + // + startedBar.Clean(); + activatedBar.Clean(); + } + } + } + + // + bool hasOBFVG = startZone.HasOB() && + startZone.HasFVG(); + result = hasOBFVG; + if (!result) + { + // + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + XBoxZone startBox; + bool hasStartBox = startZone.AsBox(startBox); + result = hasStartBox; + if (!result) + { + // + startBox.Clean(); + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + // Detect Other Zones Inside Box ... + XBoxZone tmpBoxes[]; + + // + // Supply Zones ... + has = otherState.HasSupplyZones(); + if (has) + { + // + count = ToBox( + otherState.supplyZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.supply = otherState.supplyZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Demand Zones ... + Clean(tmpBoxes); + has = otherState.HasDemandZones(); + if (has) + { + // + count = ToBox( + otherState.demandZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.demand = otherState.demandZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Support Zones ... + Clean(tmpBoxes); + has = otherState.HasSupportZones(); + if (has) + { + // + count = ToBox( + otherState.supportZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.support = otherState.supportZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Resistance Zones ... + Clean(tmpBoxes); + has = otherState.HasResistanceZones(); + if (has) + { + // + count = ToBox( + otherState.resistanceZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.resistance = otherState.resistanceZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + result = startZone.IsValid() && + startZone.HasDirection(); + if (result) + { + // + AddRef( + startZone, + startZones // + ); + } + + // + Clean(tmpBoxes); + startBox.Clean(); + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + void ValidateStartZones( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool has = HasStartZones(); + if (!has) + { + return; + } + + // + X121SMCXWZZone tmpZones[]; + int count = CountStartZones(); + Copy( + startZones, + tmpZones // + ); + for (int i = 0; i < count; i++) + { + // + bool isValid = tmpZones[i].ValidateZone( + barIndex, + forPeriod // + ); + if (!isValid) + { + // + ArrayRemove( + startZones, + i, + 1 // + ); + } + } + + // + Clean(tmpZones); + } + + // + void DetectPriority( + ENUM_X121SMC_XWZ_PRIORITY &bullish, + ENUM_X121SMC_XWZ_PRIORITY &bearish, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bullish = X121SMC_XWZ_PRIORITY_NONE; + bearish = X121SMC_XWZ_PRIORITY_NONE; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + bool hasWorkingZone = HasWorkingZone(); + if (!hasWorkingZone) + { + return; + } + + // + XOHCL zBar; + bool isInited = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!isInited) + { + // + zBar.Clean(); + return; + } + + // + XOHCL cBar; + isInited = zBar.GetPreviousBar(cBar); + if (!isInited) + { + // + zBar.Clean(); + cBar.Clean(); + return; + } + + // + // ZoneUpper, Upper ... + if (cBar.low > workingZone.upper && + cBar.high < workingZone.zoneUpper && + zBar.low > workingZone.upper && + zBar.high < workingZone.zoneUpper) + { + // + bullish = X121SMC_XWZ_PRIORITY_NONE; + bearish = X121SMC_XWZ_PRIORITY_STRONG_HIGH; + } + // + // Upper, Quarter1 ... + else if (cBar.low > workingZone.quarter1 && + cBar.high < workingZone.upper && + zBar.low > workingZone.quarter1 && + zBar.high < workingZone.upper) + { + // + bullish = X121SMC_XWZ_PRIORITY_WEAK; + bearish = X121SMC_XWZ_PRIORITY_HIGH; + } + // + // Quarter1, Quarter2 ... + else if (cBar.low > workingZone.quarter2 && + cBar.high < workingZone.quarter1 && + zBar.low > workingZone.quarter2 && + zBar.high < workingZone.quarter1) + { + // + bullish = X121SMC_XWZ_PRIORITY_LOW; + bearish = X121SMC_XWZ_PRIORITY_REGULAR; + } + // + // Quarter2, Quarter3 ... + else if (cBar.low > workingZone.quarter3 && + cBar.high < workingZone.quarter2 && + zBar.low > workingZone.quarter3 && + zBar.high < workingZone.quarter2) + { + // + bullish = X121SMC_XWZ_PRIORITY_REGULAR; + bearish = X121SMC_XWZ_PRIORITY_LOW; + } + // + // Quarter3, Lower ... + else if (cBar.low > workingZone.lower && + cBar.high < workingZone.quarter3 && + zBar.low > workingZone.lower && + zBar.high < workingZone.quarter3) + { + // + bullish = X121SMC_XWZ_PRIORITY_HIGH; + bearish = X121SMC_XWZ_PRIORITY_WEAK; + } + // + // Lower, ZoneLower ... + else if (cBar.low > workingZone.zoneLower && + cBar.high < workingZone.lower && + zBar.low > workingZone.zoneLower && + zBar.high < workingZone.lower) + { + // + bullish = X121SMC_XWZ_PRIORITY_STRONG_HIGH; + bearish = X121SMC_XWZ_PRIORITY_NONE; + } + + // + zBar.Clean(); + cBar.Clean(); + } + + // + bool HasConditions( + double &_pivot, + double &_point, + ENUM_X_DIRECTION &conditionsDir, + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + _pivot = 0; + _point = 0; + conditionsDir = X_DIRECTION_NONE; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (forPeriod == NULL) + { + forPeriod = period; + } + + // + result = + // + IsValid(symbol) && + IsValid(period) && + state.IsValid() && + HasWorkingZone() && + state.HasChild() + // + ; + if (!result) + { + return result; + } + + // + result = false; + + // + ValidateStartZones( + barIndex, + forPeriod // + ); + + // + // Detect Conditions Based On Start Zones ... + bool hasStartZones = HasStartZones(); + if (hasStartZones) + { + // + int selectedIndex = -1; + int count = CountStartZones(); + for (int i = 0; i < count; i++) + { + // + X121SMCXWZZone iStartZone = startZones[i]; + + // + XBoxZone selectedBox; + bool hasConditions = false; + bool isBullish = iStartZone.IsBullish(); + + // + // Conditions Inside Box ... + bool isPriceInside = iStartZone.IsPriceInside( + selectedBox, + barIndex, + forPeriod, + false, + false // + ); + if (isPriceInside) + { + // + // hasConditions = iStartZone.HasInsideConditions( + // state, + // barIndex, + // period // + // ); + + // + hasConditions = true; + + // + if (hasConditions) + { + // + _pivot = + // + isBullish + ? selectedBox.lower + : selectedBox.upper + // + ; + + // + _point = + // + isBullish + ? selectedBox.upper + : selectedBox.lower + // + ; + + // + conditionsDir = selectedBox.dir; + result = hasConditions; + iStartZone.Clean(); + break; + } + } + + // // + // // Order Block Rejection Conditions ... + // bool hasOBBox = ToBox( + // selectedBox, + // iStartZone.ob // + // ); + // if (hasOBBox && + // !hasConditions) + // { + // // + // hasConditions = iStartZone.HasBoxConitions( + // selectedBox, + // state, + // barIndex, + // forPeriod // + // ); + + // // + // if (hasConditions) + // { + // // + // _pivot = + // // + // isBullish + // ? selectedBox.lower + // : selectedBox.upper + // // + // ; + + // // + // _point = + // // + // isBullish + // ? selectedBox.upper + // : selectedBox.lower + // // + // ; + + // // + // conditionsDir = selectedBox.dir; + // result = hasConditions; + // iStartZone.Clean(); + // break; + // } + // } + + // // + // // Fair Value Gap Rejection Conditions ... + // bool hasFVGBox = ToBox( + // selectedBox, + // iStartZone.fvg // + // ); + // if (hasFVGBox) + // { + // // + // hasConditions = iStartZone.HasBoxConitions( + // selectedBox, + // state, + // barIndex, + // forPeriod // + // ); + + // // + // if (hasConditions) + // { + // // + // _pivot = + // // + // isBullish + // ? selectedBox.lower + // : selectedBox.upper + // // + // ; + + // // + // _point = + // // + // isBullish + // ? selectedBox.upper + // : selectedBox.lower + // // + // ; + + // // + // conditionsDir = selectedBox.dir; + // result = hasConditions; + // iStartZone.Clean(); + // break; + // } + // } + + // + iStartZone.Clean(); + } + + // + if (result && + IsValidIndex(selectedIndex)) + { + // + ArrayRemove( + startZones, + selectedIndex, + 1 // + ); + } + } + + // + // Detect Conditions Based On Working Zones ... + if (!result) + { + // + // Detect Result Based On WorkingZone ... + } + + // + if (!result) + { + // + _point = 0; + _pivot = 0; + conditionsDir = X_DIRECTION_NONE; + + // + return result; + } + + // + return result; + } + + // +}; + +// +bool X121SMCXWZCheckPriceInside( + XOHCL &zBar, + XOHCL &cBar, + double upper, + double lower // +) +{ + // + bool result = false; + + // + result = zBar.IsValid() && + cBar.IsValid() && + upper > 0 && + lower > 0 && + upper > lower && + zBar.time > cBar.time; + if (!result) + { + return result; + } + + // + result = + // + zBar.high < upper && + cBar.high < upper && + // + zBar.low > lower && + cBar.low > lower + // + ; + + // + return result; +} + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.xwz.signal.lib.mq5 b/Documents/BKP/x-121.smc.xwz.signal.lib.mq5 new file mode 100644 index 00000000..ac6f0427 --- /dev/null +++ b/Documents/BKP/x-121.smc.xwz.signal.lib.mq5 @@ -0,0 +1,3560 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XWZ +// 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" + +// +enum ENUM_X121SMC_XWZ_PRIORITY +{ + X121SMC_XWZ_PRIORITY_NONE, + X121SMC_XWZ_PRIORITY_WEAK, + X121SMC_XWZ_PRIORITY_LOW, + X121SMC_XWZ_PRIORITY_REGULAR, + X121SMC_XWZ_PRIORITY_HIGH, + X121SMC_XWZ_PRIORITY_STRONG_HIGH, +}; + +// +struct X121SMCXWZZone +{ + // + // Props ... + XCFVG *fvg; + XCOrderBlock *ob; + XCSupplyZone *supply; + XCDemandZone *demand; + XCSupportZone *support; + XCResistanceZone *resistance; + + // + XOHCL swingBar; + XOHCL breakerBar; + XOHCL momentumBar; + XOHCL rejectionBar; + XBoxZone appliedBox; + + // + // Constructor ... + X121SMCXWZZone() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + ZeroMemory(ob); + ZeroMemory(fvg); + ZeroMemory(supply); + ZeroMemory(demand); + ZeroMemory(support); + ZeroMemory(resistance); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + bool IsValid() + { + // + return HasOB() && + HasFVG() && + HasDirection(); + } + + // + bool AsBox(XBoxZone &box) + { + // + bool result = false; + + // + box.Clean(); + + // + result = IsValid() && + HasDirection(); + if (!result) + { + return result; + } + + // + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + ob // + ); + result = hasOBBox; + if (!result) + { + // + box.Clean(); + obBox.Clean(); + return result; + } + + // + box = obBox; + + // + obBox.Clean(); + + // + bool hasOB = HasOB(); + bool hasFVG = HasFVG(); + bool hasSupply = HasSupply(); + bool hasDemand = HasDemand(); + bool hasSupport = HasSupport(); + bool hasResistance = HasResistance(); + + // + // OB Compared since box used obBox ... + + // + if (hasFVG) + { + // + if (fvg.Upper() > box.upper) + { + box.upper = fvg.Upper(); + } + + // + if (fvg.Lower() < box.lower) + { + box.lower = fvg.Lower(); + } + } + + // + result = box.IsValid(); + + // + return result; + } + + // + bool HasOB() + { + return ob != NULL && + ob.IsValid(); + } + + // + bool HasFVG() + { + return fvg != NULL && + fvg.IsValid(); + } + + // + bool HasSupply() + { + return supply != NULL && + supply.IsValid(); + } + + // + bool HasDemand() + { + return demand != NULL && + demand.IsValid(); + } + + // + bool HasSupport() + { + return support != NULL && + support.IsValid(); + } + + // + bool HasResistance() + { + return resistance != NULL && + resistance.IsValid(); + } + + // + bool IsBullish() + { + // + return HasOB() && + ob.IsBullish() && + HasFVG() && + fvg.IsBullish(); + } + + // + bool IsBearish() + { + // + return HasOB() && + ob.IsBearish() && + HasFVG() && + fvg.IsBearish(); + } + + // + bool HasDirection() + { + return IsBullish() || + IsBearish(); + } + + // + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + bool hasDirection = HasDirection(); + if (!hasDirection) + { + return result; + } + + // + bool isBullish = IsBullish(); + + // + result = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + // + bool IsPriceInside( + XBoxZone &box, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL, + bool forceOB = false, + bool forceFVG = false // + ) + { + // + bool result = false; + + // + box.Clean(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = IsValid() && + HasOB() && + HasFVG() && + HasDirection(); + if (!result) + { + return result; + } + + // + string symbol = ob.GetSymbol(); + if (forPeriod == NULL) + { + forPeriod = ob.GetPeriod(); + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + bool isBullish = IsBullish(forDir); + + // + // Check Start Bars ... + + // + XOHCL obStartedBar; + ENUM_X_DIRECTION obStartedDir; + bool isOBStarted = ob.IsStarted( + forDir, + obStartedBar, + obStartedDir // + ); + result = isOBStarted; + if (!result) + { + return result; + } + + // + XOHCL fvgStartedBar; + ENUM_X_DIRECTION fvgStartedDir; + bool isFVGStarted = fvg.IsStarted( + forDir, + fvgStartedBar, + fvgStartedDir // + ); + result = isFVGStarted; + if (!result) + { + return result; + } + + // + // Retrieve Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + bool isPriceInsideOB = X121SMCXWZCheckPriceInside( + zBar, + cBar, + ob.Upper(), + ob.Lower() // + ); + + // + // isBullish + // ? ( + // // + // pBar.close > ob.Upper() && + // cBar.low <= ob.Upper() && + // cBar.close <= ob.Upper() && + // zBar.open <= ob.Upper() + // // + // ) + // : ( + // // + // pBar.close < ob.Lower() && + // cBar.high >= ob.Lower() && + // cBar.close >= ob.Lower() && + // zBar.open >= ob.Lower() + // // + // ); + + // + bool isPriceInsideFVG = X121SMCXWZCheckPriceInside( + zBar, + cBar, + fvg.Upper(), + fvg.Lower() // + ); + + // + // isBullish + // ? ( + // // + // pBar.close > fvg.Upper() && + // cBar.low <= fvg.Upper() && + // cBar.close <= fvg.Upper() && + // zBar.open <= fvg.Upper() + // // + // ) + // : ( + // // + // pBar.close < fvg.Lower() && + // cBar.high >= fvg.Lower() && + // cBar.close >= fvg.Lower() && + // zBar.open >= fvg.Lower() + // // + // ); + + // + if ((forceOB && forceFVG) || + (!forceOB && !forceFVG)) + { + // + result = + isPriceInsideOB || + isPriceInsideFVG; + } + else if (forceOB) + { + result = isPriceInsideOB; + } + else if (forceFVG) + { + result = isPriceInsideFVG; + } + + // + if (result) + { + // + if (isPriceInsideOB && !isPriceInsideFVG) + { + // + result = ToBox( + box, + ob // + ); + } + else if (isPriceInsideFVG && !isPriceInsideOB) + { + // + result = ToBox( + box, + fvg // + ); + } + else if (isPriceInsideOB && isPriceInsideFVG) + { + result = AsBox(box); + } + } + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + bool HasInsideConditions( + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + XBoxZone zoneBox; + bool hasBox = AsBox(zoneBox); + + // + result = hasBox && + IsValid() && + HasDirection() && + state.IsValid() && + state.HasChild(); + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + string symbol = zoneBox.symbol; + if (!IsValid(forPeriod)) + { + forPeriod = zoneBox.period; + } + datetime cTime = iTime( + symbol, + forPeriod, + barIndex // + ); + + // + ENUM_X_DIRECTION forDir = zoneBox.dir; + bool isBullish = IsBullish(forDir); + + // + int count = 0; + bool has = false; + + // + XBoxZone supResBoxes[]; + int supresBoxesCount = 0; + bool hasSupResBoxes = false; + + // + has = state.HasSupportZones(); + if (has) + { + // + count = state.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + zoneBox // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + ZeroMemory(iZone); + } + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + has = state.HasResistanceZones(); + if (has) + { + // + count = state.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + zoneBox // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + ZeroMemory(iZone); + } + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + result = hasSupResBoxes; + if (!result) + { + // + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + for (int i = 0; i < supresBoxesCount; i++) + { + // + XBoxZone iBox = supResBoxes[i]; + + // + bool hasBoxConditions = HasBoxConitions( + iBox, + state, + barIndex, + forPeriod // + ); + if (hasBoxConditions) + { + // + appliedBox = iBox; + result = true; + iBox.Clean(); + break; + } + + // + iBox.Clean(); + } + + // + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + Clean(supResBoxes); + + // + return result; + } + + // + bool HasBoxConitions( + XBoxZone &box, + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = box.IsValid() && + IsValid() && + HasDirection(); + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + string symbol = box.symbol; + if (forPeriod == NULL) + { + forPeriod = box.period; + } + ENUM_X_DIRECTION forDir = box.dir; + bool isBullish = IsBullish(forDir); + + // + // Detect Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + zBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382); + + // + double fiboUpDown = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BEARISH // + ); + double fiboDownUp = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BULLISH // + ); + + // + bool hasFiboToUpPressure = + fiboDownUp > 0 && + fiboDownUp <= pBar.GetDown(); + bool hasFiboToDownPressure = + fiboUpDown > 0 && + fiboUpDown >= pBar.GetUp(); + + // + double appliedPrice = + isBullish + ? box.upper + : box.lower; + + // + // Check Swing Low ... + bool isSwingLow = + // + pBar.low < ppBar.low && + pBar.low < cBar.low && + zBar.open > pBar.low && + // + appliedPrice > pBar.low && + appliedPrice < pBar.GetDown() + // + ; + bool isPressuredSwingLow = + isSwingLow && + hasFiboToUpPressure; + bool isPressuredStrongSwingLow = + pBar.IsBullish() && + isPressuredSwingLow; + + // + bool isSwingHigh = + // + pBar.high > ppBar.high && + pBar.high > cBar.high && + zBar.open < pBar.high && + // + appliedPrice < pBar.high && + appliedPrice > pBar.GetUp() + // + ; + bool isPressuredSwingHigh = + isSwingHigh && + hasFiboToDownPressure; + bool isPressuredStrongSwingHigh = + pBar.IsBearish() && + isPressuredSwingHigh; + + // + bool hasValidSwing = + isBullish + ? isSwingLow + : isSwingHigh; + bool hasValidPressuredSwing = + isBullish + ? isPressuredSwingLow + : isPressuredSwingHigh; + bool hasValidPressuredStrongSwing = + isBullish + ? isPressuredStrongSwingLow + : isPressuredStrongSwingHigh; + if (hasValidSwing) + { + swingBar = pBar; + } + if (hasValidPressuredSwing) + { + swingBar = pBar; + } + if (hasValidPressuredStrongSwing) + { + swingBar = pBar; + } + + // + bool isCBarBreaked = IsBarBreak( + appliedPrice, + forDir, + cBar // + ); + if (isCBarBreaked) + { + breakerBar = cBar; + } + bool isPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarBreaked && isPBarBreaked) + { + breakerBar = pBar; + } + else + { + isPBarBreaked = false; + } + bool isPPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarBreaked && + !isPBarBreaked && + isPPBarBreaked) + { + breakerBar = ppBar; + } + else + { + isPPBarBreaked = false; + } + bool isBoxBreaked = isCBarBreaked || + isPBarBreaked || + isPPBarBreaked; + + // + bool isCBarRejected = IsBarReject( + appliedPrice, + forDir, + cBar // + ); + if (isCBarRejected) + { + rejectionBar = cBar; + } + bool isPBarRejected = IsBarReject( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarRejected && isPBarRejected) + { + rejectionBar = pBar; + } + else + { + isPBarRejected = false; + } + bool isPPBarRejected = IsBarReject( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarRejected && + !isPBarRejected && + isPPBarRejected) + { + rejectionBar = ppBar; + } + else + { + isPPBarRejected = false; + } + bool isBoxRejected = isCBarRejected || + isPBarRejected || + isPPBarRejected; + + // + result = + // + isBoxBreaked || + isBoxRejected || + hasValidPressuredSwing + // + ; + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + else + { + appliedBox = box; + } + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + return result; + } + + // +}; + +// +struct X121SMCXWZWorkingZone +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + double zoneUpper; + double zoneLower; + + // + double quarter1; + double quarter2; + double quarter3; + + // + datetime to; + datetime from; + + // + XOHCL swingBar; + XOHCL breakerBar; + XOHCL momentumBar; + XOHCL rejectionBar; + XBoxZone appliedBox; + + // + X121SMCXWZWorkingZone() + { + Clean(); + } + + // + void Clean() + { + // + upper = 0; + lower = 0; + quarter1 = 0; + quarter2 = 0; + quarter3 = 0; + zoneLower = 0; + zoneUpper = 0; + + // + from = NULL; + symbol = NULL; + period = NULL; + + // + CleanConditionBars(); + + // + ZeroMemory(this); + } + + // + void CleanConditionBars() + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + bool IsValid() + { + // + bool result = false; + + // + result = + lower > 0 && + upper > 0 && + quarter1 > 0 && + quarter2 > 0 && + quarter3 > 0 && + upper > lower && + zoneLower > 0 && + zoneUpper > 0 && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + zoneUpper > upper && + zoneLower < lower; + + // + return result; + } + + // + bool IsDestroyed( + ENUM_X_DIRECTION &destroyedDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + destroyedDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + return result; + } + + // + bool isUpperBreaked = + bar.high > zoneUpper && + bar.close > zoneUpper; + + // + bool isLowerBreaked = + bar.low < zoneLower && + bar.close < zoneLower; + + // + result = isUpperBreaked || + isLowerBreaked; + if (result) + { + // + destroyedDir = + isUpperBreaked + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + // +}; + +// +// Definitions ... +struct X121SMCStrategyXWZSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + double reward; + double amountPercent; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + ENUM_X121SMC_XWZ_PRIORITY priority; + + // + // Working Zone ... + XCFVG *fairValueGap; + XCOrderBlock *orderBlock; + XCSupplyZone *supplyZone; + XCDemandZone *demandZone; + X121SMCXWZWorkingZone workingZone; + + // + // X121SMCXWZZone startZone; + X121SMCXWZZone startZones[]; + + // + // Constructor ... + X121SMCStrategyXWZSignalConditions() + { + 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(); + + // + ZeroMemory(this); + } + + /** + * 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; + + // + target = 0; + reward = 0; + amountPercent = 0; + + // + ZeroMemory(supplyZone); + + // + ZeroMemory(demandZone); + + // + ZeroMemory(orderBlock); + + // + ZeroMemory(fairValueGap); + + // + // startZone.Clean(); + Clean(startZones); + + // + workingZone.Clean(); + } + + // + // + // + + // + bool HasWorkingZone() + { + return workingZone.IsValid(); + } + + // + bool HasOrderBlock() + { + return orderBlock != NULL && + orderBlock.IsValid(); + } + + // + bool HasFairValueGap() + { + return fairValueGap != NULL && + fairValueGap.IsValid(); + } + + // + bool HasSupplyZone() + { + return supplyZone != NULL && + supplyZone.IsValid(); + } + + // + bool HasDemandZone() + { + return demandZone != NULL && + demandZone.IsValid(); + } + + // + bool HasStartZones() + { + return HasChild(startZones); + } + + // + int CountStartZones() + { + return ArraySize(startZones); + } + + // + void UpdateTo(datetime value = NULL) + { + // + value = NormalizeTime(value); + + // + bool hasSupplyZone = HasSupplyZone(); + if (hasSupplyZone) + { + supplyZone.To(value); + } + + // + bool hasDemandZone = HasDemandZone(); + if (hasDemandZone) + { + demandZone.To(value); + } + + // + bool hasOrderBlock = HasOrderBlock(); + if (hasOrderBlock) + { + orderBlock.To(value); + } + + // + bool hasFairValueGap = HasFairValueGap(); + if (hasFairValueGap) + { + fairValueGap.To(value); + } + + // + // Working Zone ... + bool hasWorkingZone = HasWorkingZone(); + if (hasWorkingZone) + { + workingZone.to = value; + } + + // + // Start Zone ... + bool hasStartZones = HasStartZones(); + if (hasStartZones) + { + // + int count = CountStartZones(); + for (int i = 0; i < count; i++) + { + // + bool hasOB = startZones[i].HasOB(); + if (hasOB) + { + startZones[i].ob.To(value); + } + + // + bool hasFVG = startZones[i].HasFVG(); + if (hasFVG) + { + startZones[i].fvg.To(value); + } + + // + bool hasSupply = startZones[i].HasSupply(); + if (hasSupply) + { + startZones[i].supply.To(value); + } + + // + bool hasDemand = startZones[i].HasDemand(); + if (hasDemand) + { + startZones[i].demand.To(value); + } + + // + bool hasSupport = startZones[i].HasSupport(); + if (hasSupport) + { + startZones[i].support.To(value); + } + + // + bool hasResistance = startZones[i].HasResistance(); + if (hasResistance) + { + startZones[i].resistance.To(value); + } + } + } + } + + // + // + // + + // + // Working Zone is an Area which + // we decide to trade inside it ... + bool ExtractWorkingZone( + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &stfState, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + int zIndex = barIndex; + + // + result = !HasWorkingZone(); + if (!result) + { + return result; + } + + // + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + // + Clean(); + return result; + } + + // + datetime cTime = iTime( + symbol, + period, + zIndex // + ); + + // + result = + // + htfState.IsValid() && + htfState.HasChild() && + htfState.HasSupplyZones() && + htfState.HasDemandZones() && + // + mtfState.IsValid() && + mtfState.HasChild() && + mtfState.HasSupplyZones() && + mtfState.HasDemandZones() && + // + stfState.IsValid() && + stfState.HasChild() + // + ; + if (!result) + { + return result; + } + + // + // Retrieve Highest Supply Zone ... + int hSupplyIDX = GetHighest(htfState.supplyZones); + int lDemandIDX = GetLowest(htfState.demandZones); + + // + result = + // + IsValidIndex(hSupplyIDX) && + IsValidIndex(lDemandIDX) + // + ; + if (!result) + { + return result; + } + + // + supplyZone = htfState.supplyZones[hSupplyIDX]; + demandZone = htfState.demandZones[lDemandIDX]; + + // + result = + // + supplyZone != NULL && + demandZone != NULL && + supplyZone.IsValid() && + demandZone.IsValid() + // + ; + if (!result) + { + // + Clean(); + return result; + } + + // + // Check Validation of Supply and Demand Zones ... + lDemandIDX = GetLowest(mtfState.demandZones); + hSupplyIDX = GetHighest(mtfState.supplyZones); + result = IsValidIndex(lDemandIDX) && + IsValidIndex(hSupplyIDX); + if (!result) + { + // + Clean(); + return result; + } + + // + // Validate Supply and Demand ... + bool isMTFHSupplyInside = + IsInside( + mtfState.supplyZones[hSupplyIDX], + supplyZone); + bool isMTFLDemandInside = + IsInside( + mtfState.demandZones[lDemandIDX], + demandZone // + ); + if (isMTFHSupplyInside && + !isMTFLDemandInside) + { + demandZone = mtfState.demandZones[lDemandIDX]; + } + else if (!isMTFHSupplyInside && + isMTFLDemandInside) + { + supplyZone = mtfState.supplyZones[hSupplyIDX]; + } + else if (isMTFHSupplyInside && + isMTFLDemandInside) + { + // + supplyZone = mtfState.supplyZones[hSupplyIDX]; + demandZone = mtfState.demandZones[lDemandIDX]; + } + + // + // Check Zones Validation ... + bool hasTrend = + supplyZone != NULL && + supplyZone.IsValid() && + demandZone != NULL && + demandZone.IsValid(); + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + datetime from = MathMax( + supplyZone.From(), + demandZone.From()); + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + // Detect Trend ... + ENUM_X_DIRECTION trend = X_DIRECTION_NONE; + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = zIndex; i < fromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + period, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + hasTrend = + // + IsValid(supplyTouch) || + IsValid(demandTouch) + // + ; + if (hasTrend) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + // Check Trend ... + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + bool hasBullishTrend = IsBullish(trend); + bool hasBearishTrend = IsBearish(trend); + + // + // Find Order Block and FVG for Trend Approve ... + + // + bool isBullishTrendApproved = false; + bool isBearishTrendApproved = false; + + // + // Now We Have to Detect at least One OrderBlock with FVG ... + // for Trend Approvement ... + bool hasOrderBlock = HasOrderBlock(); + bool hasFairValueGap = HasFairValueGap(); + if (!hasOrderBlock && + !hasFairValueGap) + { + // + int count = 0; + bool has = false; + + // + XCFVG *fvg = NULL; + XCOrderBlock *ob = NULL; + + // + has = mtfState.HasBullishOrderBlocks(); + count = mtfState.CountBullishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bullishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > demandZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + demandZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBullishFairValueGaps(); + count = stfState.CountBullishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bullishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + isBullishTrendApproved = hasOrderBlock && + hasFairValueGap; + } + + // + if (!isBullishTrendApproved) + { + // + has = mtfState.HasBearishOrderBlocks(); + count = mtfState.CountBearishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bearishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > supplyZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + supplyZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBearishFairValueGaps(); + count = stfState.CountBearishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bearishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + isBearishTrendApproved = hasOrderBlock && + hasFairValueGap; + } + } + } + + // + // Check Trend Approved ... + bool isTrendApproved = + hasOrderBlock && + hasFairValueGap && + (isBullishTrendApproved || + isBearishTrendApproved); + result = isTrendApproved; + if (!result) + { + // + Clean(); + return result; + } + + // + // Prepare Working Zone ... + workingZone.symbol = symbol; + workingZone.period = period; + + // + workingZone.upper = supplyZone.Lower(); + workingZone.zoneUpper = supplyZone.Upper(); + + // + workingZone.lower = demandZone.Upper(); + workingZone.zoneLower = demandZone.Lower(); + + // + workingZone.from = from; + + // + double upper = workingZone.upper; + double range = + workingZone.upper - workingZone.lower; + double ranegPercent = range / 100; + double quarterValue = ranegPercent * 25; + + // + workingZone.quarter1 = upper - (quarterValue * 1); + workingZone.quarter2 = upper - (quarterValue * 2); + workingZone.quarter3 = upper - (quarterValue * 3); + + // + result = workingZone.IsValid(); + if (!result) + { + Clean(); + } + + // + return result; + } + + // + bool IsWorkingZoneDestroyed( + ENUM_X_DIRECTION &destroyedDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + destroyedDir = X_DIRECTION_NONE; + + // + result = workingZone.IsValid(); + if (!result) + { + return result; + } + + // + result = workingZone.IsDestroyed( + destroyedDir, + barIndex, + forPeriod // + ); + + // + return result; + } + + // + bool DetectTrend( + ENUM_X_DIRECTION &trend, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (forPeriod == NULL) + { + forPeriod = period; + } + + // + trend = X_DIRECTION_NONE; + + // + result = HasWorkingZone(); + if (!result) + { + return result; + } + + // + int FromIndex = iBarShift( + symbol, + forPeriod, + workingZone.from // + ); + + // + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = barIndex; i < FromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + forPeriod, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + result = + // + IsValid(supplyTouch) || + IsValid(demandTouch) + // + ; + if (result) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + return result; + } + + // + bool DetectStartZones( + ENUM_X_DIRECTION forDir, + XPOIState &obState, + XPOIState &fvgState, + XPOIState &otherState, + XC121SMCCycleHelper *cycleHelper // + ) + { + // + bool result = false; + + // + result = obState.IsValid() && + obState.HasChild() && + fvgState.IsValid() && + fvgState.HasChild() && + otherState.IsValid() && + otherState.HasChild() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + int idx = -1; + int count = 0; + int has = false; + + // + X121SMCXWZZone startZone; + X121SMCXWZZone lastStartZone; + bool hasLastStartZone = HasStartZones(); + if (hasLastStartZone) + { + // + int startZonesCount = CountStartZones(); + lastStartZone = startZones[startZonesCount - 1]; + } + + // + if (isBullish) + { + // + has = obState.HasBullishOrderBlocks(); + if (has) + { + // + count = obState.CountBullishOrderBlocks(); + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = obState.bullishOrderBlocks[i]; + + // + bool isFromPassed = + !hasLastStartZone + ? true + : iOB.From() > lastStartZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(iOB); + continue; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + continue; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = iOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + bool isPlacePassed = + !IsInsideDiff( + iOB, + demandZone // + ) && + (!hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsAbove( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsAbove( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + )); + if (!isPlacePassed) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Attache OB ... + startZone.ob = iOB; + + // + // Now we Have to Find Specified FVG ... + has = fvgState.HasBullishFairValueGaps(); + if (has) + { + // + int jCount = fvgState.CountBullishFairValueGaps(); + for (int j = 0; j < jCount; j++) + { + // + XCFVG *jFVG = fvgState.bullishFairValueGaps[j]; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + isStarted = jFVG.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + continue; + } + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + isActivated = jFVG.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + isPlacePassed = + // + !IsInsideDiff( + jFVG, + demandZone // + ) && + IsAboveDiff( + jFVG, + iOB, + true // Ignore Inside ... + ) + // + ; + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + } + + // + startZone.fvg = jFVG; + } + } + + // + startedBar.Clean(); + activatedBar.Clean(); + } + } + } + else + { + // + has = obState.HasBearishOrderBlocks(); + if (has) + { + // + count = obState.CountBearishOrderBlocks(); + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = obState.bearishOrderBlocks[i]; + + // + bool isFromPassed = + !hasLastStartZone + ? true + : iOB.From() > lastStartZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(iOB); + continue; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + continue; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = iOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + bool isPlacePassed = + !IsInsideDiff( + iOB, + supplyZone // + ) && + (!hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsBelow( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsBelow( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + )); + if (!isPlacePassed) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Attache OB ... + startZone.ob = iOB; + + // + // Now we Have to Find Specified FVG ... + has = fvgState.HasBearishFairValueGaps(); + if (has) + { + // + int jCount = fvgState.CountBearishFairValueGaps(); + for (int j = 0; j < jCount; j++) + { + // + XCFVG *jFVG = fvgState.bearishFairValueGaps[j]; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + isStarted = jFVG.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + continue; + } + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + isActivated = jFVG.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + isPlacePassed = + // + !IsInsideDiff( + jFVG, + supplyZone // + ) && + IsBelowDiff( + jFVG, + iOB, + true // Ignore Inside ... + ) + // + ; + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + } + + // + startZone.fvg = jFVG; + } + } + + // + startedBar.Clean(); + activatedBar.Clean(); + } + } + } + + // + bool hasOBFVG = startZone.HasOB() && + startZone.HasFVG(); + result = hasOBFVG; + if (!result) + { + // + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + XBoxZone startBox; + bool hasStartBox = startZone.AsBox(startBox); + result = hasStartBox; + if (!result) + { + // + startBox.Clean(); + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + // Detect Other Zones Inside Box ... + XBoxZone tmpBoxes[]; + + // + // Supply Zones ... + has = otherState.HasSupplyZones(); + if (has) + { + // + count = ToBox( + otherState.supplyZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.supply = otherState.supplyZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Demand Zones ... + Clean(tmpBoxes); + has = otherState.HasDemandZones(); + if (has) + { + // + count = ToBox( + otherState.demandZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.demand = otherState.demandZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Support Zones ... + Clean(tmpBoxes); + has = otherState.HasSupportZones(); + if (has) + { + // + count = ToBox( + otherState.supportZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.support = otherState.supportZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Resistance Zones ... + Clean(tmpBoxes); + has = otherState.HasResistanceZones(); + if (has) + { + // + count = ToBox( + otherState.resistanceZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.resistance = otherState.resistanceZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + result = startZone.IsValid() && + startZone.HasDirection(); + if (result) + { + // + AddRef( + startZone, + startZones // + ); + } + + // + Clean(tmpBoxes); + startBox.Clean(); + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + void DetectPriority( + ENUM_X121SMC_XWZ_PRIORITY &bullish, + ENUM_X121SMC_XWZ_PRIORITY &bearish, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bullish = X121SMC_XWZ_PRIORITY_NONE; + bearish = X121SMC_XWZ_PRIORITY_NONE; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + bool hasWorkingZone = HasWorkingZone(); + if (!hasWorkingZone) + { + return; + } + + // + XOHCL zBar; + bool isInited = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!isInited) + { + // + zBar.Clean(); + return; + } + + // + XOHCL cBar; + isInited = zBar.GetPreviousBar(cBar); + if (!isInited) + { + // + zBar.Clean(); + cBar.Clean(); + return; + } + + // + // ZoneUpper, Upper ... + if (cBar.low > workingZone.upper && + cBar.high < workingZone.zoneUpper && + zBar.low > workingZone.upper && + zBar.high < workingZone.zoneUpper) + { + // + bullish = X121SMC_XWZ_PRIORITY_NONE; + bearish = X121SMC_XWZ_PRIORITY_STRONG_HIGH; + } + // + // Upper, Quarter1 ... + else if (cBar.low > workingZone.quarter1 && + cBar.high < workingZone.upper && + zBar.low > workingZone.quarter1 && + zBar.high < workingZone.upper) + { + // + bullish = X121SMC_XWZ_PRIORITY_WEAK; + bearish = X121SMC_XWZ_PRIORITY_HIGH; + } + // + // Quarter1, Quarter2 ... + else if (cBar.low > workingZone.quarter2 && + cBar.high < workingZone.quarter1 && + zBar.low > workingZone.quarter2 && + zBar.high < workingZone.quarter1) + { + // + bullish = X121SMC_XWZ_PRIORITY_LOW; + bearish = X121SMC_XWZ_PRIORITY_REGULAR; + } + // + // Quarter2, Quarter3 ... + else if (cBar.low > workingZone.quarter3 && + cBar.high < workingZone.quarter2 && + zBar.low > workingZone.quarter3 && + zBar.high < workingZone.quarter2) + { + // + bullish = X121SMC_XWZ_PRIORITY_REGULAR; + bearish = X121SMC_XWZ_PRIORITY_LOW; + } + // + // Quarter3, Lower ... + else if (cBar.low > workingZone.lower && + cBar.high < workingZone.quarter3 && + zBar.low > workingZone.lower && + zBar.high < workingZone.quarter3) + { + // + bullish = X121SMC_XWZ_PRIORITY_HIGH; + bearish = X121SMC_XWZ_PRIORITY_WEAK; + } + // + // Lower, ZoneLower ... + else if (cBar.low > workingZone.zoneLower && + cBar.high < workingZone.lower && + zBar.low > workingZone.zoneLower && + zBar.high < workingZone.lower) + { + // + bullish = X121SMC_XWZ_PRIORITY_STRONG_HIGH; + bearish = X121SMC_XWZ_PRIORITY_NONE; + } + + // + zBar.Clean(); + cBar.Clean(); + } + + // + bool HasConditions( + double &_pivot, + double &_point, + ENUM_X_DIRECTION &conditionsDir, + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + _pivot = 0; + _point = 0; + conditionsDir = X_DIRECTION_NONE; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (forPeriod == NULL) + { + forPeriod = period; + } + + // + result = + // + IsValid(symbol) && + IsValid(period) && + state.IsValid() && + HasWorkingZone() && + state.HasChild() + // + ; + if (!result) + { + return result; + } + + // + result = false; + + // + // Detect Conditions Based On Start Zones ... + bool hasStartZones = HasStartZones(); + if (hasStartZones) + { + // + int selectedIndex = -1; + int count = CountStartZones(); + for (int i = 0; i < count; i++) + { + // + X121SMCXWZZone iStartZone = startZones[i]; + + // + XBoxZone selectedBox; + bool hasConditions = false; + bool isBullish = iStartZone.IsBullish(); + + // + // Conditions Inside Box ... + bool isPriceInside = iStartZone.IsPriceInside( + selectedBox, + barIndex, + forPeriod, + false, + false // + ); + if (isPriceInside) + { + // + // hasConditions = iStartZone.HasInsideConditions( + // state, + // barIndex, + // period // + // ); + + // + hasConditions = true; + + // + if (hasConditions) + { + // + _pivot = + // + isBullish + ? selectedBox.lower + : selectedBox.upper + // + ; + + // + _point = + // + isBullish + ? selectedBox.upper + : selectedBox.lower + // + ; + + // + conditionsDir = selectedBox.dir; + result = hasConditions; + iStartZone.Clean(); + break; + } + } + + // // + // // Order Block Rejection Conditions ... + // bool hasOBBox = ToBox( + // selectedBox, + // iStartZone.ob // + // ); + // if (hasOBBox && + // !hasConditions) + // { + // // + // hasConditions = iStartZone.HasBoxConitions( + // selectedBox, + // state, + // barIndex, + // forPeriod // + // ); + + // // + // if (hasConditions) + // { + // // + // _pivot = + // // + // isBullish + // ? selectedBox.lower + // : selectedBox.upper + // // + // ; + + // // + // _point = + // // + // isBullish + // ? selectedBox.upper + // : selectedBox.lower + // // + // ; + + // // + // conditionsDir = selectedBox.dir; + // result = hasConditions; + // iStartZone.Clean(); + // break; + // } + // } + + // // + // // Fair Value Gap Rejection Conditions ... + // bool hasFVGBox = ToBox( + // selectedBox, + // iStartZone.fvg // + // ); + // if (hasFVGBox) + // { + // // + // hasConditions = iStartZone.HasBoxConitions( + // selectedBox, + // state, + // barIndex, + // forPeriod // + // ); + + // // + // if (hasConditions) + // { + // // + // _pivot = + // // + // isBullish + // ? selectedBox.lower + // : selectedBox.upper + // // + // ; + + // // + // _point = + // // + // isBullish + // ? selectedBox.upper + // : selectedBox.lower + // // + // ; + + // // + // conditionsDir = selectedBox.dir; + // result = hasConditions; + // iStartZone.Clean(); + // break; + // } + // } + + // + iStartZone.Clean(); + } + + // + if (result && + IsValidIndex(selectedIndex)) + { + // + ArrayRemove( + startZones, + selectedIndex, + 1 // + ); + } + } + + // + // Detect Conditions Based On Working Zones ... + if (!result) + { + // + // Detect Result Based On WorkingZone ... + } + + // + if (!result) + { + // + _point = 0; + _pivot = 0; + conditionsDir = X_DIRECTION_NONE; + + // + return result; + } + + // + return result; + } + + // +}; + +// +bool X121SMCXWZCheckPriceInside( + XOHCL &zBar, + XOHCL &cBar, + double upper, + double lower // +) +{ + // + bool result = false; + + // + result = zBar.IsValid() && + cBar.IsValid() && + upper > 0 && + lower > 0 && + upper > lower && + zBar.time > cBar.time; + if (!result) + { + return result; + } + + // + result = + // + zBar.high < upper && + cBar.high < upper && + // + zBar.low > lower && + cBar.low > lower + // + ; + + // + return result; +} + +// \ No newline at end of file diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 index dbe50b02..93ee287f 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 @@ -374,7 +374,9 @@ class XCX121SMCXWZSignalDetector : public XCBase // bool hasStartZone = mConditions.DetectStartZones( trend, + consolidationState, analyseState, + decisionState, decisionCycleHelper // ); @@ -639,8 +641,8 @@ class XCX121SMCXWZSignalDetector : public XCBase result = hasConditions && hasRewardAmount && isPriorityPassed && - trend == conditionsDir && - isConsolidationZonePassed; + trend == conditionsDir; // && + // isConsolidationZonePassed; if (!result) { // @@ -741,7 +743,7 @@ class XCX121SMCXWZSignalDetector : public XCBase XC121SMCCycleHelper *consolidationCycleHelper, XC121SMCCycleHelper *visionCycleHelper, // - int maxAllowedSetupAge = 60 + int maxAllowedSetupAge = 30 // ) { @@ -896,7 +898,8 @@ class XCX121SMCXWZSignalDetector : public XCBase isBullish = // isBullish && - isPointBreaked + isPointBreaked && + cBar.IsBullish() // ; @@ -904,7 +907,8 @@ class XCX121SMCXWZSignalDetector : public XCBase isBearish = // isBearish && - isPointBreaked + isPointBreaked && + cBar.IsBearish() // ; @@ -961,6 +965,9 @@ class XCX121SMCXWZSignalDetector : public XCBase sls // ); + // + // TODO: Add Consolidation Zone for SLs ... + // double iAtr = decisionXConditions.atrBuffer[1]; iAtr *= 2; @@ -2315,77 +2322,77 @@ class XCX121SMCXWZSignalDetector : public XCBase ); } - // - bool hasSupply = conditions.startZones[i].HasSupply(); - if (hasSupply) - { - // - XCSupplyZoneObject *iObj; - isCreated = drawer.CreateSupplyZone( - conditions.startZones[i].supply, - iObj // - ); + // // + // bool hasSupply = conditions.startZones[i].HasSupply(); + // if (hasSupply) + // { + // // + // XCSupplyZoneObject *iObj; + // isCreated = drawer.CreateSupplyZone( + // conditions.startZones[i].supply, + // iObj // + // ); - // - if (isCreated) - { - mObjects.Add(iObj); - } - } + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } - // - bool hasDemand = conditions.startZones[i].HasDemand(); - if (hasDemand) - { - // - XCDemandZoneObject *iObj; - isCreated = drawer.CreateDemandZone( - conditions.startZones[i].demand, - iObj // - ); + // // + // bool hasDemand = conditions.startZones[i].HasDemand(); + // if (hasDemand) + // { + // // + // XCDemandZoneObject *iObj; + // isCreated = drawer.CreateDemandZone( + // conditions.startZones[i].demand, + // iObj // + // ); - // - if (isCreated) - { - mObjects.Add(iObj); - } - } + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } - // - bool hasSupport = conditions.startZones[i].HasSupport(); - if (hasSupport) - { - // - XCSupportZoneObject *iObj; - isCreated = drawer.CreateSupportZone( - conditions.startZones[i].support, - iObj // - ); + // // + // bool hasSupport = conditions.startZones[i].HasSupport(); + // if (hasSupport) + // { + // // + // XCSupportZoneObject *iObj; + // isCreated = drawer.CreateSupportZone( + // conditions.startZones[i].support, + // iObj // + // ); - // - if (isCreated) - { - mObjects.Add(iObj); - } - } + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } - // - bool hasResistance = conditions.startZones[i].HasResistance(); - if (hasResistance) - { - // - XCResistanceZoneObject *iObj; - isCreated = drawer.CreateResistanceZone( - conditions.startZones[i].resistance, - iObj // - ); + // // + // bool hasResistance = conditions.startZones[i].HasResistance(); + // if (hasResistance) + // { + // // + // XCResistanceZoneObject *iObj; + // isCreated = drawer.CreateResistanceZone( + // conditions.startZones[i].resistance, + // iObj // + // ); - // - if (isCreated) - { - mObjects.Add(iObj); - } - } + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + // } // // diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 index e68abd68..9a7025d0 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 @@ -235,6 +235,67 @@ struct X121SMCXWZZone IsBearish(); } + // + bool ValidateZone( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = IsValid() && + HasDirection(); + if (!result) + { + return result; + } + + // + string symbol = ob.GetSymbol(); + if (forPeriod == NULL) + { + forPeriod = ob.GetPeriod(); + } + ENUM_X_DIRECTION forDir = GetDirection(); + + // + XOHCL cBar; + result = cBar.Init( + symbol, + forPeriod, + barIndex + 1 // + ); + if (!result) + { + // + cBar.Clean(); + return result; + } + + // + bool isBreaked = + IsBullish(forDir) + ? cBar.close < ob.Lower() || + cBar.close < fvg.Lower() + : cBar.close > ob.Upper() || + cBar.close > fvg.Upper(); + result = !isBreaked; + + // + cBar.Clean(); + + // + return result; + } + // ENUM_X_DIRECTION GetDirection() { @@ -265,7 +326,9 @@ struct X121SMCXWZZone bool IsPriceInside( XBoxZone &box, int barIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // + ENUM_TIMEFRAMES forPeriod = NULL, + bool forceOB = false, + bool forceFVG = false // ) { // @@ -382,49 +445,82 @@ struct X121SMCXWZZone } // - bool isPriceInsideOB = - isBullish - ? ( - // - pBar.low > ob.Upper() && - cBar.low <= ob.Upper() && - zBar.open <= ob.Upper() - // - ) - : ( - // - pBar.high < ob.Lower() && - cBar.high >= ob.Lower() && - zBar.open >= ob.Lower() - // - ); + bool isPriceInsideOB = X121SMCXWZCheckPriceInside( + zBar, + cBar, + ob.Upper(), + ob.Lower() // + ); // - bool isPriceInsideFVG = - isBullish - ? ( - // - pBar.low > fvg.Upper() && - cBar.low <= fvg.Upper() && - zBar.open <= fvg.Upper() - // - ) - : ( - // - pBar.high < fvg.Lower() && - cBar.high >= fvg.Lower() && - zBar.open >= fvg.Lower() - // - ); + // isBullish + // ? ( + // // + // pBar.close > ob.Upper() && + // cBar.low <= ob.Upper() && + // cBar.close <= ob.Upper() && + // zBar.open <= ob.Upper() + // // + // ) + // : ( + // // + // pBar.close < ob.Lower() && + // cBar.high >= ob.Lower() && + // cBar.close >= ob.Lower() && + // zBar.open >= ob.Lower() + // // + // ); + + // + bool isPriceInsideFVG = X121SMCXWZCheckPriceInside( + zBar, + cBar, + fvg.Upper(), + fvg.Lower() // + ); + + // + // isBullish + // ? ( + // // + // pBar.close > fvg.Upper() && + // cBar.low <= fvg.Upper() && + // cBar.close <= fvg.Upper() && + // zBar.open <= fvg.Upper() + // // + // ) + // : ( + // // + // pBar.close < fvg.Lower() && + // cBar.high >= fvg.Lower() && + // cBar.close >= fvg.Lower() && + // zBar.open >= fvg.Lower() + // // + // ); + + // + if ((forceOB && forceFVG) || + (!forceOB && !forceFVG)) + { + // + result = + isPriceInsideOB || + isPriceInsideFVG; + } + else if (forceOB) + { + result = isPriceInsideOB; + } + else if (forceFVG) + { + result = isPriceInsideFVG; + } // - result = - isPriceInsideOB || - isPriceInsideFVG; if (result) { // - if (isPriceInsideOB) + if (isPriceInsideOB && !isPriceInsideFVG) { // result = ToBox( @@ -432,7 +528,7 @@ struct X121SMCXWZZone ob // ); } - else if (isPriceInsideFVG) + else if (isPriceInsideFVG && !isPriceInsideOB) { // result = ToBox( @@ -440,6 +536,10 @@ struct X121SMCXWZZone fvg // ); } + else if (isPriceInsideOB && isPriceInsideFVG) + { + result = AsBox(box); + } } // @@ -2462,7 +2562,9 @@ struct X121SMCStrategyXWZSignalConditions // bool DetectStartZones( ENUM_X_DIRECTION forDir, - XPOIState &state, + XPOIState &obState, + XPOIState &fvgState, + XPOIState &otherState, XC121SMCCycleHelper *cycleHelper // ) { @@ -2470,8 +2572,12 @@ struct X121SMCStrategyXWZSignalConditions bool result = false; // - result = state.IsValid() && - state.HasChild() && + result = obState.IsValid() && + obState.HasChild() && + fvgState.IsValid() && + fvgState.HasChild() && + otherState.IsValid() && + otherState.HasChild() && HasDirection(forDir); if (!result) { @@ -2501,15 +2607,15 @@ struct X121SMCStrategyXWZSignalConditions if (isBullish) { // - has = state.HasBullishOrderBlocks(); + has = obState.HasBullishOrderBlocks(); if (has) { // - count = state.CountBullishOrderBlocks(); + count = obState.CountBullishOrderBlocks(); for (int i = 0; i < count; i++) { // - XCOrderBlock *iOB = state.bullishOrderBlocks[i]; + XCOrderBlock *iOB = obState.bullishOrderBlocks[i]; // bool isFromPassed = @@ -2556,24 +2662,48 @@ struct X121SMCStrategyXWZSignalConditions continue; } + // + // Validate Zone Iverse Breake ... + XOHCL breakedBar; + ENUM_X_DIRECTION breakedDir; + bool isBreaked = iOB.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + // bool isPlacePassed = - !hasLastStartZone - ? workingZone.IsValid() && - HasOrderBlock() && - forDir == orderBlock.GetDirection() - ? IsAbove( - iOB, - orderBlock, - true // Ignore Inside ... - ) - : true - : lastStartZone.HasOB() && - IsAbove( - iOB, - lastStartZone.ob, - true // Ignore Inside ... - ); + !IsInsideDiff( + iOB, + demandZone // + ) && + (!hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsAbove( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsAbove( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + )); if (!isPlacePassed) { // @@ -2589,15 +2719,15 @@ struct X121SMCStrategyXWZSignalConditions // // Now we Have to Find Specified FVG ... - has = state.HasBullishFairValueGaps(); + has = fvgState.HasBullishFairValueGaps(); if (has) { // - int jCount = state.CountBullishFairValueGaps(); + int jCount = fvgState.CountBullishFairValueGaps(); for (int j = 0; j < jCount; j++) { // - XCFVG *jFVG = state.bullishFairValueGaps[j]; + XCFVG *jFVG = fvgState.bullishFairValueGaps[j]; // startedBar.Clean(); @@ -2632,9 +2762,33 @@ struct X121SMCStrategyXWZSignalConditions continue; } + // + // Validate Zone Iverse Breake ... + breakedBar.Clean(); + breakedDir = X_DIRECTION_NONE; + bool isBreaked = jFVG.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + // isPlacePassed = // + !IsInsideDiff( + jFVG, + demandZone // + ) && IsAboveDiff( jFVG, iOB, @@ -2664,15 +2818,15 @@ struct X121SMCStrategyXWZSignalConditions else { // - has = state.HasBearishOrderBlocks(); + has = obState.HasBearishOrderBlocks(); if (has) { // - count = state.CountBearishOrderBlocks(); + count = obState.CountBearishOrderBlocks(); for (int i = 0; i < count; i++) { // - XCOrderBlock *iOB = state.bearishOrderBlocks[i]; + XCOrderBlock *iOB = obState.bearishOrderBlocks[i]; // bool isFromPassed = @@ -2719,24 +2873,48 @@ struct X121SMCStrategyXWZSignalConditions continue; } + // + // Validate Zone Iverse Breake ... + XOHCL breakedBar; + ENUM_X_DIRECTION breakedDir; + bool isBreaked = iOB.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + // bool isPlacePassed = - !hasLastStartZone - ? workingZone.IsValid() && - HasOrderBlock() && - forDir == orderBlock.GetDirection() - ? IsBelow( - iOB, - orderBlock, - true // Ignore Inside ... - ) - : true - : lastStartZone.HasOB() && - IsBelow( - iOB, - lastStartZone.ob, - true // Ignore Inside ... - ); + !IsInsideDiff( + iOB, + supplyZone // + ) && + (!hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsBelow( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsBelow( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + )); if (!isPlacePassed) { // @@ -2752,15 +2930,15 @@ struct X121SMCStrategyXWZSignalConditions // // Now we Have to Find Specified FVG ... - has = state.HasBearishFairValueGaps(); + has = fvgState.HasBearishFairValueGaps(); if (has) { // - int jCount = state.CountBearishFairValueGaps(); + int jCount = fvgState.CountBearishFairValueGaps(); for (int j = 0; j < jCount; j++) { // - XCFVG *jFVG = state.bearishFairValueGaps[j]; + XCFVG *jFVG = fvgState.bearishFairValueGaps[j]; // startedBar.Clean(); @@ -2795,9 +2973,33 @@ struct X121SMCStrategyXWZSignalConditions continue; } + // + // Validate Zone Iverse Breake ... + breakedBar.Clean(); + breakedDir = X_DIRECTION_NONE; + bool isBreaked = jFVG.IsBreaked( + Opposit(forDir), + breakedBar, + breakedDir, + true // Ignore Activation ... + ); + if (isBreaked) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + breakedBar.Clean(); + activatedBar.Clean(); + continue; + } + // isPlacePassed = // + !IsInsideDiff( + jFVG, + supplyZone // + ) && IsBelowDiff( jFVG, iOB, @@ -2860,12 +3062,12 @@ struct X121SMCStrategyXWZSignalConditions // // Supply Zones ... - has = state.HasSupplyZones(); + has = otherState.HasSupplyZones(); if (has) { // count = ToBox( - state.supplyZones, + otherState.supplyZones, tmpBoxes // ); @@ -2898,7 +3100,7 @@ struct X121SMCStrategyXWZSignalConditions } // - startZone.supply = state.supplyZones[i]; + startZone.supply = otherState.supplyZones[i]; // iBox.Clean(); @@ -2910,12 +3112,12 @@ struct X121SMCStrategyXWZSignalConditions // // Demand Zones ... Clean(tmpBoxes); - has = state.HasDemandZones(); + has = otherState.HasDemandZones(); if (has) { // count = ToBox( - state.demandZones, + otherState.demandZones, tmpBoxes // ); @@ -2948,7 +3150,7 @@ struct X121SMCStrategyXWZSignalConditions } // - startZone.demand = state.demandZones[i]; + startZone.demand = otherState.demandZones[i]; // iBox.Clean(); @@ -2960,12 +3162,12 @@ struct X121SMCStrategyXWZSignalConditions // // Support Zones ... Clean(tmpBoxes); - has = state.HasSupportZones(); + has = otherState.HasSupportZones(); if (has) { // count = ToBox( - state.supportZones, + otherState.supportZones, tmpBoxes // ); @@ -2998,7 +3200,7 @@ struct X121SMCStrategyXWZSignalConditions } // - startZone.support = state.supportZones[i]; + startZone.support = otherState.supportZones[i]; // iBox.Clean(); @@ -3010,12 +3212,12 @@ struct X121SMCStrategyXWZSignalConditions // // Resistance Zones ... Clean(tmpBoxes); - has = state.HasResistanceZones(); + has = otherState.HasResistanceZones(); if (has) { // count = ToBox( - state.resistanceZones, + otherState.resistanceZones, tmpBoxes // ); @@ -3048,7 +3250,7 @@ struct X121SMCStrategyXWZSignalConditions } // - startZone.resistance = state.resistanceZones[i]; + startZone.resistance = otherState.resistanceZones[i]; // iBox.Clean(); @@ -3079,6 +3281,48 @@ struct X121SMCStrategyXWZSignalConditions return result; } + // + void ValidateStartZones( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool has = HasStartZones(); + if (!has) + { + return; + } + + // + X121SMCXWZZone tmpZones[]; + int count = CountStartZones(); + Copy( + startZones, + tmpZones // + ); + for (int i = 0; i < count; i++) + { + // + bool isValid = tmpZones[i].ValidateZone( + barIndex, + forPeriod // + ); + if (!isValid) + { + // + ArrayRemove( + startZones, + i, + 1 // + ); + } + } + + // + Clean(tmpZones); + } + // void DetectPriority( ENUM_X121SMC_XWZ_PRIORITY &bullish, @@ -3255,6 +3499,12 @@ struct X121SMCStrategyXWZSignalConditions // result = false; + // + ValidateStartZones( + barIndex, + forPeriod // + ); + // // Detect Conditions Based On Start Zones ... bool hasStartZones = HasStartZones(); @@ -3278,16 +3528,21 @@ struct X121SMCStrategyXWZSignalConditions bool isPriceInside = iStartZone.IsPriceInside( selectedBox, barIndex, - forPeriod // + forPeriod, + false, + false // ); if (isPriceInside) { // - hasConditions = iStartZone.HasInsideConditions( - state, - barIndex, - period // - ); + // hasConditions = iStartZone.HasInsideConditions( + // state, + // barIndex, + // period // + // ); + + // + hasConditions = true; // if (hasConditions) @@ -3318,96 +3573,96 @@ struct X121SMCStrategyXWZSignalConditions } } - // - // Order Block Rejection Conditions ... - bool hasOBBox = ToBox( - selectedBox, - iStartZone.ob // - ); - if (hasOBBox && - !hasConditions) - { - // - hasConditions = iStartZone.HasBoxConitions( - selectedBox, - state, - barIndex, - forPeriod // - ); + // // + // // Order Block Rejection Conditions ... + // bool hasOBBox = ToBox( + // selectedBox, + // iStartZone.ob // + // ); + // if (hasOBBox && + // !hasConditions) + // { + // // + // hasConditions = iStartZone.HasBoxConitions( + // selectedBox, + // state, + // barIndex, + // forPeriod // + // ); - // - if (hasConditions) - { - // - _pivot = - // - isBullish - ? selectedBox.lower - : selectedBox.upper - // - ; + // // + // if (hasConditions) + // { + // // + // _pivot = + // // + // isBullish + // ? selectedBox.lower + // : selectedBox.upper + // // + // ; - // - _point = - // - isBullish - ? selectedBox.upper - : selectedBox.lower - // - ; + // // + // _point = + // // + // isBullish + // ? selectedBox.upper + // : selectedBox.lower + // // + // ; - // - conditionsDir = selectedBox.dir; - result = hasConditions; - iStartZone.Clean(); - break; - } - } + // // + // conditionsDir = selectedBox.dir; + // result = hasConditions; + // iStartZone.Clean(); + // break; + // } + // } - // - // Fair Value Gap Rejection Conditions ... - bool hasFVGBox = ToBox( - selectedBox, - iStartZone.fvg // - ); - if (hasFVGBox) - { - // - hasConditions = iStartZone.HasBoxConitions( - selectedBox, - state, - barIndex, - forPeriod // - ); + // // + // // Fair Value Gap Rejection Conditions ... + // bool hasFVGBox = ToBox( + // selectedBox, + // iStartZone.fvg // + // ); + // if (hasFVGBox) + // { + // // + // hasConditions = iStartZone.HasBoxConitions( + // selectedBox, + // state, + // barIndex, + // forPeriod // + // ); - // - if (hasConditions) - { - // - _pivot = - // - isBullish - ? selectedBox.lower - : selectedBox.upper - // - ; + // // + // if (hasConditions) + // { + // // + // _pivot = + // // + // isBullish + // ? selectedBox.lower + // : selectedBox.upper + // // + // ; - // - _point = - // - isBullish - ? selectedBox.upper - : selectedBox.lower - // - ; + // // + // _point = + // // + // isBullish + // ? selectedBox.upper + // : selectedBox.lower + // // + // ; - // - conditionsDir = selectedBox.dir; - result = hasConditions; - iStartZone.Clean(); - break; - } - } + // // + // conditionsDir = selectedBox.dir; + // result = hasConditions; + // iStartZone.Clean(); + // break; + // } + // } // iStartZone.Clean(); @@ -3452,3 +3707,43 @@ struct X121SMCStrategyXWZSignalConditions // }; + +// +bool X121SMCXWZCheckPriceInside( + XOHCL &zBar, + XOHCL &cBar, + double upper, + double lower // +) +{ + // + bool result = false; + + // + result = zBar.IsValid() && + cBar.IsValid() && + upper > 0 && + lower > 0 && + upper > lower && + zBar.time > cBar.time; + if (!result) + { + return result; + } + + // + result = + // + zBar.high < upper && + cBar.high < upper && + // + zBar.low > lower && + cBar.low > lower + // + ; + + // + return result; +} + +// \ No newline at end of file