From 121b3ffb5e3cbe7f7a899e6c993961929fb54813 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sat, 1 Nov 2025 20:42:24 +0330 Subject: [PATCH] last works on Strategy 1 of XFIMA Signaller ... --- Classes/x-saherelm.x-market.pattern.class.mq5 | 11 ++ Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 82 ++++++++++++ .../x-saherelm.xfima.signaller.class.mq5 | 117 +++++++++++++++++- 3 files changed, 209 insertions(+), 1 deletion(-) diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index df4bea0d..bf22010c 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -4244,6 +4244,7 @@ class XCMarketPatternDetector : public XCBase * @param forDir: ENUM_X_DIRECTION, Specified Zones Direction for Detecting ... * @param sortby: ENUM_X_SORT_BY, Specified Zones Sorting Factor ... * @param sortDir: ENUM_X_DIRECTION, Specified Zones Sorting Direction ... + * @param zonesRangeValidationFactor: double, Specified Zones Range Validation in Points ... * @param zonesLoopback: int, loop back for Zones Detection ... * @param zonesValidationLength: int, zones Validation Length ... * @param count: int, number of required Zones ... @@ -4262,6 +4263,7 @@ class XCMarketPatternDetector : public XCBase ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH, + double zonesRangeValidationFactor = 10, int zonesLoopback = 5, int zonesValidationLength = 5, int count = 0, @@ -4410,6 +4412,15 @@ class XCMarketPatternDetector : public XCBase RemoveBreakedZones(zones, true); } + // + // Validate Zones Range ... + if (zonesRangeValidationFactor > 0) { + // + double points = GetPoints(bar.symbol); + double minAllowedRange = points * zonesRangeValidationFactor; + ValidateZonesRange(zones, minAllowedRange); + } + // // Apply Sorting ... Sort(zones, sortBy, sortDir); diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index b352d0d8..128d9307 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -5659,6 +5659,14 @@ bool HasInside( return result; } +/** + * Check Specified ZOne is Affected by Specified Bar or not ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param zone: XBoxZone, reference to Specified Zone ... + * + * @return ( bool ) + */ bool IsZoneAffected( XOHCL &bar, XBoxZone &zone // @@ -6167,6 +6175,14 @@ int GetTesterBars( return result; } +/** + * Check Specified Zone is Breaked or not ... + * + * @param zone: XBoxZone, reference to Specified Zone ... + * @param priceType: ENUM_X_PRICE, Specified Price Type for Zone Break Detection ... + * + * @return ( bool ) + */ bool IsBreaked( XBoxZone &zone, ENUM_X_PRICE priceType = X_PRICE_CLOSE // @@ -6225,6 +6241,72 @@ bool IsBreaked( return result; } +/** + * Validate Zones Range ... + * + * @param source: XBoxZone, collection reference to Validate ... + * @param minAllowedRange: double, min allowed range to Validate ... + * + * @return ( int ) + */ +int ValidateZonesRange( + XBoxZone &source[], + double minAllowedRange // +) +{ + // + int result = 0; + + // + // Validate ... + bool has = HasChild(source) && + minAllowedRange > 0; + if (!has) + { + return result; + } + + // + XBoxZone iTMP; + XBoxZone tmps[]; + Copy(source, tmps); + XClean(source); + while (HasChild(tmps)) + { + // + iTMP.Clean(); + iTMP = tmps[0]; + ArrayRemove(tmps, 0, 1); + + // + // Check Range Validation ... + has = iTMP.GetRange() > minAllowedRange; + if (has) + { + AddIfNotExists(iTMP, source); + } + } + + // + result = ArraySize(source); + + // + // Cleanup ... + XClean(tmps); + iTMP.Clean(); + + // + return result; +} + +/** + * Remove Breaked Zones ... + * + * @param source: XBoxZone, collection reference to Remove Breaked Zones ... + * @param priceType: ENUM_X_PRICE, Specified Price type of Break Detection ... + * + * @return ( int ) + */ int RemoveBreakedZones( XBoxZone &source[], ENUM_X_PRICE priceType = X_PRICE_CLOSE // diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index fbd1f032..19357681 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -1062,7 +1062,9 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // // Validator Flags ... + bool validateByZones = true; bool validateByXFIMARejected = true; + bool validateByCyclesMATresnding = true; // // Define Requirements ... @@ -1071,6 +1073,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XOHCL pBar; XOHCL p2Bar; XOHCL p3Bar; + XBoxZone zones[]; double rejecteds[]; bool isBullish = false; bool isBearish = false; @@ -1206,8 +1209,115 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // rejectedBar.Clean(); + + // + // Reset Flags ... + if (!result) + { + // + zone.Clean(); + result = false; + isBullish = false; + isBearish = false; + dir = X_DIRECTION_NONE; + } } + // + // Validate Rejection by Cycleas MA Trending ... + if (result && validateByCyclesMATresnding) + { + // + int barIDX = pBar.Index(); + + // + bool isCyclesMABulliah = + fimaParser.IsHCMABullish(barIDX) && + fimaParser.IsHCMAOverLast(barIDX); + + // + bool isCyclesMABearish = + fimaParser.IsHCMABearish(barIDX) && + fimaParser.IsHCMAUnderLast(barIDX); + + // + isBullish = + isBullish && + isCyclesMABulliah; + + // + isBearish = + isBearish && + isCyclesMABearish; + + // + result = isBullish || isBearish; + } + + // + // Detect a Zone ... + // Validate by Has a Zone (FVG, Support, Resistance) ... + if (result && validateByZones) + { + // + int zonesCount = poiDetector.DetectZones( + bar, + zones, + true, // Validated Zones ... + false, // Contains Order Block ... + true, // Contains Fair Value Gaps ... + true, // Contains Supports ... + true, // Contains Resistances ... + X_DIRECTION_ALL, // For All Directions ... + X_SORT_BY_DATE, // Sort by Date ... + X_DIRECTION_BEARISH, // Sorting Direction ... + 10, // Zones Validation Points Factor ... + 5, // Zones Loopback ... + 3, // Zones Validation ... + 0, // All Zones ... + 50 // Loopback Length ... + ); + UpdateToTime(zones, bar.time); + + // + result = result && IsValidSize(zonesCount); + if (result) + { + // + XBoxZone tmpZones[]; + int bullishCount = ExtractByDirection( + tmpZones, + zones, + X_DIRECTION_BULLISH // + ); + int bearishCount = ExtractByDirection( + tmpZones, + zones, + X_DIRECTION_BEARISH // + ); + + // + result = + result && + IsValidSize(bullishCount) && + IsValidSize(bearishCount); + } + + // + // Reset Flags ... + if (!result) + { + // + zone.Clean(); + result = false; + isBullish = false; + isBearish = false; + dir = X_DIRECTION_NONE; + } + } + + // + // TODO: Remove this and Put inside Draws Part ... if (result) { // @@ -1250,7 +1360,11 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } // - DebugBreak(); + // Draw Detected Zones ... + if (HasChild(zones)) + { + poiDrawer.DrawZones(zones, iConfig); + } } // @@ -1373,6 +1487,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); + XClean(zones); XClean(rejecteds); pBarPatterns.Clean(); p2BarPatterns.Clean();