From 574c79afccee520491cbf757222e3698b1952f9a Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 30 Oct 2025 00:07:23 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-market.pattern.class.mq5 | 422 -------- Documents/BKP/xfima.tmp.codes.poi.mq5 | 916 ++++++++++++++++++ Libraries/x-saherelm.x-pivot.analysis.lib.mq5 | 193 ---- .../Classes/x-saherelm.xfima.parser.class.mq5 | 782 ++++++++++++--- .../x-saherelm.xfima.signaller.class.mq5 | 561 ++++++----- .../x-saherelm.xfima.x-poi.detector.class.mq5 | 296 +++++- 6 files changed, 2209 insertions(+), 961 deletions(-) create mode 100644 Documents/BKP/xfima.tmp.codes.poi.mq5 diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index 054d3cc0..840cda69 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -1660,428 +1660,6 @@ class XCMarketPatternDetector : public XCBase return result; } - /** - * Leg Pattern Detection ... - * - * @param bar: XOHCL, reference to Specified Bar ... - * @param zone: XBoxZone, reference to Holds Detection Zone ... - * @param validationLength: int, leg minimum Validation Length ... - * @param loopback: int, Max Allowed Loopback Length ... - * - * @return ( bool ) - */ - bool IsLegPattern( - XOHCL &bar, - XLeg &leg, - int validationLength = 3, - int loopback = 10 // - ) - { - // - bool result = false; - - // - // Prepare ... - leg.Clean(); - - // - // Normalize ... - loopback = NormalizeInt(loopback, 5); - - // - // Validate ... - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - // Prepare Patterns Analysis Config ... - XPatternAnalysisConfig iPatternsConfig; - iPatternsConfig.Default(); - iPatternsConfig.CleanPatterns(); - iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW); - iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH); - iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG); - iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR); - iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING); - iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING); - iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED); - iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM); - iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY); - iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED); - - // - XOHCL iBar; - XOHCL pBar; - XOHCL iZBar; - XBoxZone zone; - XBoxZone iZone; - XBoxZone jZone; - bool has = false; - XBoxZone supports[]; - XOHCL bullishBars[]; - XOHCL bearishBars[]; - XBoxZone bullishFVGs[]; - XBoxZone bearishFVGs[]; - bool isBullish = false; - bool isBearish = false; - XBoxZone resistances[]; - double bullishPower = 0; - double bearishPower = 0; - int bullishBarsCount = 0; - int bearishBarsCount = 0; - int barIndex = bar.Index(); - int start = barIndex + 1; - XPatternAnalysis iPattern; - int end = start + loopback; - XPatternAnalysis patterns[]; - int bullishPatternsCount = 0; - int bearishPatternsCount = 0; - int sequentialsBullishBarsCount = 0; - int sequentialsBearishBarsCount = 0; - ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; - - // - for (int i = end; i >= start; i--) - { - // - // Initialize Indexed Bar ... - iBar.Clean(); - pBar.Clean(); - result = bar.BarAt(i, iBar); - result = result && - iBar.GetPreviousBar(pBar); - if (!result) - { - break; - } - - // - // Fill Bar Direction ... - isBullish = iBar.IsBullish(); - isBearish = iBar.IsBearish(); - - // - // Directional ... - - // - if (isBullish) - { - // - bullishBarsCount++; - - // - bullishPower += iBar.GetBody(); - bullishPower += iBar.GetLowShadow(); - bullishPower -= iBar.GetHighShadow(); - - // - AddIfNotExists(iBar, bullishBars); - } - - // - if (isBearish) - { - // - bearishBarsCount++; - - // - bearishPower += iBar.GetBody(); - bearishPower -= iBar.GetLowShadow(); - bearishPower += iBar.GetHighShadow(); - - // - AddIfNotExists(iBar, bearishBars); - } - - // - // Sequentail .... - - // - // Bullish ... - if (isBullish) - { - // - if (pBar.IsBullish()) - { - sequentialsBullishBarsCount++; - } - else if (pBar.IsBearish()) - { - sequentialsBullishBarsCount = 0; - } - } - - // - // Bearish ... - if (isBearish) - { - // - if (pBar.IsBearish()) - { - sequentialsBearishBarsCount++; - } - else if (pBar.IsBullish()) - { - sequentialsBearishBarsCount = 0; - } - } - - // - // Detect Patterns ... - iPattern.Clean(); - has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig); - if (has) - { - // - AddRef(iPattern, patterns); - - // - bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH); - bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH); - } - - // - // FVG Detection ... - CleanDirection(iDir); - has = HasFVG(iBar, iDir, iZone); - if (has) - { - // - if (iZone.IsBullish()) - { - AddIfNotExists(iZone, bullishFVGs); - } - else - { - AddIfNotExists(iZone, bearishFVGs); - } - } - - // - // Support / Resistance Detection ... - has = HasSupportResistance( - iBar, - iZone, - jZone, - 5 // - ); - if (has) - { - // - if (iZone.IsValid()) - { - AddIfNotExists(iZone, supports); - } - - // - if (jZone.IsValid()) - { - AddIfNotExists(jZone, resistances); - } - } - } - - // - // Summarizing ... - - // - // Detect Direction ... - zone.Clean(); - isBullish = false; - isBearish = false; - CleanDirection(iDir); - - // - isBullish = - // - bullishPower > 0 && - bullishBarsCount > 0 && - bullishPatternsCount > 0 && - sequentialsBullishBarsCount > 0 && - // - bullishPower > bearishPower && - bullishBarsCount > bearishBarsCount && - bullishPatternsCount > bearishPatternsCount && - sequentialsBullishBarsCount > sequentialsBearishBarsCount - // - ; - - // - isBearish = - // - bearishPower > 0 && - bearishBarsCount > 0 && - bearishPatternsCount > 0 && - sequentialsBearishBarsCount > 0 && - // - bearishPower > bullishPower && - bearishBarsCount > bullishBarsCount && - bearishPatternsCount > bullishPatternsCount && - sequentialsBearishBarsCount > sequentialsBullishBarsCount - // - ; - - // - // Validate ... - result = - (isBullish && !isBearish) || - (isBearish && !isBullish); - - // - // PRICE Types ... - ENUM_X_PRICE lowerPriceType = X_PRICE_LOW; - ENUM_X_PRICE upperPriceType = X_PRICE_HIGH; - - // - // Prepare Zone ... - if (result) - { - // - zone.at = bar.time; - zone.to = bar.time; - zone.period = bar.period; - zone.symbol = bar.symbol; - - // - zone.type = ToXString(X_BAR_PATTERN_LEG); - zone.dir = isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - int idx = -1; - if (isBullish) - { - idx = GetOldest(bullishBars); - } - else - { - idx = GetOldest(bearishBars); - } - - // - result = IsValidIndex(idx); - if (result) - { - // - iZBar.Clean(); - if (isBullish) - { - iZBar = bullishBars[idx]; - } - else - { - iZBar = bearishBars[idx]; - } - - // - zone.from = iZBar.time; - - // - iZBar.Clean(); - } - - // - if (isBullish) - { - // - // Prepare Upper and Lower ... - - // - // Upper ... - idx = GetHighestBarPrice(bullishBars, upperPriceType); - if (IsValidIndex(idx)) - { - zone.upper = bullishBars[idx].GetPrice(upperPriceType); - } - - // - // Lower ... - idx = GetLowestBarPrice(bullishBars, upperPriceType); - if (IsValidIndex(idx)) - { - zone.lower = bullishBars[idx].GetPrice(lowerPriceType); - } - } - else - { - // - // Prepare Upper and Lower ... - - // - // Upper ... - idx = GetHighestBarPrice(bearishBars, upperPriceType); - if (IsValidIndex(idx)) - { - zone.upper = bearishBars[idx].GetPrice(upperPriceType); - } - - // - // Lower ... - idx = GetLowestBarPrice(bearishBars, upperPriceType); - if (IsValidIndex(idx)) - { - zone.lower = bearishBars[idx].GetPrice(lowerPriceType); - } - } - - // - result = zone.IsValid(); - } - - // - // Prepare XLeg ... - if (result) - { - // - leg.dir = zone.dir; - leg.time = zone.from; - leg.upper = zone.upper; - leg.lower = zone.lower; - leg.symbol = zone.symbol; - leg.period = zone.period; - Copy(patterns, leg.patterns); - Copy(supports, leg.supports); - Copy(bullishBars, leg.bullishBars); - Copy(bearishBars, leg.bearishBars); - Copy(resistances, leg.resistances); - Copy(bullishFVGs, leg.bullishFVGs); - Copy(bearishFVGs, leg.bearishFVGs); - leg.sequentialBullishBars = sequentialsBullishBarsCount; - leg.sequentialBearishBars = sequentialsBearishBarsCount; - - // - result = leg.IsValid(); - } - - // - // Cleanup ... - if (!result) - { - zone.Clean(); - } - iBar.Clean(); - pBar.Clean(); - zone.Clean(); - iZBar.Clean(); - iZone.Clean(); - jZone.Clean(); - iPattern.Clean(); - XClean(supports); - XClean(patterns); - XClean(bullishBars); - XClean(bearishBars); - XClean(bullishFVGs); - XClean(bearishFVGs); - XClean(resistances); - - // - return result; - } - /** * Detect Order Flow ... * diff --git a/Documents/BKP/xfima.tmp.codes.poi.mq5 b/Documents/BKP/xfima.tmp.codes.poi.mq5 new file mode 100644 index 00000000..2451c737 --- /dev/null +++ b/Documents/BKP/xfima.tmp.codes.poi.mq5 @@ -0,0 +1,916 @@ + +/** + * Leg Pattern Detection ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param zone: XBoxZone, reference to Holds Detection Zone ... + * @param validationLength: int, leg minimum Validation Length ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( bool ) + */ +bool IsLegPattern( + XOHCL &bar, + XLeg &leg, + int validationLength = 3, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Prepare ... + leg.Clean(); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 5); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Prepare Patterns Analysis Config ... + XPatternAnalysisConfig iPatternsConfig; + iPatternsConfig.Default(); + iPatternsConfig.CleanPatterns(); + iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW); + iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH); + iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG); + iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR); + iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING); + iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING); + iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED); + iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM); + iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY); + iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED); + + // + XOHCL iBar; + XOHCL pBar; + XOHCL iZBar; + XBoxZone zone; + XBoxZone iZone; + XBoxZone jZone; + bool has = false; + XBoxZone supports[]; + XOHCL bullishBars[]; + XOHCL bearishBars[]; + XBoxZone bullishFVGs[]; + XBoxZone bearishFVGs[]; + bool isBullish = false; + bool isBearish = false; + XBoxZone resistances[]; + double bullishPower = 0; + double bearishPower = 0; + int bullishBarsCount = 0; + int bearishBarsCount = 0; + int barIndex = bar.Index(); + int start = barIndex + 1; + XPatternAnalysis iPattern; + int end = start + loopback; + XPatternAnalysis patterns[]; + int bullishPatternsCount = 0; + int bearishPatternsCount = 0; + int sequentialsBullishBarsCount = 0; + int sequentialsBearishBarsCount = 0; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + for (int i = end; i >= start; i--) + { + // + // Initialize Indexed Bar ... + iBar.Clean(); + pBar.Clean(); + result = bar.BarAt(i, iBar); + result = result && + iBar.GetPreviousBar(pBar); + if (!result) + { + break; + } + + // + // Fill Bar Direction ... + isBullish = iBar.IsBullish(); + isBearish = iBar.IsBearish(); + + // + // Directional ... + + // + if (isBullish) + { + // + bullishBarsCount++; + + // + bullishPower += iBar.GetBody(); + bullishPower += iBar.GetLowShadow(); + bullishPower -= iBar.GetHighShadow(); + + // + AddIfNotExists(iBar, bullishBars); + } + + // + if (isBearish) + { + // + bearishBarsCount++; + + // + bearishPower += iBar.GetBody(); + bearishPower -= iBar.GetLowShadow(); + bearishPower += iBar.GetHighShadow(); + + // + AddIfNotExists(iBar, bearishBars); + } + + // + // Sequentail .... + + // + // Bullish ... + if (isBullish) + { + // + if (pBar.IsBullish()) + { + sequentialsBullishBarsCount++; + } + else if (pBar.IsBearish()) + { + sequentialsBullishBarsCount = 0; + } + } + + // + // Bearish ... + if (isBearish) + { + // + if (pBar.IsBearish()) + { + sequentialsBearishBarsCount++; + } + else if (pBar.IsBullish()) + { + sequentialsBearishBarsCount = 0; + } + } + + // + // Detect Patterns ... + iPattern.Clean(); + has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig); + if (has) + { + // + AddRef(iPattern, patterns); + + // + bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH); + bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH); + } + + // + // FVG Detection ... + CleanDirection(iDir); + has = HasFVG(iBar, iDir, iZone); + if (has) + { + // + if (iZone.IsBullish()) + { + AddIfNotExists(iZone, bullishFVGs); + } + else + { + AddIfNotExists(iZone, bearishFVGs); + } + } + + // + // Support / Resistance Detection ... + has = HasSupportResistance( + iBar, + iZone, + jZone, + 5 // + ); + if (has) + { + // + if (iZone.IsValid()) + { + AddIfNotExists(iZone, supports); + } + + // + if (jZone.IsValid()) + { + AddIfNotExists(jZone, resistances); + } + } + } + + // + // Summarizing ... + + // + // Detect Direction ... + zone.Clean(); + isBullish = false; + isBearish = false; + CleanDirection(iDir); + + // + isBullish = + // + bullishPower > 0 && + bullishBarsCount > 0 && + bullishPatternsCount > 0 && + sequentialsBullishBarsCount > 0 && + // + bullishPower > bearishPower && + bullishBarsCount > bearishBarsCount && + bullishPatternsCount > bearishPatternsCount && + sequentialsBullishBarsCount > sequentialsBearishBarsCount + // + ; + + // + isBearish = + // + bearishPower > 0 && + bearishBarsCount > 0 && + bearishPatternsCount > 0 && + sequentialsBearishBarsCount > 0 && + // + bearishPower > bullishPower && + bearishBarsCount > bullishBarsCount && + bearishPatternsCount > bullishPatternsCount && + sequentialsBearishBarsCount > sequentialsBullishBarsCount + // + ; + + // + // Validate ... + result = + (isBullish && !isBearish) || + (isBearish && !isBullish); + + // + // PRICE Types ... + ENUM_X_PRICE lowerPriceType = X_PRICE_LOW; + ENUM_X_PRICE upperPriceType = X_PRICE_HIGH; + + // + // Prepare Zone ... + if (result) + { + // + zone.at = bar.time; + zone.to = bar.time; + zone.period = bar.period; + zone.symbol = bar.symbol; + + // + zone.type = ToXString(X_BAR_PATTERN_LEG); + zone.dir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + int idx = -1; + if (isBullish) + { + idx = GetOldest(bullishBars); + } + else + { + idx = GetOldest(bearishBars); + } + + // + result = IsValidIndex(idx); + if (result) + { + // + iZBar.Clean(); + if (isBullish) + { + iZBar = bullishBars[idx]; + } + else + { + iZBar = bearishBars[idx]; + } + + // + zone.from = iZBar.time; + + // + iZBar.Clean(); + } + + // + if (isBullish) + { + // + // Prepare Upper and Lower ... + + // + // Upper ... + idx = GetHighestBarPrice(bullishBars, upperPriceType); + if (IsValidIndex(idx)) + { + zone.upper = bullishBars[idx].GetPrice(upperPriceType); + } + + // + // Lower ... + idx = GetLowestBarPrice(bullishBars, upperPriceType); + if (IsValidIndex(idx)) + { + zone.lower = bullishBars[idx].GetPrice(lowerPriceType); + } + } + else + { + // + // Prepare Upper and Lower ... + + // + // Upper ... + idx = GetHighestBarPrice(bearishBars, upperPriceType); + if (IsValidIndex(idx)) + { + zone.upper = bearishBars[idx].GetPrice(upperPriceType); + } + + // + // Lower ... + idx = GetLowestBarPrice(bearishBars, upperPriceType); + if (IsValidIndex(idx)) + { + zone.lower = bearishBars[idx].GetPrice(lowerPriceType); + } + } + + // + result = zone.IsValid(); + } + + // + // Prepare XLeg ... + if (result) + { + // + leg.dir = zone.dir; + leg.time = zone.from; + leg.upper = zone.upper; + leg.lower = zone.lower; + leg.symbol = zone.symbol; + leg.period = zone.period; + Copy(patterns, leg.patterns); + Copy(supports, leg.supports); + Copy(bullishBars, leg.bullishBars); + Copy(bearishBars, leg.bearishBars); + Copy(resistances, leg.resistances); + Copy(bullishFVGs, leg.bullishFVGs); + Copy(bearishFVGs, leg.bearishFVGs); + leg.sequentialBullishBars = sequentialsBullishBarsCount; + leg.sequentialBearishBars = sequentialsBearishBarsCount; + + // + result = leg.IsValid(); + } + + // + // Cleanup ... + if (!result) + { + zone.Clean(); + } + iBar.Clean(); + pBar.Clean(); + zone.Clean(); + iZBar.Clean(); + iZone.Clean(); + jZone.Clean(); + iPattern.Clean(); + XClean(supports); + XClean(patterns); + XClean(bullishBars); + XClean(bearishBars); + XClean(bullishFVGs); + XClean(bearishFVGs); + XClean(resistances); + + // + return result; +} + +bool IsLegPattern1( + XOHCL &bar, + XLeg &leg, + int validationLength = 5, + int loopback = 500 // +) +{ + // + bool result = false; + + // + // Prepare ... + leg.Clean(); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + validationLength = NormalizeInt(validationLength, 3); + + // + // Validate ... + result = bar.IsValid() && + fimaParser.IsValid(); + if (!result) + { + return result; + } + + // + int idx = bar.Index(); + while (idx < bar.Index() + loopback) + { + // + } + + // + return result; +} + +////////////////////////////////////////////////// + +// +// Leg ... + +XLeg leg; // Exists Leg ... +bool drawLeg; // Draw Leg ... +bool manageLegs; + +// +bool HasLeg() +{ + return leg.IsValid(); +} + +// +bool ValidateLeg(XOHCL &bar) +{ + // + bool result = false; + + // + result = HasLeg() && + bar.IsValid(); + if (!result) + { + return result; + } + + // + result = + leg.IsBullish() + ? bar.low > leg.lower + : leg.IsBearish() + ? bar.high < leg.upper + : false; + + // + return result; +} + +// +void DrawLeg() +{ + // + if (!drawLeg) + { + return; + } + + // + if (!HasLeg()) + { + return; + } + + // + // Update to Times ... + leg.UpdateTimes(); + + // + // Draw Leg Box ... + XBoxZone legZone; + leg.ToBox(legZone); + if (legZone.IsValid()) + { + // + legZone.to = TimeCurrent(); + poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig); + } + + // + // Draw Legs Other Stufs ... + return; + + // + // FVGs ... + poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig); + poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig); + + // + // Support and Resistances ... + poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig); + poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig); + + // + // Patterns ... + poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig); +} + +// +void ManageLeg(XOHCL &bar) +{ + // + // Validate Exists ... + if (HasLeg()) + { + // + if (!ValidateLeg(bar)) + { + // + // Invalidate XLeg ... + leg.Clean(); + } + } + + // + // Detect New ... + if (!HasLeg()) + { + poiDetector.IsLegPattern(bar, leg); + } + + // + // Update Exists ... + if (HasLeg()) + { + // + // Update to Times ... + leg.UpdateTimes(); + + // + DrawLeg(); + } +} + +// +// +// + +ManageLeg(bar); + +// +// Checking For Leg Pattern ... +bool hasLeg = poiDetector.IsLegPattern( + pBar, + _leg, + 3, + 10 // +); +if (hasLeg) +{ + hasLeg = _leg.ToBox(legZone); +} +bool hasBullishLeg = hasLeg && _leg.IsBullish(); +bool hasBearishLeg = hasLeg && _leg.IsBearish(); + +// +// +// + +int CollectPivots( + XPivot &pivots[], + int barIndex = 0, + int loopback = 500 // +) +{ + // + int result = 0; + + // + // Prepare ... + XClean(pivots); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + has = false; + XOHCL tmpBar; + XPivot tmpPivot; + double tmpValue; + datetime tmpTime; + bool isBullish = false; + bool isBearish = false; + string tmpSymbol = symbol; + ENUM_TIMEFRAMES tmpPeriod = period; + ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + tmpBar.Clean(); + tmpPivot.Clean(); + + // + has = tmpBar.Init(tmpSymbol, tmpPeriod, i); + if (!has) + { + continue; + } + + // + // XSAR ... + isBullish = IsSARSwitchedToBullish(i); + isBearish = IsSARSwitchedToBearish(i); + has = isBullish || isBearish; + if (has) + { + } + + // + // XMA Fast / Slow ... + + // + // States ... + isBullish = IsMASlowSwitchedToBullish(i); + isBearish = IsMASlowSwitchedToBearish(i); + has = isBullish || isBearish; + if (has) + { + } + + // + // Crossed Fast Slow ... + isBullish = IsMAFastCrossedOverSlow(i); + isBearish = IsMAFastCrossedUnderSlow(i); + has = isBullish || isBearish; + if (has) + { + } + + // + // Crossed Last ... + isBullish = IsMASlowCrossedOverLast(i); + isBearish = IsMASlowCrossedUnderLast(i); + has = isBullish || isBearish; + if (has) + { + } + + // + // XHK ... + isBullish = IsHKSwitchedToBullish(i); + isBearish = IsHKSwitchedToBearish(i); + has = isBullish || isBearish; + if (has) + { + } + } + + // + result = ArraySize(pivots); + + // + return result; +} + +// +// +// + + +/** + * an strucutre to Model Specified Leg Pattern ... + **/ +struct XLeg +{ + // + // Props ... + + // + datetime time; + string symbol; + ENUM_X_DIRECTION dir; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + XOHCL bullishBars[]; + XOHCL bearishBars[]; + + // + XBoxZone supports[]; + XBoxZone resistances[]; + + // + XBoxZone bullishFVGs[]; + XBoxZone bearishFVGs[]; + + // + XPatternAnalysis patterns[]; + + // + int sequentialBullishBars; + int sequentialBearishBars; + + // + // Constructor ... + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + time = NULL; + symbol = NULL; + period = NULL; + dir = X_DIRECTION_NONE; + + // + upper = 0; + lower = 0; + sequentialBullishBars = 0; + sequentialBearishBars = 0; + + // + XClean(patterns); + XClean(supports); + XClean(bullishBars); + XClean(bearishBars); + XClean(resistances); + XClean(bullishFVGs); + XClean(bearishFVGs); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + IsXValid(time) && + IsXValid(symbol) && + IsXValid(period) && + HasDirection(dir) && + NotEmptyZero(upper) && + NotEmptyZero(lower) && + upper > lower; + + // + return result; + } + + /** + * Check is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + return IsValid() && + IsXBullish(dir); + } + + /** + * Check is Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + return IsValid() && + IsXBearish(dir); + } + + /** + * Converts a Leg to XBoxZone ... + * + * @param zone: XBoxZone, reference to holds Converted ... + * + * @return ( bool ) + */ + bool ToBox(XBoxZone &zone) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + zone.at = time; + zone.dir = dir; + zone.from = time; + zone.upper = upper; + zone.lower = lower; + zone.symbol = symbol; + zone.period = period; + zone.to = TimeCurrent(); + zone.type = ToXString(X_BAR_PATTERN_LEG); + + // + result = zone.IsValid(); + + // + // Cleanup ... + if (!result) + { + zone.Clean(); + } + + // + return result; + } + + /** + * Update Times of Collections ... + * + * @param value: datetime, Specified Time ... + */ + void UpdateTimes(datetime value = NULL) + { + // + // Normalize ... + value = NormalizeTime(value); + + // + // Validate ... + if (!IsValid()) + { + return; + } + + // + UpdateToTime(supports, value); + UpdateToTime(resistances, value); + UpdateToTime(bullishFVGs, value); + UpdateToTime(bearishFVGs, value); + } + + // +}; diff --git a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 index 504eb9de..f05366d2 100644 --- a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 +++ b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 @@ -2916,199 +2916,6 @@ struct XPatternAnalysisDrawConfig } }; -/** - * an strucutre to Model Specified Leg Pattern ... - **/ -struct XLeg -{ - // - // Props ... - - // - datetime time; - string symbol; - ENUM_X_DIRECTION dir; - ENUM_TIMEFRAMES period; - - // - double upper; - double lower; - - // - XOHCL bullishBars[]; - XOHCL bearishBars[]; - - // - XBoxZone supports[]; - XBoxZone resistances[]; - - // - XBoxZone bullishFVGs[]; - XBoxZone bearishFVGs[]; - - // - XPatternAnalysis patterns[]; - - // - int sequentialBullishBars; - int sequentialBearishBars; - - // - // Constructor ... - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - time = NULL; - symbol = NULL; - period = NULL; - dir = X_DIRECTION_NONE; - - // - upper = 0; - lower = 0; - sequentialBullishBars = 0; - sequentialBearishBars = 0; - - // - XClean(patterns); - XClean(supports); - XClean(bullishBars); - XClean(bearishBars); - XClean(resistances); - XClean(bullishFVGs); - XClean(bearishFVGs); - } - - /** - * Validate ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - IsXValid(time) && - IsXValid(symbol) && - IsXValid(period) && - HasDirection(dir) && - NotEmptyZero(upper) && - NotEmptyZero(lower) && - upper > lower; - - // - return result; - } - - /** - * Check is Bullish ... - * - * @return ( bool ) - */ - bool IsBullish() - { - return IsValid() && - IsXBullish(dir); - } - - /** - * Check is Bearish ... - * - * @return ( bool ) - */ - bool IsBearish() - { - return IsValid() && - IsXBearish(dir); - } - - /** - * Converts a Leg to XBoxZone ... - * - * @param zone: XBoxZone, reference to holds Converted ... - * - * @return ( bool ) - */ - bool ToBox(XBoxZone &zone) - { - // - bool result = false; - - // - // Prepare ... - zone.Clean(); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - zone.at = time; - zone.dir = dir; - zone.from = time; - zone.upper = upper; - zone.lower = lower; - zone.symbol = symbol; - zone.period = period; - zone.to = TimeCurrent(); - zone.type = ToXString(X_BAR_PATTERN_LEG); - - // - result = zone.IsValid(); - - // - // Cleanup ... - if (!result) - { - zone.Clean(); - } - - // - return result; - } - - /** - * Update Times of Collections ... - * - * @param value: datetime, Specified Time ... - */ - void UpdateTimes(datetime value = NULL) - { - // - // Normalize ... - value = NormalizeTime(value); - - // - // Validate ... - if (!IsValid()) - { - return; - } - - // - UpdateToTime(supports, value); - UpdateToTime(resistances, value); - UpdateToTime(bullishFVGs, value); - UpdateToTime(bearishFVGs, value); - } - - // -}; - // // Extensions ... diff --git a/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 index c26f667d..19296d64 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 @@ -3335,6 +3335,82 @@ class XCXFIMAHelperParser : XCBase // // XATR ... + bool GetATRBox( + XBoxZone &zone, + int barIndex = 0, + int loopback = 3 // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double lowers[]; + double uppers[]; + double iUpper = EMPTY_VALUE; + double iLower = EMPTY_VALUE; + double upper = helper.GetATRRawBandUpper(barIndex); + double lower = helper.GetATRRawBandLower(barIndex); + int idx = barIndex; + while (idx <= barIndex + loopback) + { + // + idx++; + iUpper = helper.GetATRRawBandUpper(idx); + iLower = helper.GetATRRawBandLower(idx); + Add(iUpper, uppers); + Add(iLower, lowers); + } + + // + zone.symbol = symbol; + zone.period = period; + zone.upper = GetMax(uppers); + zone.lower = GetMin(lowers); + zone.dir = + (upper > zone.upper || + lower > zone.lower) + ? X_DIRECTION_BULLISH + : (upper < zone.upper || + lower < zone.lower) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + zone.type = ToXString(XFIMA_PIVOT_ATR); + zone.to = GetBarTime(symbol, period, barIndex); + zone.at = zone.to; + zone.from = GetBarTime(symbol, period, barIndex + loopback); + + // + result = zone.IsValid(); + + // + // Cleanup ... + if (!result) + { + zone.Clean(); + } + + // + return result; + } + /** * Check Price is Over ATR Band Lower ... * @@ -3533,10 +3609,10 @@ class XCXFIMAHelperParser : XCBase /** * Check Price is Crossed Over ATR Band Lower ... - * + * * @param barIndex: int, Specified Bar Index ... * @param priceType: ENUM_X_PRICE, Specified Price Type ... - * + * * @return ( bool ) */ bool IsCrossedOverATRBandLower( @@ -3572,10 +3648,10 @@ class XCXFIMAHelperParser : XCBase /** * Check Price is Crossed Under ATR Band Lower ... - * + * * @param barIndex: int, Specified Bar Index ... * @param priceType: ENUM_X_PRICE, Specified Price Type ... - * + * * @return ( bool ) */ bool IsCrossedUnderATRBandLower( @@ -3611,10 +3687,10 @@ class XCXFIMAHelperParser : XCBase /** * Check Price is Crossed Over ATR Band Upper ... - * + * * @param barIndex: int, Specified Bar Index ... * @param priceType: ENUM_X_PRICE, Specified Price Type ... - * + * * @return ( bool ) */ bool IsCrossedOverATRBandUpper( @@ -3650,10 +3726,10 @@ class XCXFIMAHelperParser : XCBase /** * Check Price is Crossed Under ATR Band Upper ... - * + * * @param barIndex: int, Specified Bar Index ... * @param priceType: ENUM_X_PRICE, Specified Price Type ... - * + * * @return ( bool ) */ bool IsCrossedUnderATRBandUpper( @@ -4047,6 +4123,152 @@ class XCXFIMAHelperParser : XCBase return result; } + /** + * Check Cycle MA Happens Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsSCMAOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetSCMA(barIndex); + double pValue = helper.GetSCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue > pValue; + + // + return result; + } + + /** + * Check Cycle MA Happens Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsSCMAUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetSCMA(barIndex); + double pValue = helper.GetSCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue < pValue; + + // + return result; + } + + /** + * Check Cycle MA Crossed Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsSCMACrossedOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsSCMAOverLast(barIndex); + bool isP = IsSCMAOverLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + + /** + * Check Cycle MA Crossed Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsSCMACrossedUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsSCMAUnderLast(barIndex); + bool isP = IsSCMAUnderLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + /** * Check Cycle Lows is Same ... * @@ -5166,6 +5388,152 @@ class XCXFIMAHelperParser : XCBase return result; } + /** + * Check Cycle MA Happens Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsMCMAOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetMCMA(barIndex); + double pValue = helper.GetMCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue > pValue; + + // + return result; + } + + /** + * Check Cycle MA Happens Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsMCMAUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetMCMA(barIndex); + double pValue = helper.GetMCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue < pValue; + + // + return result; + } + + /** + * Check Cycle MA Crossed Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsMCMACrossedOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsMCMAOverLast(barIndex); + bool isP = IsMCMAOverLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + + /** + * Check Cycle MA Crossed Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsMCMACrossedUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsMCMAUnderLast(barIndex); + bool isP = IsMCMAUnderLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + /** * Check Cycle Lows is Same ... * @@ -6285,6 +6653,152 @@ class XCXFIMAHelperParser : XCBase return result; } + /** + * Check Cycle MA Happens Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsLCMAOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetLCMA(barIndex); + double pValue = helper.GetLCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue > pValue; + + // + return result; + } + + /** + * Check Cycle MA Happens Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsLCMAUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetLCMA(barIndex); + double pValue = helper.GetLCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue < pValue; + + // + return result; + } + + /** + * Check Cycle MA Crossed Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsLCMACrossedOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsLCMAOverLast(barIndex); + bool isP = IsLCMAOverLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + + /** + * Check Cycle MA Crossed Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsLCMACrossedUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsLCMAUnderLast(barIndex); + bool isP = IsLCMAUnderLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + /** * Check Cycle Lows is Same ... * @@ -7404,6 +7918,152 @@ class XCXFIMAHelperParser : XCBase return result; } + /** + * Check Cycle MA Happens Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsHCMAOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetHCMA(barIndex); + double pValue = helper.GetHCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue > pValue; + + // + return result; + } + + /** + * Check Cycle MA Happens Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsHCMAUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double cValue = helper.GetHCMA(barIndex); + double pValue = helper.GetHCMA(barIndex + 1); + + // + result = + NotEmptyZero(cValue) && + NotEmptyZero(pValue) && + cValue < pValue; + + // + return result; + } + + /** + * Check Cycle MA Crossed Over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsHCMACrossedOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsHCMAOverLast(barIndex); + bool isP = IsHCMAOverLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + + /** + * Check Cycle MA Crossed Under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsHCMACrossedUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isC = IsHCMAUnderLast(barIndex); + bool isP = IsHCMAUnderLast(barIndex + 1); + + // + result = isC && !isP; + + // + return result; + } + /** * Check Cycle Lows is Same ... * @@ -9209,112 +9869,6 @@ class XCXFIMAHelperParser : XCBase // // Other Tools ... - int CollectPivots( - XPivot &pivots[], - int barIndex = 0, - int loopback = 500 // - ) - { - // - int result = 0; - - // - // Prepare ... - XClean(pivots); - - // - // Normalize ... - loopback = NormalizeInt(loopback, 50); - barIndex = NormalizeBarIndex(barIndex); - - // - // Validate ... - bool has = IsValid(); - if (!has) - { - return result; - } - - // - has = false; - XOHCL tmpBar; - XPivot tmpPivot; - double tmpValue; - datetime tmpTime; - bool isBullish = false; - bool isBearish = false; - string tmpSymbol = symbol; - ENUM_TIMEFRAMES tmpPeriod = period; - ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - tmpBar.Clean(); - tmpPivot.Clean(); - - // - has = tmpBar.Init(tmpSymbol, tmpPeriod, i); - if (!has) - { - continue; - } - - // - // XSAR ... - isBullish = IsSARSwitchedToBullish(i); - isBearish = IsSARSwitchedToBearish(i); - has = isBullish || isBearish; - if (has) - { - } - - // - // XMA Fast / Slow ... - - // - // States ... - isBullish = IsMASlowSwitchedToBullish(i); - isBearish = IsMASlowSwitchedToBearish(i); - has = isBullish || isBearish; - if (has) - { - } - - // - // Crossed Fast Slow ... - isBullish = IsMAFastCrossedOverSlow(i); - isBearish = IsMAFastCrossedUnderSlow(i); - has = isBullish || isBearish; - if (has) - { - } - - // - // Crossed Last ... - isBullish = IsMASlowCrossedOverLast(i); - isBearish = IsMASlowCrossedUnderLast(i); - has = isBullish || isBearish; - if (has) - { - } - - // - // XHK ... - isBullish = IsHKSwitchedToBullish(i); - isBearish = IsHKSwitchedToBearish(i); - has = isBullish || isBearish; - if (has) - { - } - } - - // - result = ArraySize(pivots); - - // - return result; - } - // // Protected ... protected: diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index e20baed2..875d3fe7 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -284,7 +284,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller { // // Configure ... - drawLeg = false; drawZones = false; drawIZones = false; drawTrends = false; @@ -299,7 +298,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller drawIResistance = false; // - manageLegs = true; manageZones = true; manageIZones = true; manageTrends = false; @@ -615,7 +613,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } // - ManageLeg(bar); ManageTrends(bar); ManageZones(p2Bar); ManageIZones(p2Bar); @@ -634,130 +631,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // // Props ... - // - // Leg ... - - XLeg leg; // Exists Leg ... - bool drawLeg; // Draw Leg ... - bool manageLegs; - - // - bool HasLeg() - { - return leg.IsValid(); - } - - // - bool ValidateLeg(XOHCL &bar) - { - // - bool result = false; - - // - result = HasLeg() && - bar.IsValid(); - if (!result) - { - return result; - } - - // - result = - leg.IsBullish() - ? bar.low > leg.lower - : leg.IsBearish() - ? bar.high < leg.upper - : false; - - // - return result; - } - - // - void DrawLeg() - { - // - if (!drawLeg) - { - return; - } - - // - if (!HasLeg()) - { - return; - } - - // - // Update to Times ... - leg.UpdateTimes(); - - // - // Draw Leg Box ... - XBoxZone legZone; - leg.ToBox(legZone); - if (legZone.IsValid()) - { - // - legZone.to = TimeCurrent(); - poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig); - } - - // - // Draw Legs Other Stufs ... - return; - - // - // FVGs ... - poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig); - poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig); - - // - // Support and Resistances ... - poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig); - poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig); - - // - // Patterns ... - poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig); - } - - // - void ManageLeg(XOHCL &bar) - { - // - // Validate Exists ... - if (HasLeg()) - { - // - if (!ValidateLeg(bar)) - { - // - // Invalidate XLeg ... - leg.Clean(); - } - } - - // - // Detect New ... - if (!HasLeg()) - { - poiDetector.IsLegPattern(bar, leg); - } - - // - // Update Exists ... - if (HasLeg()) - { - // - // Update to Times ... - leg.UpdateTimes(); - - // - DrawLeg(); - } - } - // // Order Flow ... @@ -1564,10 +1437,10 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // // Signaller Flags ... - bool useSignaller1 = false; - bool useSignaller2 = true; - bool useSignaller3 = true; - bool useSignaller4 = true; + bool useSignaller1 = true; + bool useSignaller2 = false; + bool useSignaller3 = false; + bool useSignaller4 = false; // XBoxZone tmpZone; @@ -1601,7 +1474,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XPOIDrawConfig iDrawConfig; // - drawLeg = false; drawZones = false; drawIZones = false; drawTrends = false; @@ -2050,11 +1922,29 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XOHCL pBar; XOHCL p2Bar; XOHCL p3Bar; + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone atrBox; + XBoxZone tmpZone; + XBoxZone scPVZone; + XBoxZone mcPVZone; + XBoxZone lcPVZone; + XBoxZone hcPVZone; + XBoxZone pinBarZone; + XBoxZone supports[]; + XBoxZone resistances[]; + XBoxZone affectedZone; + XTrend pinBarZoneTrend; bool isBullish = false; bool isBearish = false; + ENUM_X_DIRECTION tmpDir; + XPatternAnalysis pBarPatterns; + XPatternAnalysis p2BarPatterns; + XPatternAnalysis p3BarPatterns; + XPatternAnalysisConfig iPatternsConfig; // - // Read PBar ... + // Reading Bars ... result = bar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); @@ -2072,22 +1962,47 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } // - // Reading pBar Patterns ... - XPatternAnalysis pBarPatterns; - poiDetector.AnalyseBarPatterns( - pBar, - pBarPatterns, - structureConfig.barsAnalysisConfig // - ); - bool hasSupport = pBarPatterns.IsSupport(); - bool hasResistance = pBarPatterns.IsResistance(); + // Reading Bar Patterns ... + iPatternsConfig.Default(); + iPatternsConfig.FullPattern(); + result = + result && + poiDetector.AnalyseBarPatterns( + pBar, + pBarPatterns, + iPatternsConfig // + ); + result = + result && + poiDetector.AnalyseBarPatterns( + p2Bar, + p2BarPatterns, + iPatternsConfig // + ); + result = + result && + poiDetector.AnalyseBarPatterns( + p3Bar, + p3BarPatterns, + iPatternsConfig // + ); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + pBarPatterns.Clean(); + p2BarPatterns.Clean(); + p3BarPatterns.Clean(); + iPatternsConfig.Clean(); + + // + return result; + } // - // Check Boundary Trend ... - XTrend boundaryTrend; - bool hasBoundaryTrend = fimaParser.HasBoundaryTrend(boundaryTrend, pBar.Index()); - bool hasBoundaryBullishTrend = hasBoundaryTrend && boundaryTrend.IsBullish(); - bool hasBoundaryBearishTrend = hasBoundaryTrend && boundaryTrend.IsBearish(); + // Detect Directional Candlestic Patterns ... // // Bullish ... @@ -2103,6 +2018,30 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH) // ); + bool isP2BarHasBullishPatterns = + (bar.close > p2Bar.low || + bar.open > p2Bar.low) && + ( + // + p2BarPatterns.IsPinned(X_DIRECTION_BULLISH) || + p2BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + p2BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + p2BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + p2BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isP3BarHasBullishPatterns = + (bar.close > p3Bar.low || + bar.open > p3Bar.low) && + ( + // + p3BarPatterns.IsPinned(X_DIRECTION_BULLISH) || + p3BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + p3BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + p3BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + p3BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); // // Bearish ... @@ -2118,80 +2057,211 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH) // ); + bool isP2BarHasBearishPatterns = + (bar.close < p2Bar.high || + bar.open < p2Bar.high) && + ( + // + p2BarPatterns.IsPinned(X_DIRECTION_BEARISH) || + p2BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + p2BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + p2BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + p2BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + bool isP3BarHasBearishPatterns = + (bar.close < p3Bar.high || + bar.open < p3Bar.high) && + ( + // + p3BarPatterns.IsPinned(X_DIRECTION_BEARISH) || + p3BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + p3BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + p3BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + p3BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); // - // Check Pull Back Pattern ... - XBoxZone pullbackZone; - ENUM_X_DIRECTION pullbackDir; - bool isPullback = poiDetector.IsPullbackPattern( - pBar, - pullbackZone, - pullbackDir // - ); - bool isBullishPullback = isPullback && IsXBullish(pullbackDir); - bool isBearishPullback = isPullback && IsXBearish(pullbackDir); + // Checking Support and Resistances ... // - // Force P2Bar is Pin Bar ... - ENUM_X_DIRECTION p2Dir; - bool isP2BarPinned = poiDetector.IsPinnedBar( - p2Bar, - p2Dir // - ); - bool isP2BarBullishPinned = - isP2BarPinned && - IsXBullish(p2Dir); - bool isP2BarBearishPinned = - isP2BarPinned && - IsXBearish(p2Dir); - - // - // Checking For Leg Pattern ... - XLeg _leg; - XBoxZone legZone; - bool hasLeg = poiDetector.IsLegPattern( - pBar, - _leg, - 3, - 100 // - ); - if (hasLeg) + // Support ... + bool hasSupport = pBarPatterns.IsSupport(); + if (hasSupport) { - hasLeg = _leg.ToBox(legZone); + // + hasSupport = pBarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p2BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p3BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p3BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } } - bool hasBullishLeg = hasLeg && _leg.IsBullish(); - bool hasBearishLeg = hasLeg && _leg.IsBearish(); // - // Check Based On LC and HC MA State ... + // Resistance ... + bool hasResistance = pBarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = pBarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p2BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p3BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p3BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } // - bool isLCMABullish = fimaParser.IsLCMABullish(pBar.Index()); - bool isHCMABullish = fimaParser.IsHCMABullish(pBar.Index()); - bool isCycleMABullish = isLCMABullish && isHCMABullish; + // Reading Cycle PVS ... + bool hasSCPV = poiDetector.GetSCZone(pBar, scPVZone); + bool hasMCPV = poiDetector.GetMCZone(pBar, mcPVZone); + bool hasLCPV = poiDetector.GetLCZone(pBar, lcPVZone); + bool hasHCPV = poiDetector.GetHCZone(pBar, hcPVZone); + bool isCyclePVBullish = + hasMCPV && mcPVZone.IsBullish() && + hasLCPV && lcPVZone.IsBullish() && + hasHCPV && hcPVZone.IsBullish(); + bool isCyclePVBearish = + hasMCPV && mcPVZone.IsBearish() && + hasLCPV && lcPVZone.IsBearish() && + hasHCPV && hcPVZone.IsBearish(); // - bool isLCMABearish = fimaParser.IsLCMABearish(pBar.Index()); - bool isHCMABearish = fimaParser.IsHCMABearish(pBar.Index()); - bool isCycleMABearish = isLCMABearish && isHCMABearish; + // Validating Market Direction ... + // by Checking HC and LC States ... // + bool isLCBullish = fimaParser.IsLCMABullish(pBar.Index()); + bool isHCBullish = fimaParser.IsHCMABullish(pBar.Index()); + bool isLCHigherLow = + (fimaParser.IsLCHigherLow(pBar.Index()) || + fimaParser.IsLCHigherLow(p2Bar.Index()) || + fimaParser.IsLCHigherLow(p3Bar.Index())); + bool isCyclesBullish = + isLCBullish && + isHCBullish && + isLCHigherLow; + // + bool isLCBearish = fimaParser.IsLCMABearish(pBar.Index()); + bool isHCBearish = fimaParser.IsHCMABearish(pBar.Index()); + bool isLCLowerHigh = + (fimaParser.IsLCLowerHigh(pBar.Index()) || + fimaParser.IsLCLowerHigh(p2Bar.Index()) || + fimaParser.IsLCLowerHigh(p3Bar.Index())); + bool isCyclesBearish = + isLCBearish && + isHCBearish && + isLCLowerHigh; + // + // Looking For a Pin Bar in P2Bar ... + bool isP2BarIsPinBar = poiDetector.IsPinnedBar( + p2Bar, + tmpDir, + 4, // Shadow Multiplier ... + 4, // Minimum Range Multiplier ... + true // Force Pin Bar Direction ... + ); + if (isP2BarIsPinBar) + { + // + isP2BarIsPinBar = ToBox( + p2Bar, + pinBarZone, + tmpDir, + X_BAR_PATTERN_PINNED // + ); + if (isP2BarIsPinBar) + { + // + pinBarZone.to = bar.time; + isP2BarIsPinBar = poiDetector.HasBoundaryTrend( + pinBarZone, + pinBarZoneTrend, + false // + ); + isP2BarIsPinBar = + isP2BarIsPinBar && + tmpDir == pinBarZoneTrend.dir; + } + } + bool isP2BarPinnedBullish = isP2BarIsPinBar && IsXBullish(tmpDir); + bool isP2BarPinnedBearish = isP2BarIsPinBar && IsXBearish(tmpDir); + + // + bool hasATRBox = fimaParser.GetATRBox( + atrBox, + bar.Index() // + ); // isBullish = - hasBullishLeg && - isCycleMABullish && - isBullishPullback && - isP2BarBullishPinned; + // + hasSupport && + hasResistance && + isCyclesBullish && + isCyclePVBullish && + isP2BarPinnedBullish && + isPBarHasBullishPatterns && + isP2BarHasBullishPatterns && + true + // + ; // isBearish = - hasBearishLeg && - isCycleMABearish && - isBearishPullback && - isP2BarBearishPinned; + // + hasSupport && + hasResistance && + isCyclesBearish && + isCyclePVBearish && + isP2BarPinnedBearish && + isPBarHasBearishPatterns && + isP2BarHasBearishPatterns && + true + // + ; // // Validate ... @@ -2215,37 +2285,61 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller { // zone.Clean(); - zone = pullbackZone; - - // - // Draws ... - if (result) - { - // - XPOIDrawConfig iConfig = structureDrawConfig.drawConfig; - iConfig.trendRayLeft = false; - iConfig.trendRayRight = false; - - // - poiDrawer.DrawZone(legZone, iConfig); - poiDrawer.DrawZone(pullbackZone, iConfig); - - // - // poiDrawer.DrawTrendLine(boundaryTrend, iConfig); - // poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig); - poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig); - - // - iConfig.Clean(); - - // - DebugBreak(); - } + zone = pinBarZone; // result = zone.IsValid(); } + // + // Draws ... + if (result) + { + // + XPOIDrawConfig iConfig = structureDrawConfig.drawConfig; + XPatternAnalysisDrawConfig iPatternsConfig = structureDrawConfig.barAnalysisDrawConfig; + iConfig.trendRayLeft = false; + iConfig.trendRayRight = false; + + // + // poiDrawer.DrawZone(scPVZone, iConfig); + // poiDrawer.DrawZone(mcPVZone, iConfig); + // poiDrawer.DrawZone(lcPVZone, iConfig); + // poiDrawer.DrawZone(hcPVZone, iConfig); + + // + poiDrawer.DrawPatternAnalysis(pBarPatterns, iPatternsConfig); + poiDrawer.DrawPatternAnalysis(p2BarPatterns, iPatternsConfig); + poiDrawer.DrawPatternAnalysis(p3BarPatterns, iPatternsConfig); + + // + poiDrawer.DrawZone(pinBarZone, iConfig); + poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig); + + // + poiDrawer.DrawZones(supports, iConfig); + poiDrawer.DrawZones(resistances, iConfig); + + // + if (hasATRBox) + { + poiDrawer.DrawZone(atrBox, iConfig); + } + + // + iConfig.Clean(); + iPatternsConfig.Clean(); + + // + DebugBreak(); + + // // + // result = false; + // isBullish = false; + // isBearish = false; + // zone.Clean(); + } + // // Prepare Targets ... if (result) @@ -2264,9 +2358,22 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); - pullbackZone.Clean(); + tmpBar.Clean(); + tmpZone.Clean(); + XClean(supports); + scPVZone.Clean(); + mcPVZone.Clean(); + lcPVZone.Clean(); + hcPVZone.Clean(); + tmpPivot.Clean(); + pinBarZone.Clean(); + XClean(resistances); + affectedZone.Clean(); pBarPatterns.Clean(); - boundaryTrend.Clean(); + p2BarPatterns.Clean(); + p3BarPatterns.Clean(); + pinBarZoneTrend.Clean(); + iPatternsConfig.Clean(); // return result; 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 222f78d8..9d46f098 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -34,11 +34,12 @@ enum ENUM_XFIMA_PIVOTS { XFIMA_PIVOT_NONE = 0, XFIMA_PIVOT_PV = 1, - XFIMA_PIVOT_ZIGZAG = 2, - XFIMA_PIVOT_MA_CROSS = 3, - XFIMA_PIVOT_HK_SWITCH = 4, - XFIMA_PIVOT_SAR_SWITCH = 5, - XFIMA_PIVOT_BOUNDARY_SWITCH = 6, + XFIMA_PIVOT_ATR = 2, + XFIMA_PIVOT_ZIGZAG = 3, + XFIMA_PIVOT_MA_CROSS = 4, + XFIMA_PIVOT_HK_SWITCH = 5, + XFIMA_PIVOT_SAR_SWITCH = 6, + XFIMA_PIVOT_BOUNDARY_SWITCH = 7, }; bool IsXValid(ENUM_XFIMA_PIVOTS value) @@ -77,6 +78,11 @@ string ToXString(ENUM_XFIMA_PIVOTS value) result = "XPV"; break; + // + case XFIMA_PIVOT_ATR: + result = "XATR"; + break; + // case XFIMA_PIVOT_ZIGZAG: result = "XZGP"; @@ -127,6 +133,10 @@ ENUM_XFIMA_PIVOTS ToXFIMAPivots(string value) { result = XFIMA_PIVOT_PV; } + else if (value == ToXString(XFIMA_PIVOT_ATR)) + { + result = XFIMA_PIVOT_ATR; + } else if (value == ToXString(XFIMA_PIVOT_ZIGZAG)) { result = XFIMA_PIVOT_ZIGZAG; @@ -1785,6 +1795,282 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector return result; } + /** + * Get Cycle Based PV Zone ... + * + * @param bar: XOHCL, reference to Specified Zone ... + * @param zone: XBoxZone, reference to holds PV Zone ... + * + * @return ( bool ) + */ + bool GetSCZone( + XOHCL &bar, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int barIndex = bar.Index(); + + // + double upper = fimaHelper.GetSHH(barIndex); + double lower = fimaHelper.GetSLL(barIndex); + double pHH = fimaHelper.GetSHH(barIndex + 1); + double pLL = fimaHelper.GetSLL(barIndex + 1); + int sameLLs = fimaParser.CountSCSameLLs(barIndex); + int sameHHs = fimaParser.CountSCSameHHs(barIndex); + int fromIDX = barIndex + MathMax(sameLLs, sameHHs); + + // + zone.to = bar.time; + zone.at = bar.time; + zone.upper = upper; + zone.lower = lower; + zone.symbol = bar.symbol; + zone.period = bar.period; + zone.dir = + (upper > pHH || + lower > pLL) + ? X_DIRECTION_BULLISH + : (upper < pHH || + lower < pLL) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + zone.type = ToXString(XFIMA_PIVOT_PV) + "_SC"; + zone.from = GetBarTime(bar.symbol, bar.period, fromIDX); + + // + result = zone.IsValid(); + if (!result) + { + zone.Clean(); + } + + // + return result; + } + + /** + * Get Cycle Based PV Zone ... + * + * @param bar: XOHCL, reference to Specified Zone ... + * @param zone: XBoxZone, reference to holds PV Zone ... + * + * @return ( bool ) + */ + bool GetMCZone( + XOHCL &bar, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int barIndex = bar.Index(); + + // + double upper = fimaHelper.GetMHH(barIndex); + double lower = fimaHelper.GetMLL(barIndex); + double pHH = fimaHelper.GetMHH(barIndex + 1); + double pLL = fimaHelper.GetMLL(barIndex + 1); + int sameLLs = fimaParser.CountMCSameLLs(barIndex); + int sameHHs = fimaParser.CountMCSameHHs(barIndex); + int fromIDX = barIndex + MathMax(sameLLs, sameHHs); + + // + zone.to = bar.time; + zone.at = bar.time; + zone.upper = upper; + zone.lower = lower; + zone.symbol = bar.symbol; + zone.period = bar.period; + zone.dir = + (upper > pHH || + lower > pLL) + ? X_DIRECTION_BULLISH + : (upper < pHH || + lower < pLL) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + zone.type = ToXString(XFIMA_PIVOT_PV) + "_MC"; + zone.from = GetBarTime(bar.symbol, bar.period, fromIDX); + + // + result = zone.IsValid(); + if (!result) + { + zone.Clean(); + } + + // + return result; + } + + /** + * Get Cycle Based PV Zone ... + * + * @param bar: XOHCL, reference to Specified Zone ... + * @param zone: XBoxZone, reference to holds PV Zone ... + * + * @return ( bool ) + */ + bool GetLCZone( + XOHCL &bar, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int barIndex = bar.Index(); + + // + double upper = fimaHelper.GetLHH(barIndex); + double lower = fimaHelper.GetLLL(barIndex); + double pHH = fimaHelper.GetLHH(barIndex + 1); + double pLL = fimaHelper.GetLLL(barIndex + 1); + int sameLLs = fimaParser.CountLCSameLLs(barIndex); + int sameHHs = fimaParser.CountLCSameHHs(barIndex); + int fromIDX = barIndex + MathMax(sameLLs, sameHHs); + + // + zone.to = bar.time; + zone.at = bar.time; + zone.upper = upper; + zone.lower = lower; + zone.symbol = bar.symbol; + zone.period = bar.period; + zone.dir = + (upper > pHH || + lower > pLL) + ? X_DIRECTION_BULLISH + : (upper < pHH || + lower < pLL) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + zone.type = ToXString(XFIMA_PIVOT_PV) + "_LC"; + zone.from = GetBarTime(bar.symbol, bar.period, fromIDX); + + // + result = zone.IsValid(); + if (!result) + { + zone.Clean(); + } + + // + return result; + } + + /** + * Get Cycle Based PV Zone ... + * + * @param bar: XOHCL, reference to Specified Zone ... + * @param zone: XBoxZone, reference to holds PV Zone ... + * + * @return ( bool ) + */ + bool GetHCZone( + XOHCL &bar, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int barIndex = bar.Index(); + + // + double upper = fimaHelper.GetHHH(barIndex); + double lower = fimaHelper.GetHLL(barIndex); + double pHH = fimaHelper.GetHHH(barIndex + 1); + double pLL = fimaHelper.GetHLL(barIndex + 1); + int sameLLs = fimaParser.CountHCSameLLs(barIndex); + int sameHHs = fimaParser.CountHCSameHHs(barIndex); + int fromIDX = barIndex + MathMax(sameLLs, sameHHs); + + // + zone.to = bar.time; + zone.at = bar.time; + zone.upper = upper; + zone.lower = lower; + zone.symbol = bar.symbol; + zone.period = bar.period; + zone.dir = + (upper > pHH || + lower > pLL) + ? X_DIRECTION_BULLISH + : (upper < pHH || + lower < pLL) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + zone.type = ToXString(XFIMA_PIVOT_PV) + "_HC"; + zone.from = GetBarTime(bar.symbol, bar.period, fromIDX); + + // + result = zone.IsValid(); + if (!result) + { + zone.Clean(); + } + + // + return result; + } + // // Others ...