From ad3a9e691f30a4ccb344144304637412fcdc2e4a Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 10 Feb 2025 14:15:06 +0330 Subject: [PATCH] last ... --- Libraries/x-saherelm.x-poi.lib.mq5 | 598 ++++++++++++++++++ .../x-121.smc.market.cycle.helper.class.mq5 | 3 + .../x-121.smc.xsupdemobs.signal.lib.mq5 | 101 ++- 3 files changed, 686 insertions(+), 16 deletions(-) diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 5b9bf548..e9e265f3 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -8558,6 +8558,476 @@ int GetLowest( return result; } +template +int FilterZones( + T *source, + F *&dest[], + bool filterDirection = true, + bool filterFrom = true, + bool filterPrice = true, + bool ignoreOutOfBox = false, + bool applySort = false, + bool ignoreInside = true // +) +{ + // + int result = 0; + + // + int count = ArraySize(dest); + if (source == NULL || + !source.IsValid() || + !IsValidSize(count)) + { + return result; + } + + // + XBoxZone sourceBox; + bool hasSourceBox = ToBox( + sourceBox, + source // + ); + if (!hasSourceBox) + { + return result; + } + + // + F *tmp[]; + for (int i = 0; i < count; i++) + { + // + F *iZone = dest[i]; + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + continue; + } + + // + ENUM_X_DIRECTION iDir = iBox.dir; + bool isIBullish = IsBullish(iDir); + + // + if (filterDirection) + { + // + bool isDirectionPassed = + sourceBox.dir == iDir; + if (!isDirectionPassed) + { + continue; + } + } + + // + if (filterFrom) + { + // + bool isFromPassed = iBox.from > sourceBox.from; + if (!isFromPassed) + { + continue; + } + } + + // + if (filterPrice) + { + // + bool isInside = IsBoxInside( + iBox, + sourceBox // + ); + + // + bool isAbove = IsBoxAbove( + iBox, + sourceBox, + ignoreInside // + ); + + // + bool isBelow = IsBoxBelow( + iBox, + sourceBox, + ignoreInside // + ); + + // + bool isPricePassed = + // + isInside = + ignoreOutOfBox + ? isInside + : isInside && + (isIBullish + ? isAbove + : isBelow) + // + ; + if (!isPricePassed) + { + continue; + } + + // + Add( + iZone, + tmp // + ); + } + } + + // + Clean(dest); + if (HasChild(tmp)) + { + // + Copy( + tmp, + dest // + ); + + // + Clean(tmp); + } + + // + if (applySort) + { + // + F *lastZone; + XBoxZone last; + count = ArraySize(dest); + if (HasChild(dest)) + { + // + int idx = GetYoungest(dest); + if (IsValidIndex(idx)) + { + // + lastZone = dest[idx]; + ArrayRemove( + dest, + idx, + 1 // + ); + + // + count = ArraySize(dest); + bool hasLastBox = ToBox( + last, + lastZone // + ); + } + + // + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + F *iZone = dest[i]; + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + continue; + } + + // + bool isLastPassed = + last.IsValid() && + (IsBullish(last.dir) + ? IsBoxAbove( + iBox, + last, + true // + ) + : IsBoxBelow( + iBox, + last, + true // + )); + if (!isLastPassed) + { + continue; + } + + // + lastZone = iZone; + bool hasLastBox = ToBox( + last, + lastZone // + ); + Add( + iZone, + tmp // + ); + } + } + else + { + // + if (last.IsValid()) + { + // + AddRef( + lastZone, + tmp // + ); + } + } + } + } + + // + Clean(dest); + if (HasChild(tmp)) + { + // + Copy( + tmp, + dest // + ); + } + + // + result = ArraySize(dest); + + // + Clean(tmp); + + // + return result; +} + +int FilterBoxes( + XBoxZone &source, + XBoxZone &dest[], + bool filterDirection = true, + bool filterFrom = true, + bool filterPrice = true, + bool ignoreOutOfBox = false, + bool applySort = false, + bool ignoreInside = true // +) +{ + // + int result = 0; + + // + int count = ArraySize(dest); + if (!source.IsValid() || + !IsValidSize(count)) + { + return result; + } + + // + XBoxZone tmp[]; + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = dest[i]; + ENUM_X_DIRECTION iDir = iBox.dir; + bool isIBullish = IsBullish(iDir); + + // + if (filterDirection) + { + // + bool isDirectionPassed = + source.dir == iDir; + if (!isDirectionPassed) + { + continue; + } + } + + // + if (filterFrom) + { + // + bool isFromPassed = iBox.from > source.from; + if (!isFromPassed) + { + continue; + } + } + + // + if (filterPrice) + { + // + bool isInside = IsBoxInside( + iBox, + source // + ); + + // + bool isAbove = IsBoxAbove( + iBox, + source, + ignoreInside // + ); + + // + bool isBelow = IsBoxBelow( + iBox, + source, + ignoreInside // + ); + + // + bool isPricePassed = + // + ignoreOutOfBox + ? isInside + : isInside && + (isIBullish + ? isAbove + : isBelow) + // + ; + if (!isPricePassed) + { + continue; + } + + // + AddRef( + iBox, + tmp // + ); + } + } + + // + if (HasChild(tmp)) + { + // + Clean(dest); + + // + Copy( + tmp, + dest // + ); + + // + Clean(tmp); + } + + // + if (applySort) + { + // + XBoxZone last; + count = ArraySize(dest); + if (HasChild(dest)) + { + // + int idx = GetYoungest(dest); + if (IsValidIndex(idx)) + { + // + last = dest[idx]; + ArrayRemove( + dest, + idx, + 1 // + ); + + // + count = ArraySize(dest); + } + + // + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = dest[i]; + + // + bool isLastPassed = + last.IsValid() && + (IsBullish(last.dir) + ? IsBoxAbove( + iBox, + last, + true // + ) + : IsBoxBelow( + iBox, + last, + true // + )); + if (!isLastPassed) + { + continue; + } + + // + last = iBox; + AddRef( + iBox, + tmp // + ); + } + } + else + { + // + if (last.IsValid()) + { + // + AddRef( + last, + tmp // + ); + } + } + } + } + + // + if (HasChild(tmp)) + { + // + Clean(dest); + + // + Copy( + tmp, + dest // + ); + } + + // + result = ArraySize(dest); + + // + return result; +} + // typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event, XCBasePOI *param // @@ -9066,6 +9536,134 @@ void OrderedSortZones( } } +void OrderedSortBoxes( + XBoxZone &items[] // +) +{ + // + int count = ArraySize(items); + if (!IsValidSize(count)) + { + return; + } + + // + // Detect Youngest ... + int youngestIDX = GetYoungest( + items // + ); + bool hasYoungest = IsValidSize(youngestIDX); + if (!hasYoungest) + { + return; + } + + // + XBoxZone youngest = items[youngestIDX]; + ArrayRemove( + items, + youngestIDX, + 1 // + ); + count = ArraySize(items); + if (!IsValidSize(count)) + { + // + AddRef( + youngest, + items // + ); + + // + return; + } + + // + if (!youngest.IsValid()) + { + return; + } + + // + ENUM_X_DIRECTION dir = youngest.dir; + bool isBullish = IsBullish(dir); + + // + XBoxZone tmp[]; + XBoxZone last = youngest; + while (IsValidSize(count)) + { + // + // Detect Youngest of Collection ... + int idx = GetYoungest(items); + XBoxZone iChild = items[idx]; + ArrayRemove( + items, + idx, + 1 // + ); + count = ArraySize(items); + + // + // Check Direction Must be Same ... + ENUM_X_DIRECTION iDir = iChild.dir; + bool isSameDir = dir == iDir; + if (!isSameDir) + { + continue; + } + + // + // Check Creation time Sequence ... + bool isFromPassed = last.from > iChild.from; + if (!isFromPassed) + { + continue; + } + + // + // Check Order Block Place ... + bool isPlacePassed = + isBullish + ? IsBoxBelow( + iChild, + last, + true // Ignore Inside ... + ) + : IsBoxAbove( + iChild, + last, + true // Ignore Inside ... + ); + if (!isPlacePassed) + { + continue; + } + + // + // Update Last OB ... + last = iChild; + AddRef( + iChild, + tmp // + ); + + // + } + + // + // Update Ordered Sorted Order Blocks ... + count = ArraySize(tmp); + if (IsValidSize(count)) + { + // + Copy( + tmp, + items // + ); + } +} + /** * Extract Order Flows Swing Points ... * diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 9bd7e6c9..a4b535d1 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -427,6 +427,9 @@ class XC121SMCCycleHelper : public XCBase conditions.period = GetPeriod(); conditions.time = TimeCurrent(); + // + // Consolidation Zones Implement here ... + // result = conditions.IsValid(); diff --git a/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 index 67e90fdb..eaeae2f9 100644 --- a/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 @@ -2403,7 +2403,7 @@ bool DetectX121SMCXSupDemOBSSignalSetup( if (isPriceInQuarterOne) { // - bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_WEAK; + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_REGULAR; } @@ -2455,7 +2455,7 @@ bool DetectX121SMCXSupDemOBSSignalSetup( { // bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_REGULAR; - bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_WEAK; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; } // @@ -2985,40 +2985,72 @@ bool DetectX121SMCXSupDemOBSSignalSetup( if (isLookingForBullish) { // - obsCount = ExtractUnActivatedZones( + Copy( analyseState.bullishOrderBlocks, obs // ); - hasOBs = IsValidSize(obsCount); + FilterZones( + insideDemandZone, + obs, + true, // Filter Direction ... + true, // Filter From ... + true, // Filter Price ... + true, // Ignore Out of Box ... + true, // Apply Sort ... + true // Ignore Inside ... + ); // - fvgsCount = ExtractUnActivatedZones( + Copy( analyseState.bullishFairValueGaps, fvgs // ); - hasFVGs = IsValidSize(fvgsCount); + FilterZones( + insideDemandZone, + fvgs, + true, // Filter Direction ... + true, // Filter From ... + true, // Filter Price ... + true, // Ignore Out of Box ... + true, // Apply Sort ... + true // Ignore Inside ... + ); } else { // - obsCount = ExtractUnActivatedZones( + Copy( analyseState.bearishOrderBlocks, obs // ); - hasOBs = IsValidSize(obsCount); + FilterZones( + insideSupplyZone, + obs, + true, // Filter Direction ... + true, // Filter From ... + true, // Filter Price ... + false, // Ignore Out of Box ... + true, // Apply Sort ... + true // Ignore Inside ... + ); // - fvgsCount = ExtractUnActivatedZones( + Copy( analyseState.bearishFairValueGaps, fvgs // ); - hasFVGs = IsValidSize(fvgsCount); + FilterZones( + insideSupplyZone, + fvgs, + true, // Filter Direction ... + true, // Filter From ... + true, // Filter Price ... + false, // Ignore Out of Box ... + true, // Apply Sort ... + true // Ignore Inside ... + ); } - // - OrderedSortZones(obs); - OrderedSortZones(fvgs); - // obsCount = ArraySize(obs); fvgsCount = ArraySize(fvgs); @@ -3026,6 +3058,42 @@ bool DetectX121SMCXSupDemOBSSignalSetup( // hasOBs = IsValidSize(obsCount); hasFVGs = IsValidSize(fvgsCount); + + // + if (hasOBs) + { + // + for (int i = 0; i < obsCount; i++) + { + // + obs[i].To(cTime); + + // + DrawX121SMCXSupDemOBSOrderBlock( + obs[i], + analyseCycleHelper.mPOIDrawer // + ); + } + } + + // + if (hasFVGs) + { + // + for (int i = 0; i < fvgsCount; i++) + { + // + fvgs[i].To(cTime); + + // + DrawX121SMCXSupDemOBSFairValueGap( + fvgs[i], + analyseCycleHelper.mPOIDrawer // + ); + } + } + + // if (hasOBs || hasFVGs) { @@ -3210,8 +3278,9 @@ bool DetectX121SMCXSupDemOBSSignalSetup( // result = hasInsideZone || - hasRejectedZone || - isPriceRejected; + hasRejectedZone; + // || + // isPriceRejected; if (!result) { //