diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index 840cda69..02b048e9 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -2227,6 +2227,450 @@ class XCMarketPatternDetector : public XCBase return result; } + // + // Complex ... + + /** + * Check Double Pinned Bar ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dir: ENUM_X_DIRECTION, reference to holds Pattern Direction ... + * @param shadowApprovedMultiplier: double, Shadow Size Approve Multiplier ... + * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... + * @param forceDirection: bool, Apply Force Bar Type ... + * @param loopback: int, Max Allowed Detecting Loopback lenght ... + * + * @return ( bool ) + */ + bool IsDoublePinned( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + double shadowApprovedMultiplier = 3, + double minimumPinBarRangeMultiplier = 4, + bool forceDirection = false, + int loopback = 5 // + ) + { + // + bool result = false; + + // + // Prepare ... + CleanDirection(dir); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + shadowApprovedMultiplier = NormalizeDouble(shadowApprovedMultiplier, 2, 5); + minimumPinBarRangeMultiplier = NormalizeDouble(minimumPinBarRangeMultiplier, 2, 100); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Do ... + + // + // Current Bar Must be a Pinned Bar ... + result = IsPinnedBar( + bar, + dir, + shadowApprovedMultiplier, + minimumPinBarRangeMultiplier, + forceDirection // + ); + if (!result) + { + // + CleanDirection(dir); + + // + return result; + } + + // + XOHCL iBar; + ENUM_X_DIRECTION iDir; + int start = bar.Index() + 1; + int end = start + loopback; + for (int i = start; i < end; i++) + { + // + iBar.Clean(); + result = bar.BarAt(i, iBar); + result = result && IsPinnedBar( + iBar, + iDir, + shadowApprovedMultiplier, + minimumPinBarRangeMultiplier, + forceDirection // + ); + result = result && + iDir == dir; + if (result) + { + break; + } + } + + // + // Cleanup ... + if (!result) + { + CleanDirection(dir); + } + iBar.Clean(); + CleanDirection(iDir); + + // + return result; + } + + /** + * Check Double Engulfed Bar ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dir: ENUM_X_DIRECTION, reference to holds Pattern Direction ... + * @param loopback: int, Max Allowed Detecting Loopback lenght ... + * + * @return ( bool ) + */ + bool IsDoubleEngulfed( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + int loopback = 5 // + ) + { + // + bool result = false; + + // + // Prepare ... + CleanDirection(dir); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Do ... + + // + // Current Bar Must be a Pinned Bar ... + result = IsEngulfedBar( + bar, + dir // + ); + if (!result) + { + // + CleanDirection(dir); + + // + return result; + } + + // + XOHCL iBar; + ENUM_X_DIRECTION iDir; + int start = bar.Index() + 1; + int end = start + loopback; + for (int i = start; i < end; i++) + { + // + iBar.Clean(); + result = bar.BarAt(i, iBar); + result = result && IsEngulfedBar( + iBar, + iDir // + ); + result = result && + iDir == dir; + if (result) + { + break; + } + } + + // + // Cleanup ... + if (!result) + { + CleanDirection(dir); + } + iBar.Clean(); + CleanDirection(iDir); + + // + return result; + } + + /** + * Check Double Momentum Bar ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dir: ENUM_X_DIRECTION, reference to holds Pattern Direction ... + * @param requiredBars: int, bar range for approve Momentum ... + * @param approvedMultiplier: double, a Multipler for approve Momentum ... + * @param loopback: int, Max Allowed Detecting Loopback lenght ... + * + * @return ( bool ) + */ + bool IsDoubleMomentum( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + int requiredBars = 3, + double approvedMultiplier = 2, + int loopback = 5 // + ) + { + // + bool result = false; + + // + // Prepare ... + CleanDirection(dir); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + requiredBars = NormalizeInt(requiredBars, 3, 10); + approvedMultiplier = NormalizeDouble(approvedMultiplier, 2, 5); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Do ... + + // + // Current Bar Must be a Pinned Bar ... + result = IsMomentumBar( + bar, + dir, + requiredBars, + approvedMultiplier // + ); + if (!result) + { + // + CleanDirection(dir); + + // + return result; + } + + // + XOHCL iBar; + ENUM_X_DIRECTION iDir; + int start = bar.Index() + 1; + int end = start + loopback; + for (int i = start; i < end; i++) + { + // + iBar.Clean(); + result = bar.BarAt(i, iBar); + result = result && IsMomentumBar( + iBar, + iDir, + requiredBars, + approvedMultiplier // + ); + result = result && + iDir == dir; + if (result) + { + break; + } + } + + // + // Cleanup ... + if (!result) + { + CleanDirection(dir); + } + iBar.Clean(); + CleanDirection(iDir); + + // + return result; + } + + /** + * Check Has Double Patterns ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dir: ENUM_X_DIRECTION, reference to holds Specified Patterns ... + * @param barPatterns: XPatternAnalysis, reference to Provides Bar's Pattern Analysis ... + * @param pBarPatterns: XPatternAnalysis, reference to Provides Previous Bar's Pattern Analysis ... + * @param allowedPatterns: ENUM_X_BAR_PATTERN, collection to Provide Allowed Bar Patterns for Detection ... + * @param config: XPatternAnalysisConfig, Provides Patterns Detection Config ... + * @param loopback: int, Max Allowed Loopback for Detection ... + * @param forDir: ENUM_X_DIRECTION, Specified Patterns Detection Direction ... + * + * @return ( bool ) + */ + bool HasDoublePatterns( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + XPatternAnalysis &barPatterns, + XPatternAnalysis &pBarPatterns, + ENUM_X_BAR_PATTERN &allowedPatterns[], + XPatternAnalysisConfig &config, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // + ) + { + // + bool result = false; + + // + // Prepare ... + barPatterns.Clean(); + CleanDirection(dir); + pBarPatterns.Clean(); + XPatternAnalysisConfig iConfig = config; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 2); + + // + // Validate ... + result = bar.IsValid() && + HasChild(allowedPatterns); + if (!result) + { + return result; + } + + // + // Prepare Config ... + iConfig.CleanPatterns(); + if (HasChild(allowedPatterns)) + { + // + for (int i = 0; i < ArraySize(allowedPatterns); i++) + { + iConfig.AddPattern(allowedPatterns[i]); + } + } + + // + // Detect Bar Patterns ... + result = AnalyseBarPatterns(bar, barPatterns, config); + if (!result) + { + // + CleanDirection(dir); + barPatterns.Clean(); + pBarPatterns.Clean(); + + // + return result; + } + + // + // Check Direction ... + int bullishCount = barPatterns.Count(X_DIRECTION_BULLISH); + int bearishCount = barPatterns.Count(X_DIRECTION_BEARISH); + dir = + bullishCount > bearishCount + ? X_DIRECTION_BULLISH + : bearishCount > bullishCount + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(dir); + + // + // Check for Dir ... + if (HasDirection(forDir)) + { + // + result = + result && + dir == forDir; + } + + // + // Looping Back ... + if (result) + { + // + XOHCL iBar; + ENUM_X_DIRECTION iDir; + int start = bar.Index() + 1; + int end = start + loopback; + for (int i = start; i < end; i++) + { + // + iBar.Clean(); + pBarPatterns.Clean(); + result = bar.BarAt(i, iBar); + result = result && + AnalyseBarPatterns(iBar, pBarPatterns, iConfig); + if (!result) + { + continue; + } + + // + bullishCount = pBarPatterns.Count(X_DIRECTION_BULLISH); + bearishCount = pBarPatterns.Count(X_DIRECTION_BEARISH); + iDir = + bullishCount > bearishCount + ? X_DIRECTION_BULLISH + : bearishCount > bullishCount + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(iDir); + result = result && + dir == iDir; + if (result) + { + break; + } + } + + // + iBar.Clean(); + CleanDirection(iDir); + } + + // + // Cleanup ... + if (!result) + { + // + CleanDirection(dir); + barPatterns.Clean(); + pBarPatterns.Clean(); + } + iConfig.Clean(); + + // + return result; + } + // // Trending ... @@ -3492,6 +3936,17 @@ class XCMarketPatternDetector : public XCBase return result; } + /** + * Collect Required Order Blocks ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dest: XBoxZone, collection reference to holds detected zones ... + * @param zonesLoopback: int, zones detection loopback ... + * @param maxRequiredZone: int, number of required zones ... + * @param loopback: int, max allowed loopback lenght for zone Detection ... + * + * @return ( int ) + */ int CollectOBs( XOHCL &bar, XBoxZone &dest[], @@ -3569,6 +4024,17 @@ class XCMarketPatternDetector : public XCBase return result; } + /** + * Collect Required Fair Value Gaps ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dest: XBoxZone, collection reference to holds detected zones ... + * @param zonesLoopback: int, zones detection loopback ... + * @param maxRequiredZone: int, number of required zones ... + * @param loopback: int, max allowed loopback lenght for zone Detection ... + * + * @return ( int ) + */ int CollectFVGs( XOHCL &bar, XBoxZone &dest[], @@ -3646,6 +4112,18 @@ class XCMarketPatternDetector : public XCBase return result; } + /** + * Collect Required Support and Resistance Zones ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param dest: XBoxZone, collection reference to holds detected zones ... + * @param zonesLoopback: int, zones detection loopback ... + * @param zonesValidationLength: int, zones validation length ... + * @param maxRequiredZone: int, number of required zones ... + * @param loopback: int, max allowed loopback lenght for zone Detection ... + * + * @return ( int ) + */ int CollectZones( XOHCL &bar, XBoxZone &dest[], @@ -3753,6 +4231,220 @@ class XCMarketPatternDetector : public XCBase return result; } + /** + * Detect and Collect Required Zones ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param zones: XBoxZone, collection reference to holds detected zones ... + * @param validateZones: bool, Specified to Detect only Valid Zones ... + * @param containsOBs: bool, Flag to use Order Block Zones ... + * @param containsFVGs: bool, Flag to use Fair Value Gap Zones ... + * @param containsSupports: bool, Flag to use Support Zones ... + * @param containsResistancess: bool, Flag to use Resistance Zones ... + * @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 zonesLoopback: int, loop back for Zones Detection ... + * @param zonesValidationLength: int, zones Validation Length ... + * @param count: int, number of required Zones ... + * @param loopback: int, max allowed looping back lenght for detection ... + * + * @return ( int ) + */ + int DetectZones( + XOHCL &bar, + XBoxZone &zones[], + bool validateZones = true, + bool removeUsedZones = true, + bool containsOBs = true, + bool containsFVGs = true, + bool containsSupports = true, + bool containsResistancess = true, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, + ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH, + int zonesLoopback = 5, + int zonesValidationLength = 5, + int count = 0, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(zones); + + // + // Normalize ... + count = NormalizeInt(count, 0); + loopback = NormalizeInt(loopback, 50); + zonesLoopback = NormalizeInt(zonesLoopback, 2); + zonesValidationLength = NormalizeInt(zonesValidationLength, 3); + + // + // Validate ... + bool has = bar.IsValid() && + IsXValid(sortDir) && + IsXValid(sortBy) && + (containsOBs || containsFVGs || containsSupports || containsResistancess); + if (!has) + { + return result; + } + + // + XOHCL iBar; + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone tmpZone; + ENUM_X_DIRECTION tmpDir; + int idx = bar.Index(); + while (idx < bar.Index() + loopback) + { + // + idx++; + + // + iBar.Clean(); + tmpBar.Clean(); + tmpZone.Clean(); + tmpPivot.Clean(); + + // + has = bar.BarAt(idx, iBar); + if (!has) + { + continue; + } + + // + // Collecting Zones ... + + // + // Support ... + if (containsSupports) + { + // + if (!HasDirection(forDir) || IsXBullish(forDir)) + { + // + has = HasSupport(iBar, tmpBar, zonesValidationLength, zonesLoopback); + if (has) + { + // + has = ToBox(tmpBar, tmpZone, X_DIRECTION_BULLISH, X_BAR_PATTERN_SUPPORT); + if (has) + { + AddIfNotExists(tmpZone, zones); + } + } + } + } + + // + // Resistance ... + if (containsResistancess) + { + // + if (!HasDirection(forDir) || IsXBearish(forDir)) + { + // + has = HasResistance(iBar, tmpBar, zonesValidationLength, zonesLoopback); + if (has) + { + // + has = ToBox(tmpBar, tmpZone, X_DIRECTION_BEARISH, X_BAR_PATTERN_RESISTANCE); + if (has) + { + AddIfNotExists(tmpZone, zones); + } + } + } + } + + // + // Order Block ... + if (containsOBs) + { + // + has = HasOB(iBar, tmpDir, tmpZone, zonesLoopback); + if (has && (!HasDirection(forDir) || tmpDir == forDir)) + { + AddIfNotExists(tmpZone, zones); + } + } + + // + // Fair Value Gaps ... + if (containsFVGs) + { + // + has = HasFVG(iBar, tmpDir, tmpZone, zonesLoopback); + if (has && (!HasDirection(forDir) || tmpDir == forDir)) + { + AddIfNotExists(tmpZone, zones); + } + } + } + + // + // Validate Zones Exists ... + result = ArraySize(zones); + has = IsValidSize(result); + if (!has) + { + return result; + } + + // + // Update Zones Time ... + UpdateToTime(zones, bar.time); + + // + // Validate Zones ... + if (validateZones) + { + // + // Apply Zones Validation Here ... + RemoveBreakedZones(zones, true); + } + + // + // Remove Filled Zones ... + if (removeUsedZones) + { + // + // Remove all Filled Zones ... + RemoveFilledZones(zones); + } + + // + // Apply Sorting ... + Sort(zones, sortBy, sortDir); + + // + // Validate Zones Count ... + if (count > 0) + { + CleanupArray(zones, count); + } + + // + result = ArraySize(zones); + + // + // Cleanup ... + iBar.Clean(); + tmpBar.Clean(); + tmpZone.Clean(); + tmpPivot.Clean(); + + // + return result; + } + /** * Filter Zones ... * @@ -3842,100 +4534,6 @@ class XCMarketPatternDetector : public XCBase return result; } - // - // Trigger Bar ... - bool IsTriggerBar( - XOHCL &bar, - ENUM_X_DIRECTION forDir, - ENUM_TIMEFRAMES forPeriod = PERIOD_M1 // - ) - { - // - // Trigger Bars Detected in Specified Perido ... - - // - bool result = false; - - // - // Validate ... - result = bar.IsValid() && - IsXValid(forPeriod) && - HasDirection(forDir); - if (!result) - { - return result; - } - - // - // Do ... - - // - // Initialized Specified Bar in Specified Time Frame ... - XOHCL periodBar; - int index = GetBarIndex( - bar.symbol, - forPeriod, - TimeCurrent() // - ); - result = periodBar.Init(bar.symbol, forPeriod, index); - if (!result) - { - return result; - } - - // - // Detect Pattern ... - XPatternAnalysisConfig iConfig; - iConfig.Default(); - iConfig.CleanPatterns(); - iConfig.AddPattern(X_BAR_PATTERN_LOW); - iConfig.AddPattern(X_BAR_PATTERN_HIGH); - iConfig.AddPattern(X_BAR_PATTERN_PINNED); - iConfig.AddPattern(X_BAR_PATTERN_ENGULFED); - iConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY); - - // - XPatternAnalysis periodBarAnalysis; - result = AnalyseBarPatterns(periodBar, periodBarAnalysis, iConfig); - - // - bool isBullish = - result && - IsXBullish(forDir) && - ( - // - periodBarAnalysis.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) || - periodBarAnalysis.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) || - periodBarAnalysis.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) - // - ); - - // - bool isBearish = - result && - IsXBearish(forDir) && - ( - // - periodBarAnalysis.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) || - periodBarAnalysis.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) || - periodBarAnalysis.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) - // - ); - - // - // Summarize Result ... - result = isBullish || isBearish; - - // - // Cleanup ... - iConfig.Clean(); - periodBar.Clean(); - periodBarAnalysis.Clean(); - - // - return result; - } - // // Protected ... protected: diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index ff74fb2f..17929094 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -5108,6 +5108,116 @@ int RemoveBreakedZones( return result; } +/** + * Remove Filled Zones ... + * + * @param source: XBoxZone, collection reference to Provide Data Source ... + * @param zoneRangeFilledFactor: double, Filling Factor ... + * + * @return ( int ) + */ +int RemoveFilledZones( + XBoxZone &source[], + double zoneRangeFilledFactor = 0.8 // +) +{ + // + int result = 0; + + // + // Validate ... + bool has = HasChild(source); + if (!has) + { + return result; + } + + // + XBoxZone iTMP; + XBoxZone tmp[]; + Copy(source, tmp); + XClean(source); + while (HasChild(tmp)) + { + // + iTMP.Clean(); + iTMP = tmp[0]; + ArrayRemove(tmp, 0, 1); + + // + has = IsFilled(iTMP, zoneRangeFilledFactor); + if (!has) + { + AddIfNotExists(iTMP, source); + } + } + + // + result = ArraySize(source); + + // + return result; +} + +/** + * Check a Zone is Filled or Not ... + * + * @param zone: XBoxZone, reference to Specified Zone ... + * @param zoneRangeFilledFactor: double, Filling Factor ... + * + * @return ( bool ) + */ +bool IsFilled( + XBoxZone &zone, + double zoneRangeFilledFactor = 0.8 // +) +{ + // + bool result = false; + + // + // Validate ... + result = zone.IsValid() && + zoneRangeFilledFactor > 0 && + zoneRangeFilledFactor < 1; + if (!result) + { + // + result = true; + return result; + } + + // + XOHCL iBar; + int toIDX = zone.ToIndex(); + int fromIDX = zone.FromIndex(); + double zoneRangeFactor = zone.GetRange() / 100; + double useValue = zone.lower + (zoneRangeFactor * zoneRangeFilledFactor); + for (int i = toIDX; i < fromIDX; i++) + { + // + // Initialize Indexed Bar ... + iBar.Clean(); + result = iBar.Init(zone.symbol, zone.period, i); + result = + result && + (zone.IsBullish() + ? iBar.GetPrice(X_PRICE_LOW) <= useValue + : iBar.GetPrice(X_PRICE_HIGH) >= useValue); + if (result) + { + break; + } + } + + // + // Cleanup ... + iBar.Clean(); + + // + return result; +} + /** * Check Specified Zone is Breaked by Specified Bar or not ... * diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 0e53a36b..7034401c 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -318,6 +318,40 @@ int GetAllBarPatters(ENUM_X_BAR_PATTERN &dest[]) return ArraySize(dest); } +/** + * Fill Required Candlestick Patters ... + * + * @param dest: ENUM_X_BAR_PATTERN, collection reference to Fill ... + * + * @return ( int ) + */ +int GetCandlestickPatterns(ENUM_X_BAR_PATTERN &dest[]) +{ + // + int result = 0; + + // + // Prepare ... + XClean(dest); + + // + Add(X_BAR_PATTERN_STAR, dest); + Add(X_BAR_PATTERN_FLAG, dest); + Add(X_BAR_PATTERN_PINNED, dest); + Add(X_BAR_PATTERN_RISING, dest); + Add(X_BAR_PATTERN_MOMENTUM, dest); + Add(X_BAR_PATTERN_ENGULFED, dest); + Add(X_BAR_PATTERN_PIERCING, dest); + Add(X_BAR_PATTERN_SIGNALKEY, dest); + Add(X_BAR_PATTERN_TRUE_GAPED, dest); + + // + result = ArraySize(dest); + + // + return result; +} + // // Structures ... diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index 875d3fe7..6283fb86 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -1925,11 +1925,13 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XOHCL tmpBar; XPivot tmpPivot; XBoxZone atrBox; + XBoxZone zones[]; XBoxZone tmpZone; XBoxZone scPVZone; XBoxZone mcPVZone; XBoxZone lcPVZone; XBoxZone hcPVZone; + XBoxZone tmpZones[]; XBoxZone pinBarZone; XBoxZone supports[]; XBoxZone resistances[]; @@ -2151,6 +2153,65 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } } + // + // Collecting Zones ... + + // + int collectedZonesCount = poiDetector.DetectZones( + bar, + zones, + true, // Validated Zones ... + false, // Remove Used Zones ... + false, // Contains Order Blocks ... + true, // Contains Fair Value Gaps ... + true, // Contains Supports ... + true, // Contains Resistances ... + X_DIRECTION_NONE, // For Dir (Contains All Direction Zones) ... + X_SORT_BY_DATE, // Sort By ... + X_DIRECTION_BEARISH, // Sort Dir ... + 3, // Zones Loopback ... + 3, // Zones Validation Length ... + 0, // Count (All Zones) ... + 100 // Loop back for Detection ... + ); + bool hasCollectedZones = IsValidSize(collectedZonesCount) && + collectedZonesCount > 1; + int affectedZonesCount = 0; + bool hasAffectedZone = false; + int collectedZonesBullishCount = 0; + int collectedZonesBearishCount = 0; + bool hasBullishAffectedZone = false; + bool hasBearishAffectedZone = false; + bool hasBullishCollectedZones = false; + bool hasBearishCollectedZones = false; + if (hasCollectedZones) + { + // + // Bullish ... + XClean(tmpZones); + collectedZonesBullishCount = ExtractByDirection(tmpZones, zones, X_DIRECTION_BULLISH); + hasBullishCollectedZones = IsValidSize(collectedZonesBullishCount); + + // + // Bearish ... + XClean(tmpZones); + collectedZonesBearishCount = ExtractByDirection(tmpZones, zones, X_DIRECTION_BEARISH); + hasBearishCollectedZones = IsValidSize(collectedZonesBearishCount); + + // + // Extract Affected Zones ... + XClean(tmpZones); + int affectedZonesCount = ExtractAffectedZones(p2Bar, zones, tmpZones); + int idx = GetYoungest(tmpZones); + if (IsValidIndex(idx)) + { + affectedZone = tmpZones[idx]; + } + hasAffectedZone = affectedZone.IsValid(); + hasBullishAffectedZone = hasAffectedZone && affectedZone.IsBullish(); + hasBearishAffectedZone = hasAffectedZone && affectedZone.IsBearish(); + } + // // Reading Cycle PVS ... bool hasSCPV = poiDetector.GetSCZone(pBar, scPVZone); @@ -2230,10 +2291,32 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller bool isP2BarPinnedBearish = isP2BarIsPinBar && IsXBearish(tmpDir); // + // Checking ATR Box ... bool hasATRBox = fimaParser.GetATRBox( atrBox, bar.Index() // ); + bool hasATRBoxBullish = hasATRBox && atrBox.IsBullish(); + bool hasATRBoxBearish = hasATRBox && atrBox.IsBearish(); + + // + // Checking Double Patterns ... + ENUM_X_DIRECTION iDBDir; + XPatternAnalysis iPatterns; + XPatternAnalysis iPPatterns; + ENUM_X_BAR_PATTERN doublePatterns[]; + GetCandlestickPatterns(doublePatterns); + bool hasDoublePatterns = poiDetector.HasDoublePatterns( + pBar, + iDBDir, + iPatterns, + iPPatterns, + doublePatterns, + iPatternsConfig, + 5 // + ); + bool hasBullishDoublePatterns = hasDoublePatterns && IsXBullish(iDBDir); + bool hasBearishDoublePatterns = hasDoublePatterns && IsXBearish(iDBDir); // isBullish = @@ -2241,10 +2324,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller hasSupport && hasResistance && isCyclesBullish && + hasATRBoxBullish && isCyclePVBullish && isP2BarPinnedBullish && + hasBullishAffectedZone && isPBarHasBullishPatterns && + hasBullishCollectedZones && isP2BarHasBullishPatterns && + collectedZonesBullishCount > collectedZonesBearishCount && true // ; @@ -2255,10 +2342,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller hasSupport && hasResistance && isCyclesBearish && + hasATRBoxBearish && isCyclePVBearish && isP2BarPinnedBearish && + hasBearishAffectedZone && isPBarHasBearishPatterns && + hasBearishCollectedZones && isP2BarHasBearishPatterns && + collectedZonesBearishCount > collectedZonesBullishCount && true // ; @@ -2314,9 +2405,11 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // poiDrawer.DrawZone(pinBarZone, iConfig); + poiDrawer.DrawZone(affectedZone, iConfig); poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig); // + // poiDrawer.DrawZones(zones, iConfig); poiDrawer.DrawZones(supports, iConfig); poiDrawer.DrawZones(resistances, iConfig); @@ -2326,6 +2419,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller poiDrawer.DrawZone(atrBox, iConfig); } + // + if (hasDoublePatterns) + { + // + poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig); + poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig); + } + // iConfig.Clean(); iPatternsConfig.Clean(); @@ -2358,9 +2459,11 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); + XClean(zones); tmpBar.Clean(); tmpZone.Clean(); XClean(supports); + XClean(tmpZones); scPVZone.Clean(); mcPVZone.Clean(); lcPVZone.Clean(); diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 index 9d46f098..5600e073 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -488,6 +488,14 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector return result; } + /** + * Detect XPV Zone ... + * + * @param zone: XBoxZone, reference to Holds detected Zone ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ bool DetectXPVZone( XBoxZone &zone, int barIndex = 0 // @@ -1600,6 +1608,15 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector return result; } + /** + * Collect Specified ZOnes Boundary Min / Max Values ... + * + * @param uppers: XPivot, collection reference to holds Peaks of Zone's Boundary ... + * @param lowers: XPivot, collection reference to holds Vales of Zone's Boundary ... + * @param zone: XBoxZone, reference to Provide Specified Zone for Boundary Detection ... + * + * @return ( int ) + */ int CollectZonesBoundary( XPivot &uppers[], XPivot &lowers[],