From e6165f44f2a5bd8e64a450187c70c0e72e87dab7 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 6 Jan 2026 11:48:16 +0330 Subject: [PATCH] last ... --- Documents/BKP/X121XKI/tmp.1.bkp.mq5 | 550 ++++++++++++++ Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 696 +++++++++++------- .../x-saherelm.x121.xki.signaller.class.mq5 | 368 ++------- ...saherelm.x121.xki.x-poi.detector.class.mq5 | 260 ++++++- 4 files changed, 1308 insertions(+), 566 deletions(-) diff --git a/Documents/BKP/X121XKI/tmp.1.bkp.mq5 b/Documents/BKP/X121XKI/tmp.1.bkp.mq5 index d6799803..d33b68cb 100644 --- a/Documents/BKP/X121XKI/tmp.1.bkp.mq5 +++ b/Documents/BKP/X121XKI/tmp.1.bkp.mq5 @@ -533,3 +533,553 @@ // return result; } + + /** + * Check Bar Has Signal Based on Strategy 1 ... + * POI ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * + * @return ( bool ) + */ + bool Strategy1HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int scoreBullish = 0; + int scoreBearish = 0; + bool isBullish = false; + bool isBearish = false; + int barIndex = bar.Index() + 1; + + // + // Initialize Indexed Bar ... + XOHCL iBar; + result = iBar.Init(bar.symbol, bar.period, barIndex); + if (!result) + { + return result; + } + + // #region Swings/OrderFlow ... + // + // Swings ... + XBoxZone swingLow; + XBoxZone swingHigh; + bool hasSwings = poiDetector.DetectRecentSwings( + swingHigh, + swingLow, + barIndex // + ); + + // + // Order Flow ... + + // + XBoxZone bullishOrderFlow[]; + result = poiDetector.HasOrderFlow(bullishOrderFlow, barIndex, 4, X_DIRECTION_BULLISH, 15); + + // + XBoxZone bearishOrderFlow[]; + result = poiDetector.HasOrderFlow(bearishOrderFlow, barIndex, 4, X_DIRECTION_BEARISH, 15); + // #endregion + + // #region Reading Conditions and Scoring ... + // + // ATR ... + bool isATRUp = kiParser.IsVolatilityHigh(barIndex) || + kiParser.IsVolatilitySwitchdToHigh(barIndex); + + // #region KI ... + // + bool isKIReadyForBullish = ((kiParser.IsKIFastBearish(barIndex) || + (kiParser.IsKIFastBullish(barIndex) && + iBar.IsRejected(kiHelper.GetKIFast(barIndex), X_DIRECTION_BULLISH))) && + kiParser.IsKISlowBullish(barIndex)); + + // + bool isKIReadyForBearish = ((kiParser.IsKIFastBullish(barIndex) || + (kiParser.IsKIFastBearish(barIndex) && + iBar.IsRejected(kiHelper.GetKIFast(barIndex), X_DIRECTION_BEARISH))) && + kiParser.IsKISlowBearish(barIndex)); + + // + bool isKIBandBullish = (kiHelper.GetKIUpper(barIndex) > kiHelper.GetKIUpper(barIndex + 1) || + kiHelper.GetKILower(barIndex) > kiHelper.GetKILower(barIndex + 1)); + + // + bool isKIBandBearish = (kiHelper.GetKIUpper(barIndex) < kiHelper.GetKIUpper(barIndex + 1) || + kiHelper.GetKILower(barIndex) < kiHelper.GetKILower(barIndex + 1)); + + // + bool isKIBullish = (kiParser.IsKIFastBullish(barIndex) || + kiParser.IsKIFastSwitchedToBullish(barIndex)) && + (kiParser.IsKISlowBullish(barIndex) || + kiParser.IsKISlowSwitchedToBullish(barIndex)); + if (isKIBullish) + { + scoreBullish++; + } + + // + bool isKIBearish = (kiParser.IsKIFastBearish(barIndex) || + kiParser.IsKIFastSwitchedToBearish(barIndex)) && + (kiParser.IsKISlowBearish(barIndex) || + kiParser.IsKISlowSwitchedToBearish(barIndex)); + if (isKIBearish) + { + scoreBearish++; + } + // #endregion + + // #region KI Wave ... + // + bool isKIWaveBullish = kiParser.IsKIWaveBullish(barIndex) || + kiParser.IsKIWaveSwitchedToBullish(barIndex); + if (isKIWaveBullish) + { + scoreBullish++; + } + + // + bool isKIWaveBearish = kiParser.IsKIWaveBearish(barIndex) || + kiParser.IsKIWaveSwitchedToBearish(barIndex); + if (isKIWaveBearish) + { + scoreBearish++; + } + // #endregion + + // #region MA ... + // + bool isMaBullish = kiParser.IsMACrossoverBullish(barIndex) || + kiParser.IsMACrossoverSwitchedToBullish(barIndex); + if (isMaBullish) + { + scoreBullish++; + } + + // + bool isMaBearish = kiParser.IsMACrossoverBearish(barIndex) || + kiParser.IsMACrossoverSwitchedToBearish(barIndex); + if (isMaBearish) + { + scoreBearish++; + } + // #endregion + + // #region LowerTF Candlstick ... + // + bool isLowerTFBullish = IsTFBullishPattern(barIndex, PERIOD_M5); + if (isLowerTFBullish) + { + scoreBullish++; + } + + // + bool isLowerTFBearish = IsTFBearishPattern(barIndex, PERIOD_M5); + if (isLowerTFBearish) + { + scoreBearish++; + } + // #endregion + + // #region Candlestick ... + // + bool isCandlestickBullish = poiDetector.HasCandlestickDirection( + iBar, + X_DIRECTION_BULLISH // + ); + if (isCandlestickBullish) + { + scoreBullish++; + } + + // + bool isCandlestickBearish = poiDetector.HasCandlestickDirection( + iBar, + X_DIRECTION_BEARISH // + ); + if (isCandlestickBearish) + { + scoreBearish++; + } + // #endregion + // #endregion + + // #region Summarize Directional Conditions ... + // + isBullish = + isATRUp && + isLowerTFBullish && + isKIReadyForBullish && + isCandlestickBullish && + scoreBullish >= 2 && + (isKIBullish || + isMaBullish || + isKIWaveBullish || + isKIBandBullish); + + // + isBearish = + isATRUp && + isLowerTFBearish && + isKIReadyForBearish && + isCandlestickBearish && + scoreBearish >= 2 && + (isKIBearish || + isMaBearish || + isKIWaveBearish || + isKIBandBearish); + // #endregion + + // + // Validate Conditions ... + result = isBullish || isBearish; + if (!result) + { + // + iBar.Clean(); + + // + return result; + } + + // + // Select Operational Zone ... + ENUM_X_DIRECTION patternsDir[]; + ENUM_X_BAR_PATTERN patterns[]; + + // + // GetAllBarPatters(patterns, patternsDir); + + // + // XAUUSD ... + + // + // FVG ... + Add(X_BAR_PATTERN_FVG, patterns); + Add(X_DIRECTION_NONE, patternsDir); + + // + // Piercing ... + Add(X_BAR_PATTERN_PIERCING, patterns); + Add(X_DIRECTION_NONE, patternsDir); + + // + // EURUSD ... + + // + // Add(X_BAR_PATTERN_STAR, patterns); + // Add(X_DIRECTION_NONE, patternsDir); + + // // + // Add(X_BAR_PATTERN_SUPPORT, patterns); + // Add(X_DIRECTION_NONE, patternsDir); + + // // + // Add(X_BAR_PATTERN_RESISTANCE, patterns); + // Add(X_DIRECTION_NONE, patternsDir); + + // + // Add(X_BAR_PATTERN_SIGNALKEY, patterns); + // Add(X_DIRECTION_NONE, patternsDir); + + // + int nearestOrderFlowIDX = -1; + if (isBullish) + { + // + // Looking Bar Patterns to Detect Zone ... + isBullish = + isBullish && + HasChild(bullishOrderFlow) && + // bullishOrderFlow[0].lower == iBar.low && + // poiDetector.HasNearZone( + // nearestOrderFlowIDX, + // iBar.close, + // 5, + // bullishOrderFlow // + // ) && + poiDetector.HasRecentPatternTouched( + zone, + patterns, + patternsDir, + iBar.close, + barIndex, + 5, + 5, + iBar.period, + X_DIRECTION_BULLISH // + ); + } + else if (isBearish) + { + // + // Looking Bar Patterns to Detect Zone ... + isBearish = + isBearish && + HasChild(bearishOrderFlow) && + // bearishOrderFlow[0].upper == iBar.high && + // poiDetector.HasNearZone( + // nearestOrderFlowIDX, + // iBar.close, + // 5, + // bearishOrderFlow // + // ) && + poiDetector.HasRecentPatternTouched( + zone, + patterns, + patternsDir, + iBar.close, + barIndex, + 5, + 5, + iBar.period, + X_DIRECTION_BEARISH // + ); + } + + // + // Refactor Result ... + result = result && + zone.IsValid(); + if (result) + { + // + // Refine Zone ... + poiDetector.RefineZone(zone); + + // + // SL Refactoring ... + + // + XOHCL toBar; + if (zone.ToBar(toBar)) + { + // + int to = zone.ToIndex(); + int from = zone.FromIndex(); + int length = from - to; + double iValue = + isBullish + ? toBar.FindLowest(length, MODE_LOW) + : isBearish + ? toBar.FindHighest(length, MODE_HIGH) + : EMPTY_VALUE; + if (NotEmptyZero(iValue)) + { + // + if (isBullish) + { + zone.lower = MathMin(zone.lower, iValue); + } + + // + if (isBearish) + { + zone.upper = MathMax(zone.upper, iValue); + } + } + } + toBar.Clean(); + } + + // + // Do Directional Validation ... + if (result) + { + // + // Bullish ... + if (isBullish) + { + // + isBullish = + isBullish && + isLowerTFBullish && + isCandlestickBullish; + } + + // + // Bearish ... + if (isBearish) + { + // + isBearish = + isBearish && + isLowerTFBearish && + isCandlestickBearish; + } + + // + result = isBullish || isBearish; + if (!result) + { + // + isBullish = false; + isBearish = false; + } + } + + // + // Validate Result ... + if (!result) + { + // + iBar.Clean(); + + // + return result; + } + + // + // Draws ... + bool draw = true; + if (draw && result) + { + // + int drawn = 0; + + // + XPOIDrawConfig config; + config.Default(); + + // + if (zone.IsValid()) + { + // + drawn++; + + // + config.zonesWidth = 3; + config.bullishColor = clrYellow; + config.bearishColor = clrOrange; + + // + poiDrawer.DrawZone(zone, config); + + // + config.Default(); + } + + // + if (swingLow.IsValid()) + { + // + drawn++; + poiDrawer.DrawZone(swingLow, config); + } + + // + if (swingHigh.IsValid()) + { + // + drawn++; + poiDrawer.DrawZone(swingHigh, config); + } + + // + if (HasChild(bullishOrderFlow)) + { + // + drawn += ArraySize(bullishOrderFlow); + poiDrawer.DrawZones(bullishOrderFlow, config); + } + + // + if (HasChild(bearishOrderFlow)) + { + // + drawn += ArraySize(bearishOrderFlow); + poiDrawer.DrawZones(bearishOrderFlow, config); + } + + // + if (drawn > 0) + { + // DebugBreak(); + } + + // + config.Clean(); + } + + // + // Check and Prepare Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = result && + HasDirection(dir); + if (result) + { + // + // Prepare Zone ... + double entry = GetEntry(iBar.symbol, dir); + + // + double upper = isBullish + ? entry + : zone.upper; + double lower = isBullish + ? zone.lower + : entry; + datetime to = bar.time; + datetime from = isBullish + ? zone.from + : zone.from; + result = zone.Init( + iBar.symbol, + iBar.period, + upper, + lower, + from, + to, + dir, + "XS1" // + ); + } + + // + // Cleanup Resources ... + iBar.Clean(); + swingLow.Clean(); + XClean(patterns); + swingHigh.Clean(); + XClean(patternsDir); + XClean(bullishOrderFlow); + XClean(bearishOrderFlow); + + // + result = + result && + zone.IsValid() && + HasDirection(dir); + + // + return result; + } diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 128d9307..d17d4878 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -2181,7 +2181,7 @@ template void Sort( T &source[], ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, - ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH, + ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH, int maxAllowed = 0 // ) { @@ -3866,6 +3866,129 @@ void UpdateToTime( } } +/** + * Remove Breaked Zones from a Collection ... + * + * @param source: XBoxZone, reference to Specified Collection ... + * + * @return ( int ) + */ +int RemoveBreakedZones( + XBoxZone &source[], + bool forceBreak = false // +) +{ + // + int result = 0; + + // + // Validate ... + bool has = HasChild(source); + if (!has) + { + return result; + } + + // + XBoxZone iZone; + XBoxZone tmps[]; + Copy( + source, + tmps // + ); + XClean(source); + XOHCL tmpBars[]; + int breakerBars = 0; + while (HasChild(tmps)) + { + // + iZone.Clean(); + iZone = tmps[0]; + ArrayRemove(tmps, 0, 1); + has = IsXValid(iZone.breakAt); + if (has) + { + continue; + } + + // + if (forceBreak) + { + // + breakerBars = GetBreakerBars(iZone, tmpBars); + has = IsValidSize(breakerBars); + } + if (has) + { + continue; + } + + // + AddIfNotExists( + iZone, + source // + ); + } + + // + result = ArraySize(source); + + // + 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; +} + +// #region Zone Converters ... /** * Converts a Bar to Pivot ... * @@ -5076,7 +5199,6 @@ bool ToResistanceBox( box.lower = bar.GetUp(); box.dir = X_DIRECTION_BEARISH; box.type = ToXString(X_BAR_PATTERN_RESISTANCE); - ; // result = box.IsValid(); @@ -5088,129 +5210,9 @@ bool ToResistanceBox( // return result; } +// #endregion -/** - * Remove Breaked Zones from a Collection ... - * - * @param source: XBoxZone, reference to Specified Collection ... - * - * @return ( int ) - */ -int RemoveBreakedZones( - XBoxZone &source[], - bool forceBreak = false // -) -{ - // - int result = 0; - - // - // Validate ... - bool has = HasChild(source); - if (!has) - { - return result; - } - - // - XBoxZone iZone; - XBoxZone tmps[]; - Copy( - source, - tmps // - ); - XClean(source); - XOHCL tmpBars[]; - int breakerBars = 0; - while (HasChild(tmps)) - { - // - iZone.Clean(); - iZone = tmps[0]; - ArrayRemove(tmps, 0, 1); - has = IsXValid(iZone.breakAt); - if (has) - { - continue; - } - - // - if (forceBreak) - { - // - breakerBars = GetBreakerBars(iZone, tmpBars); - has = IsValidSize(breakerBars); - } - if (has) - { - continue; - } - - // - AddIfNotExists( - iZone, - source // - ); - } - - // - result = ArraySize(source); - - // - 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; -} - +// #region Zone Checkers ... /** * Check a Zone is Filled or Not ... * @@ -5349,8 +5351,46 @@ bool IsTested( // Check Test ... result = zone.IsBullish() - ? bar.low < zone.upper - : bar.high > zone.lower; + ? bar.low < zone.upper && bar.low > zone.lower + : bar.high > zone.lower && + bar.high < zone.upper; + + // + return result; +} + +/** + * Check Specified Zone is Rejected by Specified Bar or not ... + * + * @param bar: Specified Bar ... + * @param zone: Specified Zone ... + * + * @return ( bool ) + */ +bool IsRejected( + XOHCL &bar, + XBoxZone &zone // +) +{ + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + zone.IsValid(); + if (!result) + { + return result; + } + + // + // Check Test ... + result = + IsTested(bar, zone) && + (zone.IsBullish() + ? bar.GetDown() >= zone.upper + : bar.GetUp() <= zone.lower); // return result; @@ -5461,6 +5501,72 @@ bool IsActed( 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 // +) +{ + // + bool result = false; + + // + // Validate ... + result = zone.IsValid() && + IsXValid(priceType); + if (!result) + { + // + result = true; + return result; + } + + // + XOHCL iBar; + double iPrice; + bool isBullish; + int start = zone.ToIndex(); + int end = zone.FromIndex(); + for (int i = start; i < end; i++) + { + // + // Initialize Indexed Bar ... + iBar.Clean(); + result = iBar.Init(zone.symbol, zone.period, i); + if (!result) + { + // + result = true; + break; + } + + // + isBullish = zone.IsBullish(); + iPrice = iBar.GetPrice(priceType); + result = isBullish + ? iPrice < zone.lower + : iPrice > zone.upper; + if (result) + { + break; + } + } + + // + // Cleanup ... + iBar.Clean(); + + // + return result; +} + /** * Check Specified Bar is Acted On Specified Zone or not ... * @@ -5607,64 +5713,12 @@ bool IsFakeBreaked( return result; } -/** - * Check a Bar is Inside a Zone or not ... - * - * @param index: int, reference to holds detected index ... - * @param bar: reference to Specified Bar ... - * @param source: reference collection to provide source ... - * - * @return ( bool ) - */ -bool HasInside( - int &index, - XOHCL &bar, - XBoxZone &source[] // -) -{ - // - bool result = false; - - // - // Prepare ... - index = -1; - - // - // Validate ... - result = bar.IsValid() && - HasChild(source); - if (!result) - { - return result; - } - - // - int count = ArraySize(source); - for (int i = 0; i < count; i++) - { - // - result = IsInside( - bar, - source[i] // - ); - if (result) - { - // - index = i; - break; - } - } - - // - 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( @@ -5697,7 +5751,155 @@ bool IsZoneAffected( // return result; } +// #endregion +// #region Zones Hasers ... +/** + * Check a Bar is Inside a Zone or not ... + * + * @param index: int, reference to holds detected index ... + * @param bar: reference to Specified Bar ... + * @param source: reference collection to provide source ... + * + * @return ( bool ) + */ +bool HasInside( + int &index, + XOHCL &bar, + XBoxZone &source[] // +) +{ + // + XBoxZone selected[]; + int count = ExtractInsides(bar, selected, source); + bool result = IsValidSize(count); + if (result) + { + // + index = GetYoungest(selected); + if (IsValidIndex(index)) + { + result = FindIndex(index, selected[index], source); + } + } + + // + XClean(selected); + + // + return result; +} + +/** + * Check a Bar is Reject a Zone or not ... + * + * @param index: int, reference to holds detected index ... + * @param bar: reference to Specified Bar ... + * @param source: reference collection to provide source ... + * + * @return ( bool ) + */ +bool HasRejected( + int &index, + XOHCL &bar, + XBoxZone &source[] // +) +{ + // + XBoxZone selected[]; + int count = ExtractRejecteds(bar, selected, source); + bool result = IsValidSize(count); + if (result) + { + // + index = GetYoungest(selected); + if (IsValidIndex(index)) + { + result = FindIndex(index, selected[index], source); + } + } + + // + XClean(selected); + + // + return result; +} + +/** + * Check a Bar is Break a Zone or not ... + * + * @param index: int, reference to holds detected index ... + * @param bar: reference to Specified Bar ... + * @param source: reference collection to provide source ... + * + * @return ( bool ) + */ +bool HasBreaked( + int &index, + XOHCL &bar, + XBoxZone &source[] // +) +{ + // + XBoxZone selected[]; + int count = ExtractBreakeds(bar, selected, source); + bool result = IsValidSize(count); + if (result) + { + // + index = GetYoungest(selected); + if (IsValidIndex(index)) + { + result = FindIndex(index, selected[index], source); + } + } + + // + XClean(selected); + + // + return result; +} + +/** + * Check a Bar is Act a Zone or not ... + * + * @param index: int, reference to holds detected index ... + * @param bar: reference to Specified Bar ... + * @param source: reference collection to provide source ... + * + * @return ( bool ) + */ +bool HasActed( + int &index, + XOHCL &bar, + XBoxZone &source[] // +) +{ + // + XBoxZone selected[]; + int count = ExtractActeds(bar, selected, source); + bool result = IsValidSize(count); + if (result) + { + // + index = GetYoungest(selected); + if (IsValidIndex(index)) + { + result = FindIndex(index, selected[index], source); + } + } + + // + XClean(selected); + + // + return result; +} +// #endregion + +// #region Zone Extractors ... /** * Extract Affected Zones for Specified Bar ... * @@ -5804,7 +6006,7 @@ int ExtractInsides( // Validate ... bool has = bar.IsValid() && HasChild(source); - if (!result) + if (!has) { return result; } @@ -5861,7 +6063,7 @@ int ExtractActeds( // Validate ... bool has = bar.IsValid() && HasChild(source); - if (!result) + if (!has) { return result; } @@ -5918,7 +6120,7 @@ int ExtractBreakeds( // Validate ... bool has = bar.IsValid() && HasChild(source); - if (!result) + if (!has) { return result; } @@ -5949,6 +6151,63 @@ int ExtractBreakeds( return result; } +/** + * Extract all Items which Specified Bar is Rejected them ... + * + * @param bar: reference to Specified Bar ... + * @param dest: reference to result ... + * @param source: reference collection to provide source ... + * + * @return ( int ) + */ +int ExtractRejecteds( + XOHCL &bar, + XBoxZone &dest[], + XBoxZone &source[] // +) +{ + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(dest); + + // + // Validate ... + bool has = bar.IsValid() && + HasChild(source); + if (!has) + { + return result; + } + + // + int count = ArraySize(source); + for (int i = 0; i < count; i++) + { + // + has = IsRejected( + bar, + source[i] // + ); + if (has) + { + // + AddIfNotExists( + source[i], + dest // + ); + } + } + + // + result = ArraySize(dest); + + // + return result; +} + /** * Collect all Bars which Breakes Specified Zone ... * @@ -6175,72 +6434,6 @@ 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 // -) -{ - // - bool result = false; - - // - // Validate ... - result = zone.IsValid() && - IsXValid(priceType); - if (!result) - { - // - result = true; - return result; - } - - // - XOHCL iBar; - double iPrice; - bool isBullish; - int start = zone.ToIndex(); - int end = zone.FromIndex(); - for (int i = start; i < end; i++) - { - // - // Initialize Indexed Bar ... - iBar.Clean(); - result = iBar.Init(zone.symbol, zone.period, i); - if (!result) - { - // - result = true; - break; - } - - // - isBullish = zone.IsBullish(); - iPrice = iBar.GetPrice(priceType); - result = isBullish - ? iPrice < zone.lower - : iPrice > zone.upper; - if (result) - { - break; - } - } - - // - // Cleanup ... - iBar.Clean(); - - // - return result; -} - /** * Validate Zones Range ... * @@ -6301,10 +6494,10 @@ int ValidateZonesRange( /** * 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( @@ -6355,6 +6548,7 @@ int RemoveBreakedZones( // return result; } +// #endregion //+------------------------------------------------------------------+ // \ No newline at end of file diff --git a/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 b/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 index 5f6d407a..445bb9ce 100644 --- a/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 +++ b/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 @@ -988,12 +988,44 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller return result; } + // + ENUM_X_DIRECTION patternsDir[]; + ENUM_X_BAR_PATTERN patterns[]; + poiDetector.FillStrategy1Patterns( + patterns, + patternsDir // + ); + + // + isBullish = poiDetector.HasRecentPatternRejected( + zone, + patterns, + patternsDir, + barIndex, + 3, // Loopback .. + iBar.period, + X_DIRECTION_BULLISH // + ); + if (!isBullish) + { + // + isBearish = poiDetector.HasRecentPatternRejected( + zone, + patterns, + patternsDir, + barIndex, + 3, // Loopback .. + iBar.period, + X_DIRECTION_BEARISH // + ); + } + // #region Swings/OrderFlow ... // // Swings ... XBoxZone swingLow; XBoxZone swingHigh; - bool hasSwings = poiDetector.DetectRecentSwings( + poiDetector.DetectRecentSwings( swingHigh, swingLow, barIndex // @@ -1004,160 +1036,11 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller // XBoxZone bullishOrderFlow[]; - result = poiDetector.HasOrderFlow(bullishOrderFlow, barIndex, 4, X_DIRECTION_BULLISH, 15); + poiDetector.HasOrderFlow(bullishOrderFlow, barIndex, 4, X_DIRECTION_BULLISH, 15); // XBoxZone bearishOrderFlow[]; - result = poiDetector.HasOrderFlow(bearishOrderFlow, barIndex, 4, X_DIRECTION_BEARISH, 15); - // #endregion - - // #region Reading Conditions and Scoring ... - // - // ATR ... - bool isATRUp = kiParser.IsVolatilityHigh(barIndex) || - kiParser.IsVolatilitySwitchdToHigh(barIndex); - - // #region KI ... - // - bool isKIReadyForBullish = ((kiParser.IsKIFastBearish(barIndex) || - (kiParser.IsKIFastBullish(barIndex) && - iBar.IsRejected(kiHelper.GetKIFast(barIndex), X_DIRECTION_BULLISH))) && - kiParser.IsKISlowBullish(barIndex)); - - // - bool isKIReadyForBearish = ((kiParser.IsKIFastBullish(barIndex) || - (kiParser.IsKIFastBearish(barIndex) && - iBar.IsRejected(kiHelper.GetKIFast(barIndex), X_DIRECTION_BEARISH))) && - kiParser.IsKISlowBearish(barIndex)); - - // - bool isKIBandBullish = (kiHelper.GetKIUpper(barIndex) > kiHelper.GetKIUpper(barIndex + 1) || - kiHelper.GetKILower(barIndex) > kiHelper.GetKILower(barIndex + 1)); - - // - bool isKIBandBearish = (kiHelper.GetKIUpper(barIndex) < kiHelper.GetKIUpper(barIndex + 1) || - kiHelper.GetKILower(barIndex) < kiHelper.GetKILower(barIndex + 1)); - - // - bool isKIBullish = (kiParser.IsKIFastBullish(barIndex) || - kiParser.IsKIFastSwitchedToBullish(barIndex)) && - (kiParser.IsKISlowBullish(barIndex) || - kiParser.IsKISlowSwitchedToBullish(barIndex)); - if (isKIBullish) - { - scoreBullish++; - } - - // - bool isKIBearish = (kiParser.IsKIFastBearish(barIndex) || - kiParser.IsKIFastSwitchedToBearish(barIndex)) && - (kiParser.IsKISlowBearish(barIndex) || - kiParser.IsKISlowSwitchedToBearish(barIndex)); - if (isKIBearish) - { - scoreBearish++; - } - // #endregion - - // #region KI Wave ... - // - bool isKIWaveBullish = kiParser.IsKIWaveBullish(barIndex) || - kiParser.IsKIWaveSwitchedToBullish(barIndex); - if (isKIWaveBullish) - { - scoreBullish++; - } - - // - bool isKIWaveBearish = kiParser.IsKIWaveBearish(barIndex) || - kiParser.IsKIWaveSwitchedToBearish(barIndex); - if (isKIWaveBearish) - { - scoreBearish++; - } - // #endregion - - // #region MA ... - // - bool isMaBullish = kiParser.IsMACrossoverBullish(barIndex) || - kiParser.IsMACrossoverSwitchedToBullish(barIndex); - if (isMaBullish) - { - scoreBullish++; - } - - // - bool isMaBearish = kiParser.IsMACrossoverBearish(barIndex) || - kiParser.IsMACrossoverSwitchedToBearish(barIndex); - if (isMaBearish) - { - scoreBearish++; - } - // #endregion - - // #region LowerTF Candlstick ... - // - bool isLowerTFBullish = IsTFBullishPattern(barIndex, PERIOD_M5); - if (isLowerTFBullish) - { - scoreBullish++; - } - - // - bool isLowerTFBearish = IsTFBearishPattern(barIndex, PERIOD_M5); - if (isLowerTFBearish) - { - scoreBearish++; - } - // #endregion - - // #region Candlestick ... - // - bool isCandlestickBullish = poiDetector.HasCandlestickDirection( - iBar, - X_DIRECTION_BULLISH // - ); - if (isCandlestickBullish) - { - scoreBullish++; - } - - // - bool isCandlestickBearish = poiDetector.HasCandlestickDirection( - iBar, - X_DIRECTION_BEARISH // - ); - if (isCandlestickBearish) - { - scoreBearish++; - } - // #endregion - // #endregion - - // #region Summarize Directional Conditions ... - // - isBullish = - isATRUp && - isLowerTFBullish && - isKIReadyForBullish && - isCandlestickBullish && - scoreBullish >= 2 && - (isKIBullish || - isMaBullish || - isKIWaveBullish || - isKIBandBullish); - - // - isBearish = - isATRUp && - isLowerTFBearish && - isKIReadyForBearish && - isCandlestickBearish && - scoreBearish >= 2 && - (isKIBearish || - isMaBearish || - isKIWaveBearish || - isKIBandBearish); + poiDetector.HasOrderFlow(bearishOrderFlow, barIndex, 4, X_DIRECTION_BEARISH, 15); // #endregion // @@ -1172,168 +1055,33 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller return result; } - // - // Select Operational Zone ... - ENUM_X_DIRECTION patternsDir[]; - ENUM_X_BAR_PATTERN patterns[]; - - // - GetAllBarPatters(patterns, patternsDir); - - // - // XAUUSD ... - - // // - // // FVG ... - // Add(X_BAR_PATTERN_FVG, patterns); - // Add(X_DIRECTION_NONE, patternsDir); - - // // - // // Piercing ... - // Add(X_BAR_PATTERN_PIERCING, patterns); - // Add(X_DIRECTION_NONE, patternsDir); - - // - // EURUSD ... - - // - // Add(X_BAR_PATTERN_STAR, patterns); - // Add(X_DIRECTION_NONE, patternsDir); - - // // - // Add(X_BAR_PATTERN_SUPPORT, patterns); - // Add(X_DIRECTION_NONE, patternsDir); - - // // - // Add(X_BAR_PATTERN_RESISTANCE, patterns); - // Add(X_DIRECTION_NONE, patternsDir); - - // - // Add(X_BAR_PATTERN_SIGNALKEY, patterns); - // Add(X_DIRECTION_NONE, patternsDir); - - // - int nearestOrderFlowIDX = -1; - if (isBullish) - { - // - // Looking Bar Patterns to Detect Zone ... - isBullish = - isBullish && - HasChild(bullishOrderFlow) && - poiDetector.HasNearZone( - nearestOrderFlowIDX, - iBar.close, - 5, - bullishOrderFlow // - ) && - poiDetector.HasRecentPatternTouched( - zone, - patterns, - patternsDir, - iBar.close, - barIndex, - 5, - 5, - iBar.period, - X_DIRECTION_BULLISH // - ); - } - else if (isBearish) - { - // - // Looking Bar Patterns to Detect Zone ... - isBearish = - isBearish && - HasChild(bearishOrderFlow) && - poiDetector.HasNearZone( - nearestOrderFlowIDX, - iBar.close, - 5, - bearishOrderFlow // - ) && - poiDetector.HasRecentPatternTouched( - zone, - patterns, - patternsDir, - iBar.close, - barIndex, - 5, - 5, - iBar.period, - X_DIRECTION_BEARISH // - ); - } - - // - // Refactor Result ... - result = result && - zone.IsValid(); - if (result) - { - // - // Refine Zone ... - poiDetector.RefineZone(zone); - - // - // SL Refactoring ... - - // - XOHCL toBar; - if (zone.ToBar(toBar)) - { - // - int to = zone.ToIndex(); - int from = zone.FromIndex(); - int length = from - to; - double iValue = - isBullish - ? toBar.FindLowest(length, MODE_LOW) - : isBearish - ? toBar.FindHighest(length, MODE_HIGH) - : EMPTY_VALUE; - if (NotEmptyZero(iValue)) - { - // - if (isBullish) - { - zone.lower = MathMin(zone.lower, iValue); - } - - // - if (isBearish) - { - zone.upper = MathMax(zone.upper, iValue); - } - } - } - toBar.Clean(); - } - // // Do Directional Validation ... if (result) { + // + poiDetector.RefactorStrategy1OperationalZone(zone); + // // Bullish ... if (isBullish) { - // - isBullish = - isBullish && - isLowerTFBullish && - isCandlestickBullish; + // // + // isBullish = + // isBullish && + // isLowerTFBullish && + // isCandlestickBullish; } // // Bearish ... if (isBearish) { - // - isBearish = - isBearish && - isLowerTFBearish && - isCandlestickBearish; + // // + // isBearish = + // isBearish && + // isLowerTFBearish && + // isCandlestickBearish; } // @@ -1346,17 +1094,6 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller } } - // - // Validate Result ... - if (!result) - { - // - iBar.Clean(); - - // - return result; - } - // // Draws ... bool draw = true; @@ -1365,6 +1102,9 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller // int drawn = 0; + // + poiDrawer.drawnObjects.Clear(); + // XPOIDrawConfig config; config.Default(); @@ -1422,7 +1162,8 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller // if (drawn > 0) { - // DebugBreak(); + DebugBreak(); + return false; } // @@ -1493,8 +1234,7 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller * * @return ( bool ) */ - bool - Strategy2HasSignal( + bool Strategy2HasSignal( XOHCL &bar, XBoxZone &zone, XTarget &targets[], diff --git a/X121XKIEA/Classes/x-saherelm.x121.xki.x-poi.detector.class.mq5 b/X121XKIEA/Classes/x-saherelm.x121.xki.x-poi.detector.class.mq5 index c3edc7bb..ca379ee6 100644 --- a/X121XKIEA/Classes/x-saherelm.x121.xki.x-poi.detector.class.mq5 +++ b/X121XKIEA/Classes/x-saherelm.x121.xki.x-poi.detector.class.mq5 @@ -2391,7 +2391,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // return result; } - + bool HasOrderFlow( XBoxZone &flow[], int barIndex = 0, @@ -2567,6 +2567,10 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // result = HasChild(flow); + if (result) + { + Sort(flow); + } // return result; @@ -2675,6 +2679,84 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // #endregion // #region Bar Patterns ... + void FillStrategy1Patterns( + ENUM_X_BAR_PATTERN &patterns[], + ENUM_X_DIRECTION &dirs[], + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + XClean(dirs); + XClean(patterns); + + // + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + + // + GetAllBarPatters(patterns, dirs); + + // + // Add(X_BAR_PATTERN_FVG, patterns); + // Add(forDir, dirs); + } + + void RefactorStrategy1OperationalZone(XBoxZone &zone) + { + + // + if (!zone.IsValid()) + { + return; + } + + // + // Refine Zone ... + RefineZone(zone); + + // + // SL Refactoring ... + + // + XOHCL toBar; + if (zone.ToBar(toBar)) + { + // + int to = zone.ToIndex(); + int from = zone.FromIndex(); + int length = from - to; + double iValue = + zone.IsBullish() + ? toBar.FindLowest(length, MODE_LOW) + : zone.IsBearish() + ? toBar.FindHighest(length, MODE_HIGH) + : EMPTY_VALUE; + if (NotEmptyZero(iValue)) + { + // + if (zone.IsBullish()) + { + zone.lower = MathMin(zone.lower, iValue); + } + + // + if (zone.IsBearish()) + { + zone.upper = MathMax(zone.upper, iValue); + } + } + } + toBar.Clean(); + } + /* * Check Recently Pattern Zone is Touched or not ... * @@ -2871,6 +2953,182 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // return result; } + + /* + * Check Recently Pattern Zone is Rejected or not ... + * + * @param zone: XBoxZone, Touched Zone ... + * @param patterns: ENUM_X_BAR_PATTERN, Allowed to Check Patterns ... + * @param patternsDir: ENUM_X_DIRECTION, Allowed Directions ... + * @param price: double, a Price to Check Toch or Reject ... + * @param barIndex: int, Bar Index to Start Checking ... + * @param loopback: int, Loopback for Pattern Formations ... + * @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ... + * @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ... + * + * @return ( bool ) + */ + bool HasRecentPatternRejected( + XBoxZone &zone, + ENUM_X_BAR_PATTERN &patterns[], + ENUM_X_DIRECTION &patternsDir[], + int barIndex = 0, + int loopback = 5, + ENUM_TIMEFRAMES forPeriod = NULL, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // + ) + { + // + bool result = false; + + // + zone.Clean(); + + // + // Validate ... + result = + HasChild(patterns) && + HasChild(patternsDir) && + ArraySize(patterns) == ArraySize(patternsDir); + if (!result) + { + return result; + } + + // + // Normalize ... + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + if (IsXValid(forPeriod)) + { + forPeriod = period; + } + + // + XOHCL bar; + result = bar.Init(symbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + int iBullishIDX = -1; + int iBearishIDX = -1; + bool isBullish = false; + bool isBearish = false; + XBoxZone iBullishZones[]; + XBoxZone iBearishZones[]; + XPatternAnalysis iAnalysis; + XPatternAnalysisConfig iConfig; + + // + // Preparing Pattern Analysis Config ... + iConfig.Default(); + + // + Copy( + patterns, + iConfig.allowedPatterns // + ); + Copy( + patternsDir, + iConfig.allowedDirs // + ); + + // + // Looping Back ... + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + // Initialize Bar ... + has = iBar.Init(symbol, forPeriod, i); + if (!has) + { + continue; + } + + // + // Analyse Patterns ... + has = AnalyseBarPatterns(iBar, iAnalysis, iConfig); + if (!has) + { + // + iBar.Clean(); + continue; + } + + // + // Bullish ... + has = iAnalysis.Count(X_DIRECTION_BULLISH) > 0; + if (has) + { + // + iAnalysis.GetPatterns(iBullishZones, X_DIRECTION_BULLISH); + isBullish = + HasChild(iBullishZones) && + HasRejected(iBullishIDX, bar, iBullishZones); + } + + // + // Bearish ... + has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0; + if (has) + { + // + iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH); + isBearish = + HasChild(iBearishZones) && + HasRejected(iBearishIDX, bar, iBearishZones); + } + + // + // Summarizing Result ... + has = + HasDirection(forDir) + ? (isBullish && !isBearish && IsXBullish(forDir)) || + (isBearish && !isBullish && IsXBearish(forDir)) + : (isBullish && !isBearish) || (isBearish && !isBullish); + if (has) + { + // + // Fill Zones ... + if (isBullish) + { + zone = iBullishZones[iBullishIDX]; + } + else + { + zone = iBearishZones[iBearishIDX]; + } + break; + } + + // + // Cleanup Resource ... + iBar.Clean(); + iAnalysis.Clean(); + XClean(iBullishZones); + XClean(iBearishZones); + } + + // + // Cleanup Resources ... + bar.Clean(); + iBar.Clean(); + iConfig.Clean(); + iAnalysis.Clean(); + XClean(iBullishZones); + XClean(iBearishZones); + + // + result = zone.IsValid(); + + // + return result; + } // #endregion //