From 31232dffef7e0be08f7e7fffb27beb089833ae8c Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 7 Jan 2026 04:27:38 +0330 Subject: [PATCH] some cleanups, refactor unnecessary requirements, implement rejected checkers and also counters ... ass support for PV and KISuperSlow and MASuper Slow in KI Indicator and also Helper and implement them in BackTester ... --- Documents/BKP/X121XKI/tmp.poi.mq5 | 1194 ++++++++ Documents/BKP/X121XKI/tmp.signaller.mq5 | 320 ++ Documents/BKP/X121XKI/tmp.zones.poi.mq5 | 458 +++ Experts/x-saherelm.x121.xki.backtester.ea.mq5 | 28 +- Helpers/x-saherelm.x121.xki.helper.mq5 | 322 +- Indicators/x-saherelm.x121.xki.mq5 | 421 ++- .../x-saherelm.x121.xki.parser.class.mq5 | 1550 +++++++++- .../x-saherelm.x121.xki.signaller.class.mq5 | 365 +-- ...saherelm.x121.xki.x-poi.detector.class.mq5 | 2661 +++++++---------- 9 files changed, 5354 insertions(+), 1965 deletions(-) create mode 100644 Documents/BKP/X121XKI/tmp.poi.mq5 create mode 100644 Documents/BKP/X121XKI/tmp.signaller.mq5 create mode 100644 Documents/BKP/X121XKI/tmp.zones.poi.mq5 diff --git a/Documents/BKP/X121XKI/tmp.poi.mq5 b/Documents/BKP/X121XKI/tmp.poi.mq5 new file mode 100644 index 00000000..1d723195 --- /dev/null +++ b/Documents/BKP/X121XKI/tmp.poi.mq5 @@ -0,0 +1,1194 @@ + + // #region XDetectors ... + bool IsKIPOI( + ENUM_X_DIRECTION &dir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + bool isBullish = IsKIBullishPOI(barIndex); + bool isBearish = IsKIBearishPOI(barIndex); + + // + dir = isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + return result; + } + + bool IsKIBullishPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = + kiParser.IsValid() && + kiParser.IsKISlowBullish(barIndex) && + kiParser.IsKIFastBearish(barIndex); + + // + return result; + } + + bool IsKIBearishPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = + kiParser.IsValid() && + kiParser.IsKISlowBearish(barIndex) && + kiParser.IsKIFastBullish(barIndex); + + // + return result; + } + + bool IsKISignal( + ENUM_X_DIRECTION &dir, // + int barIndex = 0 // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Retrieve KI State ... + bool isBullish = kiParser.IsKIFastSwitchedToBullish(barIndex + 1) && + kiParser.IsKIFastBullish(barIndex) && + kiParser.IsKISlowBullish(barIndex); + bool isBearish = kiParser.IsKIFastSwitchedToBearish(barIndex + 1) && + kiParser.IsKIFastBearish(barIndex) && + kiParser.IsKISlowBearish(barIndex); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + dir = isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(dir); + if (!result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init(symbol, period, barIndex + 1); + if (!result) + { + return result; + } + + // + // Bar Direction Same as Dir ... + + // + // Price Place Check ... + double kiFast = kiHelper.GetKIFast(barIndex + 1); + double kiSlow = kiHelper.GetKISlow(barIndex + 1); + isBullish = + isBullish && + bar.close > kiFast && + kiFast > kiSlow && + (kiParser.IsKIFastOverLast(barIndex + 1) || + kiParser.IsKISlowOverLast(barIndex + 1)); + isBearish = + isBearish && + bar.close < kiFast && + kiFast < kiSlow && + (kiParser.IsKIFastUnderLast(barIndex + 1) || + kiParser.IsKISlowUnderLast(barIndex + 1)); + + // + result = + result && + (isBullish || + isBearish); + + // + // Cleanup Resources ... + bar.Clean(); + + // + return result; + } + // #endregion + + + // #region Detectors ... + bool IsPOI( + ENUM_X_DIRECTION &forDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + forDir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = IsBullishPOI(barIndex); + bool isBearish = IsBearishPOI(barIndex); + result = isBullish || isBearish; + if (!result) + { + return result; + } + + // + forDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(forDir); + + // + return result; + } + + bool IsBullishPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsTrendBullish(barIndex) && + kiParser.IsRSIBullish(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BULLISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsBearishPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsTrendBearish(barIndex) && + kiParser.IsRSIBearish(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BEARISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsBreakoutPOI( + ENUM_X_DIRECTION &forDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + forDir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = IsBullishBreakoutPOI(barIndex); + bool isBearish = IsBearishBreakoutPOI(barIndex); + result = isBullish || isBearish; + if (!result) + { + return result; + } + + // + forDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(forDir); + + // + return result; + } + + bool IsBullishBreakoutPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsBullishBreakout(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BULLISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsBearishBreakoutPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsBearishBreakout(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BEARISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsReversalPOI( + ENUM_X_DIRECTION &forDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + forDir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = IsBullishReversalPOI(barIndex); + bool isBearish = IsBearishReversalPOI(barIndex); + result = isBullish || isBearish; + if (!result) + { + return result; + } + + // + forDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(forDir); + + // + return result; + } + + bool IsBullishReversalPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsBullishReversal(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BULLISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsBearishReversalPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsBearishReversal(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BEARISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsContinuationPOI( + ENUM_X_DIRECTION &forDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + forDir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = IsBullishContinuationPOI(barIndex); + bool isBearish = IsBearishContinuationPOI(barIndex); + result = isBullish || isBearish; + if (!result) + { + return result; + } + + // + forDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(forDir); + + // + return result; + } + + bool IsBullishContinuationPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsTrendStrongBullish(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + ENUM_X_DIRECTION dir; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + XOHCL swingBar; + result = result && + IsFlagPattern(bar, dir, swingBar) && + IsXBullish(dir); + + // + bar.Clean(); + swingBar.Clean(); + + // + return result; + } + + bool IsBearishContinuationPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + result = kiParser.IsTrendStrongBearish(barIndex); + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + ENUM_X_DIRECTION dir; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + XOHCL swingBar; + result = result && + IsFlagPattern(bar, dir, swingBar) && + IsXBearish(dir); + + // + bar.Clean(); + swingBar.Clean(); + + // + return result; + } + + bool IsExhaustionPOI( + ENUM_X_DIRECTION &forDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + forDir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = IsBullishExhaustionPOI(barIndex); + bool isBearish = IsBearishExhaustionPOI(barIndex); + result = isBullish || isBearish; + if (!result) + { + return result; + } + + // + forDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(forDir); + + // + return result; + } + + bool IsBullishExhaustionPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isTrendOk = kiParser.IsTrendStrongBullish(barIndex); + bool isRSIOk = kiParser.IsRSIOverbought(barIndex); + result = isTrendOk && isRSIOk; + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BEARISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsBearishExhaustionPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isTrendOk = kiParser.IsTrendStrongBearish(barIndex); + bool isRSIOk = kiParser.IsRSIOversold(barIndex); + result = isTrendOk && isRSIOk; + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BULLISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsTrendExhaustedPOI( + ENUM_X_DIRECTION &forDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + forDir = X_DIRECTION_NONE; + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = IsBullishTrendExhaustedPOI(barIndex); + bool isBearish = IsBearishTrendExhaustedPOI(barIndex); + result = isBullish || isBearish; + if (!result) + { + return result; + } + + // + forDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + result = HasDirection(forDir); + + // + return result; + } + + bool IsBullishTrendExhaustedPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Trend was strong in last 3 bars ... + bool isTrendOk = kiParser.IsTrendStrongBullish(barIndex + 1); + for (int i = 1; i <= 3; i++) + { + // + if (kiParser.IsTrendStrongBullish(barIndex + i)) + { + isTrendOk = true; + break; + } + } + + // + // RSI rolling over from overbought ... + double rsiNow = kiHelper.GetRSI(barIndex); + double rsiPrev = kiHelper.GetRSI(barIndex + 1); + bool rsiFlip = (rsiPrev > 70 && rsiNow < rsiPrev); + bool isRSIOk = rsiFlip || kiParser.IsRSIOverbought(barIndex); + + // + bool volCooling = kiHelper.GetATR(barIndex) <= kiHelper.GetATRSmoothed(barIndex) * 1.05; + bool isVolatilityOk = volCooling || kiParser.IsVolatilityLow(barIndex); + + // + result = isRSIOk && + isTrendOk && + isVolatilityOk; + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BEARISH // + ); + + // + bar.Clean(); + + // + return result; + } + + bool IsBearishTrendExhaustedPOI(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isTrendOk = kiParser.IsTrendStrongBearish(barIndex + 1); + for (int i = 1; i <= 3; i++) + { + // + if (kiParser.IsTrendStrongBearish(barIndex + i)) + { + isTrendOk = true; + break; + } + } + + // + // RSI rolling over from overbought ... + double rsiNow = kiHelper.GetRSI(barIndex); + double rsiPrev = kiHelper.GetRSI(barIndex + 1); + bool rsiFlip = (rsiPrev < 30 && rsiNow > rsiPrev); + bool isRSIOk = rsiFlip || kiParser.IsRSIOversold(barIndex); + + // + bool volCooling = kiHelper.GetATR(barIndex) <= kiHelper.GetATRSmoothed(barIndex) * 1.05; + bool isVolatilityOk = volCooling || kiParser.IsVolatilityLow(barIndex); + + // + result = isRSIOk && + isTrendOk && + isVolatilityOk; + if (!result) + { + return result; + } + + // + // Add candlestick confirmation ... + XOHCL bar; + result = result && + bar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = result && + HasCandlestickDirection( + bar, + X_DIRECTION_BULLISH // + ); + + // + bar.Clean(); + + // + return result; + } + // #endregion + + // #region POI Detectors ... + bool NearestKIFastBullish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKIFastBullish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKIFastBearish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKIFastBearish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKIFastSwitchedToBullish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKIFastSwitchedToBullish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKIFastSwitchedToBearish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKIFastSwitchedToBearish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKISlowBullish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKISlowBullish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKISlowBearish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKISlowBearish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKISlowSwitchedToBullish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKISlowSwitchedToBullish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool NearestKISlowSwitchedToBearish( + int &index, + int barIndex = 0, + int loopback = 50 // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Normalize ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + // Loop Back ... + bool isPassed = false; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + isPassed = kiParser.IsKISlowSwitchedToBearish(i); + if (isPassed) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + // #endregion diff --git a/Documents/BKP/X121XKI/tmp.signaller.mq5 b/Documents/BKP/X121XKI/tmp.signaller.mq5 new file mode 100644 index 00000000..fba53776 --- /dev/null +++ b/Documents/BKP/X121XKI/tmp.signaller.mq5 @@ -0,0 +1,320 @@ + + // #region Signals ... + + // #region POI ... + bool IsBullishPOILongEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + // IMPORTANT: Use near Support/Resistance ... + bool result = poiDetector.IsBullishPOI(barIndex) && + kiParser.IsSafeBullishEntry(barIndex) && + IsTFBullishPattern(barIndex, lowerTF); + + // + return result; + } + + bool IsBearishPOIShortEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + // IMPORTANT: Use near Support/Resistance ... + bool result = poiDetector.IsBearishPOI(barIndex) && + kiParser.IsSafeBearishEntry(barIndex) && + IsTFBearishPattern(barIndex, lowerTF); + + // + return result; + } + + bool ExitBullishPOILong(int barIndex = 0) + { + // + bool result = + poiDetector.IsBearishReversalPOI(barIndex) || + poiDetector.IsBearishBreakoutPOI(barIndex) || + poiDetector.IsBearishExhaustionPOI(barIndex); + + // + return result; + } + + bool ExitBearishPOIShort(int barIndex = 0) + { + // + bool result = + poiDetector.IsBullishReversalPOI(barIndex) || + poiDetector.IsBullishBreakoutPOI(barIndex) || + poiDetector.IsBullishExhaustionPOI(barIndex); + + // + return result; + } + // #endregion + + // #region Breakout ... + bool IsBreakoutLongEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = false; + + // + result = + kiParser.IsVolatilityHigh(barIndex) && + IsTFBullishPattern(barIndex, lowerTF) && + poiDetector.IsBullishBreakoutPOI(barIndex); + + // + return result; + } + + bool IsBreakoutShortEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = false; + + // + result = + kiParser.IsVolatilityHigh(barIndex) && + IsTFBearishPattern(barIndex, lowerTF) && + poiDetector.IsBearishBreakoutPOI(barIndex); + + // + return result; + } + + bool ExitBreakoutLong(int barIndex = 0) + { + // + bool result = + poiDetector.IsBearishReversalPOI(barIndex) || + poiDetector.IsBearishExhaustionPOI(barIndex); + + // + return result; + } + + bool ExitBreakoutShort(int barIndex = 0) + { + // + bool result = + poiDetector.IsBullishReversalPOI(barIndex) || + poiDetector.IsBullishExhaustionPOI(barIndex); + + // + return result; + } + // #endregion + + // #region Reversal ... + bool IsReversalLongEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + kiParser.IsRSIBullish(barIndex) && + IsTFBullishPattern(barIndex, lowerTF) && + poiDetector.IsBullishReversalPOI(barIndex); + + // + return result; + } + + bool IsReversalShortEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + kiParser.IsRSIBearish(barIndex) && + IsTFBearishPattern(barIndex, lowerTF) && + poiDetector.IsBearishReversalPOI(barIndex); + + // + return result; + } + + bool ExitReversalLong(int barIndex = 0) + { + // + bool result = + poiDetector.IsBearishBreakoutPOI(barIndex) || + poiDetector.IsBearishContinuationPOI(barIndex); + + // + return result; + } + + bool ExitReversalShort(int barIndex = 0) + { + // + bool result = + poiDetector.IsBullishBreakoutPOI(barIndex) || + poiDetector.IsBullishContinuationPOI(barIndex); + + // + return result; + } + // #endregion + + // #region Continuation ... + bool IsContinuationLongEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + IsTFBullishPattern(barIndex, lowerTF) && + kiParser.IsTrendStrongBullish(barIndex) && + poiDetector.IsBullishContinuationPOI(barIndex); + + // + return result; + } + + bool IsContinuationShortEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + IsTFBearishPattern(barIndex, lowerTF) && + kiParser.IsTrendStrongBearish(barIndex) && + poiDetector.IsBearishContinuationPOI(barIndex); + + // + return result; + } + + bool ExitContinuationLong(int barIndex = 0) + { + // + bool result = + poiDetector.IsBearishReversalPOI(barIndex) || + poiDetector.IsBearishExhaustionPOI(barIndex); + + // + return result; + } + + bool ExitContinuationShort(int barIndex = 0) + { + // + bool result = + poiDetector.IsBullishReversalPOI(barIndex) || + poiDetector.IsBullishExhaustionPOI(barIndex); + + // + return result; + } + // #endregion + + // #region Exhaustion ... + bool IsExhaustionLongEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + IsTFBullishPattern(barIndex, lowerTF) && + poiDetector.IsBearishExhaustionPOI(barIndex); + + // + return result; + } + + bool IsExhaustionShortEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + IsTFBearishPattern(barIndex, lowerTF) && + poiDetector.IsBullishExhaustionPOI(barIndex); + + // + return result; + } + + bool ExitExhaustionLong(int barIndex = 0) + { + return poiDetector.IsBearishBreakoutPOI(barIndex); + } + + bool ExitExhaustionShort(int barIndex = 0) + { + return poiDetector.IsBullishBreakoutPOI(barIndex); + } + // #endregion + + // #region Trend Exhaustion ... + bool IsTrendExhaustionLongEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + IsTFBullishPattern(barIndex, lowerTF) && + poiDetector.IsBearishTrendExhaustedPOI(barIndex); + + // + return result; + } + + bool IsTrendExhaustionShortEntry( + int barIndex = 0, + ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // + ) + { + // + bool result = + IsTFBearishPattern(barIndex, lowerTF) && + poiDetector.IsBullishTrendExhaustedPOI(barIndex); + + // + return result; + } + + bool ExitTrendExhaustionLong(int barIndex = 0) + { + // + bool result = + poiDetector.IsBearishBreakoutPOI(barIndex) || + poiDetector.IsBearishContinuationPOI(barIndex); + + // + return result; + } + + bool ExitTrendExhaustionShort(int barIndex = 0) + { + // + bool result = + poiDetector.IsBullishBreakoutPOI(barIndex) || + poiDetector.IsBullishContinuationPOI(barIndex); + + // + return result; + } + // #endregion + + // #endregion diff --git a/Documents/BKP/X121XKI/tmp.zones.poi.mq5 b/Documents/BKP/X121XKI/tmp.zones.poi.mq5 new file mode 100644 index 00000000..973afd82 --- /dev/null +++ b/Documents/BKP/X121XKI/tmp.zones.poi.mq5 @@ -0,0 +1,458 @@ + + int CounteZoneTouches( + XBoxZone &zone, + double threshold = 10, + int loopback = 100 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + threshold = NormalizeDouble(threshold, 10); + + // + if (!zone.IsValid()) + { + return result; + } + + // + XOHCL tmpBar; + int start = zone.ToIndex(); + bool isUpperTouched = false; + bool isLowerTouched = false; + double points = GetPoints(zone.symbol); + double distance = points * threshold; + int end = MathMin(start + loopback, zone.FromIndex()); + for (int i = start; i < end; i++) + { + // + if (tmpBar.Init(zone.symbol, zone.period, i)) + { + // + isUpperTouched = MathAbs(tmpBar.high - zone.upper) <= distance; + isLowerTouched = MathAbs(tmpBar.low - zone.lower) <= distance; + + // + if ( + (zone.IsBullish() && + (isLowerTouched || + MathAbs(tmpBar.close - zone.lower) <= distance)) || + (zone.IsBearish() && + (isUpperTouched || + MathAbs(tmpBar.close - zone.upper) <= distance))) + { + // + result++; + Add( + tmpBar.time, + zone.tests // + ); + } + + // + tmpBar.Clean(); + } + } + + // + tmpBar.Clean(); + + // + return result; + } + + bool HasNearZone( + int &index, + double price, + double threshold, + XBoxZone &zones[] // + ) + { + // + bool result = false; + + // + index = -1; + + // + // Validate ... + result = HasChild(zones) && + NotEmptyZero(price) && + NotEmptyZero(threshold) && + price > 0 && + threshold > 0; + if (!result) + { + return result; + } + + // + double points = GetPoints(zones[0].symbol); + double distance = points * threshold; + for (int i = 0; i < ArraySize(zones); i++) + { + // + // Check Price Distance by Upper ... + result = price >= zones[i].lower - distance && + price <= zones[i].upper + distance; + if (result) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + bool IsNearZone( + double price, + XBoxZone &zone, + double threshold = 0 // + ) + { + // + bool result = false; + + // + result = + zone.IsValid() && + NotEmptyZero(price); + if (!result) + { + return result; + } + + // + double points = GetPoints(zone.symbol); + double distance = points * threshold; + + // + result = price >= zone.lower - distance && + price <= zone.upper + distance; + + // + return result; + } + + + /* + * Check Recently Pattern Zone is Touched 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 threshold: double, threshold for Pattern touch ... + * @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ... + * @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ... + * + * @return ( bool ) + */ + bool HasRecentPatternTouched( + XBoxZone &zone, + ENUM_X_BAR_PATTERN &patterns[], + ENUM_X_DIRECTION &patternsDir[], + double price, + int barIndex = 0, + int loopback = 5, + double threshold = 5, + ENUM_TIMEFRAMES forPeriod = NULL, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // + ) + { + // + bool result = false; + + // + zone.Clean(); + + // + // Validate ... + result = + HasChild(patterns) && + NotEmptyZero(price) && + 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 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 // + ); + + // + // XAUUSD ... + iConfig.AddPattern(X_BAR_PATTERN_FVG); + iConfig.AddPattern(X_BAR_PATTERN_PIERCING); + + // + // 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); + has = HasChild(iBullishZones); + if (has) + { + // + has = HasNearZone( + iBullishIDX, + price, + threshold, + iBullishZones // + ); + if (has) + { + isBullish = true; + } + } + } + + // + // Bearish ... + has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0; + if (has) + { + // + iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH); + has = HasChild(iBearishZones); + if (has) + { + // + has = HasNearZone( + iBearishIDX, + price, + threshold, + iBearishZones // + ); + if (has) + { + isBearish = true; + } + } + } + + // + // 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 ... + iBar.Clean(); + iConfig.Clean(); + iAnalysis.Clean(); + XClean(iBullishZones); + XClean(iBearishZones); + + // + return result; + } + + + void ValidateZones( + XBoxZone &zones[], + int barIndex = 0, + int minimumRetests = 2, + double retestThreshold = 10, + int retestLoopback = 100, + ENUM_X_BOUNDARY_PRICE forPriceType = X_BOUNDARY_PRICE_UP_DOWN // + ) + { + // + bool has = false; + + // + // Validation ... + has = HasChild(zones) && + IsXValid(forPriceType); + if (!has) + { + return; + } + + // + // Normalizetion ... + barIndex = kiParser.NormalizeBarIndex(barIndex); + minimumRetests = NormalizeInt(minimumRetests, 0); + retestLoopback = NormalizeInt(retestLoopback, 50); + retestThreshold = NormalizeDouble(retestThreshold, 5, 10); + + // + XOHCL tmpBar; + XBoxZone tmp; + XBoxZone tmps[]; + double tmpValue = 0; + for (int i = 0; i < ArraySize(zones); i++) + { + // + tmp = zones[i]; + + // + if (minimumRetests > 0) + { + // + int retests = CounteZoneTouches(tmp, retestThreshold, retestLoopback); + if (retests < minimumRetests) + { + continue; + } + } + + // + // Validate Zone ... + has = false; + for (int j = barIndex; j < tmp.FromIndex(); j++) + { + // + // Initial Bar ... + if (tmpBar.Init(tmp.symbol, tmp.period, j)) + { + // + tmpValue = forPriceType == X_BOUNDARY_PRICE_UP_DOWN + ? tmp.IsBullish() + ? tmpBar.GetDown() + : tmpBar.GetUp() + : forPriceType == X_BOUNDARY_PRICE_HIGH_LOW + ? tmp.IsBullish() + ? tmpBar.low + : tmpBar.high + : EMPTY_VALUE; + if (NotEmptyZero(tmpValue)) + { + // + // Check Break ... + has = tmp.IsBullish() + ? tmpValue < tmp.lower + : tmpValue > tmp.upper; + + // + // If Breakes ... + if (has) + { + break; + } + } + + // + tmpBar.Clean(); + } + } + + // + // Not Breaked ... + if (!has) + { + // + AddIfNotExists( + tmp, + tmps // + ); + } + + // + tmp.Clean(); + } + + // + // Update Zones ... + XClean(zones); + Copy( + tmps, + zones // + ); + XClean(tmps); + } diff --git a/Experts/x-saherelm.x121.xki.backtester.ea.mq5 b/Experts/x-saherelm.x121.xki.backtester.ea.mq5 index 15ab2fb4..d49f7a82 100644 --- a/Experts/x-saherelm.x121.xki.backtester.ea.mq5 +++ b/Experts/x-saherelm.x121.xki.backtester.ea.mq5 @@ -78,8 +78,10 @@ input bool showBarTime = true; // Show Bar Time input group "Calculation"; input int kiFastLength = 26; // KI Fast Length input int kiSlowLength = 104; // KI Slow Length -input int maFastLength = 9; // MA Fast Length -input int maSlowLength = 26; // MA Slow Length +input int kiSuperSlowLength = 208; // KI Super Slow Length +input int maFastLength = 26; // MA Fast Length +input int maSlowLength = 104; // MA Slow Length +input int maSuperSlowLength = 208; // MA Super Slow Length input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Mode input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // MA Applied To input int rsiLength = 14; // RSI Length @@ -97,13 +99,16 @@ input ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Price T // // Presentation ... input group "Presentation"; -input bool showKIFast = true; // Show KI Fast -input bool showKISlow = true; // Show KI Slow -input bool showMaFast = true; // Show Ma Fast -input bool showMaSlow = true; // Show MA Slow -input bool showKIWave = true; // Show KI Wave -input bool showKIUpper = true; // Show KI Upper -input bool showKILower = true; // Show KI Lower +input bool showPV = true; // Show PV +input bool showKIFast = true; // Show KI Fast +input bool showKISlow = true; // Show KI Slow +input bool showKISuperSlow = true; // Show KI Super Slow +input bool showMaFast = true; // Show Ma Fast +input bool showMaSlow = true; // Show MA Slow +input bool showMaSuperSlow = true; // Show MA Super Slow +input bool showKIWave = true; // Show KI Wave +input bool showKIUpper = true; // Show KI Upper +input bool showKILower = true; // Show KI Lower // input int startCalculationForLastBars = 1500; // Calculate Last n Bars @@ -251,8 +256,10 @@ int OnInit() // Here we Attach Inputs to Indicator ... kiInputs.kiFastLength = kiFastLength; kiInputs.kiSlowLength = kiSlowLength; + kiInputs.kiSuperSlowLength = kiSuperSlowLength; kiInputs.maFastLength = maFastLength; kiInputs.maSlowLength = maSlowLength; + kiInputs.maSuperSlowLength = maSuperSlowLength; kiInputs.maMethod = maMethod; kiInputs.maAppliedTo = maAppliedTo; kiInputs.rsiLength = rsiLength; @@ -266,10 +273,13 @@ int OnInit() kiInputs.atrSmoothingMode = atrSmoothingMode; kiInputs.atrUpperPriceType = atrUpperPriceType; kiInputs.atrLowerPriceType = atrLowerPriceType; + kiInputs.showPV = showPV; kiInputs.showKIFast = showKIFast; kiInputs.showKISlow = showKISlow; + kiInputs.showKISuperSlow = showKISuperSlow; kiInputs.showMaFast = showMaFast; kiInputs.showMaSlow = showMaSlow; + kiInputs.showMaSuperSlow = showMaSuperSlow; kiInputs.showKIWave = showKIWave; kiInputs.showKIUpper = showKIUpper; kiInputs.showKILower = showKILower; diff --git a/Helpers/x-saherelm.x121.xki.helper.mq5 b/Helpers/x-saherelm.x121.xki.helper.mq5 index ddfcb3e4..531a1d14 100644 --- a/Helpers/x-saherelm.x121.xki.helper.mq5 +++ b/Helpers/x-saherelm.x121.xki.helper.mq5 @@ -31,18 +31,23 @@ enum ENUM_X121_XKI_BUFFERS // KI Fast ... X121_XKI_KI_FAST_LINE = 0, X121_XKI_KI_FAST_COLOR_LINE = 1, - X121_XKI_KI_FAST_STATE_LINE = 10, + X121_XKI_KI_FAST_STATE_LINE = 15, // // KI Slow ... X121_XKI_KI_SLOW_LINE = 8, X121_XKI_KI_SLOW_COLOR_LINE = 9, - X121_XKI_KI_SLOW_STATE_LINE = 17, + X121_XKI_KI_SLOW_STATE_LINE = 22, + // + // KI Super Slow ... + X121_XKI_KI_SUPER_SLOW_LINE = 10, + X121_XKI_KI_SUPER_SLOW_COLOR_LINE = 11, + X121_XKI_KI_SUPER_SLOW_STATE_LINE = 24, // // KI Wave ... X121_XKI_KI_WAVE_LINE = 2, - X121_XKI_KI_WAVE_RAW_LINE = 15, + X121_XKI_KI_WAVE_RAW_LINE = 20, X121_XKI_KI_WAVE_COLOR_LINE = 3, - X121_XKI_KI_WAVE_STATE_LINE = 16, + X121_XKI_KI_WAVE_STATE_LINE = 21, // // Upper/Lower ... X121_XKI_KI_UPPER_LINE = 4, @@ -51,15 +56,20 @@ enum ENUM_X121_XKI_BUFFERS // MA Fast/Slow ... X121_XKI_MA_FAST_LINE = 6, X121_XKI_MA_SLOW_LINE = 7, + X121_XKI_MA_SUPER_SLOW_LINE = 12, + // + // PV ... + X121_XKI_PEAK_LINE = 13, + X121_XKI_VALE_LINE = 14, // // ATR ... - X121_XKI_ATR_LINE = 11, - X121_XKI_ATR_SMOOTHED_LINE = 18, - X121_XKI_ATR_RAW_UPPER_LINE = 12, - X121_XKI_ATR_RAW_LOWER_LINE = 13, + X121_XKI_ATR_LINE = 16, + X121_XKI_ATR_SMOOTHED_LINE = 23, + X121_XKI_ATR_RAW_UPPER_LINE = 17, + X121_XKI_ATR_RAW_LOWER_LINE = 18, // // RSI ... - X121_XKI_RSI_LINE = 14, + X121_XKI_RSI_LINE = 19, }; // #endregion @@ -70,8 +80,10 @@ struct X121XKIInputs // #region Calculations ... int kiFastLength; // KI Fast Length int kiSlowLength; // KI Slow Length + int kiSuperSlowLength; // KI Super Slow Length int maFastLength; // MA Fast Length int maSlowLength; // MA Slow Length + int maSuperSlowLength; // MA Super Slow Length ENUM_MA_METHOD maMethod; // MA Mode ENUM_APPLIED_PRICE maAppliedTo; // MA Applied To int rsiLength; // RSI Length @@ -88,16 +100,23 @@ struct X121XKIInputs // #endregion // #region Presentations ... - bool showKIFast; // Show KI - bool showKISlow; // Show Slow - bool showMaFast; // Show Ma Fast - bool showMaSlow; // Show MA Slow - bool showKIWave; // Show KI Wave - bool showKIUpper; // Show KI Upper - bool showKILower; // Show KI Lower + bool showPV; // Show PV + bool showKIFast; // Show KI + bool showKISlow; // Show KI Slow + bool showKISuperSlow; // Show KI Super Slow + bool showMaFast; // Show Ma Fast + bool showMaSlow; // Show MA Slow + bool showMaSuperSlow; // Show MA Super Slow + bool showKIWave; // Show KI Wave + bool showKIUpper; // Show KI Upper + bool showKILower; // Show KI Lower // int startCalculationForLastBars; // Calculate Last n Bars + + // + int peakArrowCode; // Peaks Arrow Code + int valeArrowCode; // Vales Arrow Code // #endregion // #endregion @@ -124,8 +143,10 @@ struct X121XKIInputs // Calculations ... kiFastLength = 26; kiSlowLength = 104; - maFastLength = 9; - maSlowLength = 26; + kiSuperSlowLength = 208; + maFastLength = 26; + maSlowLength = 104; + maSuperSlowLength = 208; maMethod = MODE_EMA; maAppliedTo = PRICE_CLOSE; rsiLength = 14; @@ -142,16 +163,23 @@ struct X121XKIInputs // // Presentations ... + showPV = true; showKIFast = true; showKISlow = true; + showKISuperSlow = true; showMaFast = true; showMaSlow = true; + showMaSuperSlow = true; showKIWave = true; showKIUpper = true; showKILower = true; // startCalculationForLastBars = 1500; + + // + peakArrowCode = 159; + valeArrowCode = 159; } // @@ -160,10 +188,13 @@ struct X121XKIInputs { // // Presentations ... + showPV = false; showKIFast = false; showKISlow = false; + showKISuperSlow = false; showMaFast = false; showMaSlow = false; + showMaSuperSlow = false; showKIWave = false; showKIUpper = false; showKILower = false; @@ -182,6 +213,12 @@ struct X121XKIInputs // KI ... kiFastLength >= 5 && kiSlowLength > kiFastLength && + kiSuperSlowLength > kiSlowLength && + // + // MA ... + maFastLength >= 2 && + maSlowLength > maFastLength && + maSuperSlowLength > maSlowLength && // // ATR ... atrLength >= 5 && @@ -219,12 +256,18 @@ struct X121XKIConditions double kiSlowBuffer[]; double kiSlowColorBuffer[]; double kiSlowStateBuffer[]; + double kiSuperSlowBuffer[]; + double kiSuperSlowColorBuffer[]; + double kiSuperSlowStateBuffer[]; double kiWaveBuffer[]; double kiWaveColorBuffer[]; double kiUpperBuffer[]; double kiLowerBuffer[]; double maFastBuffer[]; double maSlowBuffer[]; + double maSuperSlowBuffer[]; + double peakBuffer[]; + double valeBuffer[]; double atrBuffer[]; double atrSmoothedBuffer[]; double atrRawUpperBuffer[]; @@ -265,12 +308,18 @@ struct X121XKIConditions XClean(kiSlowBuffer); XClean(kiSlowColorBuffer); XClean(kiSlowStateBuffer); + XClean(kiSuperSlowBuffer); + XClean(kiSuperSlowColorBuffer); + XClean(kiSuperSlowStateBuffer); XClean(kiWaveBuffer); XClean(kiWaveColorBuffer); XClean(kiUpperBuffer); XClean(kiLowerBuffer); XClean(maFastBuffer); XClean(maSlowBuffer); + XClean(maSuperSlowBuffer); + XClean(peakBuffer); + XClean(valeBuffer); XClean(atrBuffer); XClean(atrSmoothedBuffer); XClean(atrRawUpperBuffer); @@ -286,12 +335,18 @@ struct X121XKIConditions ArraySetAsSeries(kiSlowBuffer, true); ArraySetAsSeries(kiSlowColorBuffer, true); ArraySetAsSeries(kiSlowStateBuffer, true); + ArraySetAsSeries(kiSuperSlowBuffer, true); + ArraySetAsSeries(kiSuperSlowColorBuffer, true); + ArraySetAsSeries(kiSuperSlowStateBuffer, true); ArraySetAsSeries(kiWaveBuffer, true); ArraySetAsSeries(kiWaveColorBuffer, true); ArraySetAsSeries(kiUpperBuffer, true); ArraySetAsSeries(kiLowerBuffer, true); ArraySetAsSeries(maFastBuffer, true); ArraySetAsSeries(maSlowBuffer, true); + ArraySetAsSeries(maSuperSlowBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); ArraySetAsSeries(atrBuffer, true); ArraySetAsSeries(atrSmoothedBuffer, true); ArraySetAsSeries(atrRawUpperBuffer, true); @@ -368,8 +423,10 @@ class XCX121XKIHelper : public XCBaseHelper "", // Calculation ... mInputs.kiFastLength, mInputs.kiSlowLength, + mInputs.kiSuperSlowLength, mInputs.maFastLength, mInputs.maSlowLength, + mInputs.maSuperSlowLength, mInputs.maMethod, mInputs.maAppliedTo, mInputs.rsiLength, @@ -384,14 +441,19 @@ class XCX121XKIHelper : public XCBaseHelper mInputs.atrUpperPriceType, mInputs.atrLowerPriceType, "", // Presentation ... + mInputs.showPV, mInputs.showKIFast, mInputs.showKISlow, + mInputs.showKISuperSlow, mInputs.showMaFast, mInputs.showMaSlow, + mInputs.showMaSuperSlow, mInputs.showKIWave, mInputs.showKIUpper, mInputs.showKILower, - mInputs.startCalculationForLastBars // + mInputs.startCalculationForLastBars, + mInputs.peakArrowCode, + mInputs.valeArrowCode // ); result = mHandler != INVALID_HANDLE; if (!result) @@ -506,6 +568,21 @@ class XCX121XKIHelper : public XCBaseHelper loopback, conditions.kiSlowStateBuffer // ); + CopyKISuperSlow( + zIndex, + loopback, + conditions.kiSuperSlowBuffer // + ); + CopyKISuperSlowColor( + zIndex, + loopback, + conditions.kiSuperSlowColorBuffer // + ); + CopyKISuperSlowState( + zIndex, + loopback, + conditions.kiSuperSlowStateBuffer // + ); CopyKIWave( zIndex, loopback, @@ -546,6 +623,21 @@ class XCX121XKIHelper : public XCBaseHelper loopback, conditions.maSlowBuffer // ); + CopyMASuperSlow( + zIndex, + loopback, + conditions.maSuperSlowBuffer // + ); + CopyPeak( + zIndex, + loopback, + conditions.peakBuffer // + ); + CopyVale( + zIndex, + loopback, + conditions.valeBuffer // + ); CopyRSI( zIndex, loopback, @@ -771,6 +863,102 @@ class XCX121XKIHelper : public XCBaseHelper } // #endregion + // #region KI Super Slow ... + // + double GetKISuperSlow( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)X121_XKI_KI_SUPER_SLOW_LINE, + barIndex // + ); + } + + // + int CopyKISuperSlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)X121_XKI_KI_SUPER_SLOW_LINE, + start, + count, + asSeries // + ); + } + // #endregion + + // #region KI Super Slow Color ... + // + double GetKISuperSlowColor( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)X121_XKI_KI_SUPER_SLOW_COLOR_LINE, + barIndex // + ); + } + + // + int CopyKISuperSlowColor( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)X121_XKI_KI_SUPER_SLOW_COLOR_LINE, + start, + count, + asSeries // + ); + } + // #endregion + + // #region KI Super Slow State ... + // + double GetKISuperSlowState( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)X121_XKI_KI_SUPER_SLOW_STATE_LINE, + barIndex // + ); + } + + // + int CopyKISuperSlowState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)X121_XKI_KI_SUPER_SLOW_STATE_LINE, + start, + count, + asSeries // + ); + } + // #endregion + // #region KI Wave ... // double GetKIWave( @@ -1027,6 +1215,102 @@ class XCX121XKIHelper : public XCBaseHelper } // #endregion + // #region MA Super Slow ... + // + double GetMASuperSlow( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)X121_XKI_MA_SUPER_SLOW_LINE, + barIndex // + ); + } + + // + int CopyMASuperSlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)X121_XKI_MA_SUPER_SLOW_LINE, + start, + count, + asSeries // + ); + } + // #endregion + + // #region Peak ... + // + double GetPeak( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)X121_XKI_PEAK_LINE, + barIndex // + ); + } + + // + int CopyPeak( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)X121_XKI_PEAK_LINE, + start, + count, + asSeries // + ); + } + // #endregion + + // #region Vale ... + // + double GetVale( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)X121_XKI_VALE_LINE, + barIndex // + ); + } + + // + int CopyVale( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)X121_XKI_VALE_LINE, + start, + count, + asSeries // + ); + } + // #endregion + // #region RSI ... // double GetRSI( diff --git a/Indicators/x-saherelm.x121.xki.mq5 b/Indicators/x-saherelm.x121.xki.mq5 index 0be7c02e..3a84b2ef 100644 --- a/Indicators/x-saherelm.x121.xki.mq5 +++ b/Indicators/x-saherelm.x121.xki.mq5 @@ -35,8 +35,10 @@ input group "Calculation"; input int kiFastLength = 26; // KI Fast Length input int kiSlowLength = 104; // KI Slow Length -input int maFastLength = 9; // MA Fast Length -input int maSlowLength = 26; // MA Slow Length +input int kiSuperSlowLength = 208; // KI Super Slow Length +input int maFastLength = 26; // MA Fast Length +input int maSlowLength = 104; // MA Slow Length +input int maSuperSlowLength = 208; // MA Super Slow Length input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Mode input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // MA Applied To input int rsiLength = 14; // RSI Length @@ -54,16 +56,23 @@ input ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Price T // // Presentation ... input group "Presentation"; -input bool showKIFast = true; // Show KI Fast -input bool showKISlow = true; // Show KI Slow -input bool showMaFast = true; // Show Ma Fast -input bool showMaSlow = true; // Show MA Slow -input bool showKIWave = true; // Show KI Wave -input bool showKIUpper = true; // Show KI Upper -input bool showKILower = true; // Show KI Lower +input bool showPV = true; // Show PV +input bool showKIFast = true; // Show KI Fast +input bool showKISlow = true; // Show KI Slow +input bool showKISuperSlow = true; // Show KI Super Slow +input bool showMaFast = true; // Show Ma Fast +input bool showMaSlow = true; // Show MA Slow +input bool showMaSuperSlow = true; // Show MA Super Slow +input bool showKIWave = true; // Show KI Wave +input bool showKIUpper = true; // Show KI Upper +input bool showKILower = true; // Show KI Lower // input int startCalculationForLastBars = 1500; // Calculate Last n Bars + +// +input int peakArrowCode = 159; // Peaks Arrow Code +input int valeArrowCode = 159; // Vales Arrow Code // #endregion // #region Non Inputs ... @@ -87,8 +96,8 @@ input int startCalculationForLastBars = 1500; // Calculate Last n Bars #property indicator_chart_window // -#property indicator_buffers 19 -#property indicator_plots 7 +#property indicator_buffers 25 +#property indicator_plots 11 // #region Plot Buffers ... // #region KI ... @@ -200,10 +209,72 @@ double kiSlowColorBuffer[]; #property indicator_style7 STYLE_SOLID #property indicator_width7 2 // #endregion + +// #region KI Super Slow ... +// +#define kiSuperSlowBufferIndex 10 +#define kiSuperSlowBufferPlotIndex 7 +double kiSuperSlowBuffer[]; + +// +#define kiSuperSlowColorBufferIndex 11 +double kiSuperSlowColorBuffer[]; + +// +#property indicator_label8 "KI Super Slow" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrAqua, clrMagenta, clrGray +#property indicator_style8 STYLE_SOLID +#property indicator_width8 2 +// #endregion + +// #region MA Super Slow ... +// +#define maSuperSlowBufferIndex 12 +#define maSuperSlowBufferPlotIndex 8 +double maSuperSlowBuffer[]; + +// +#property indicator_label9 "MA Super Slow" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrMagenta +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 +// #endregion + +// #region PV ... +// +// PEAKS ... + +// +#define peakBufferIndex 13 +#define peakBufferPlotIndex 9 +double peakBuffer[]; + +// +#property indicator_label10 "PEAK" +#property indicator_type10 DRAW_ARROW +#property indicator_color10 clrMagenta +#property indicator_width10 3 + +// +// VALES ... + +// +#define valeBufferIndex 14 +#define valeBufferPlotIndex 10 +double valeBuffer[]; + +// +#property indicator_label11 "VALE" +#property indicator_type11 DRAW_ARROW +#property indicator_color11 clrAqua +#property indicator_width11 3 +// #endregion // #endregion // -#define mLastBufferIndex 9 +#define mLastBufferIndex 14 // #region Data Buffers ... // @@ -241,6 +312,10 @@ double kiSlowStateBuffer[]; // #define atrSmoothedBufferIndex mLastBufferIndex + 9 double atrSmoothedBuffer[]; + +// +#define kiSuperSlowStateBufferIndex mLastBufferIndex + 10 +double kiSuperSlowStateBuffer[]; // #endregion // #endregion @@ -260,6 +335,7 @@ int atrHandler = INVALID_HANDLE; int rsiHandler = INVALID_HANDLE; int maFastHandler = INVALID_HANDLE; int maSlowHandler = INVALID_HANDLE; +int maSuperSlowHandler = INVALID_HANDLE; // #endregion // #region Event Handlers ... @@ -353,12 +429,20 @@ void OnDeinit(const int reason) { IndicatorRelease(maFastHandler); } + // // MA Slow ... if (maSlowHandler != INVALID_HANDLE) { IndicatorRelease(maSlowHandler); } + + // + // MA Super Slow ... + if (maSuperSlowHandler != INVALID_HANDLE) + { + IndicatorRelease(maSuperSlowHandler); + } } /** @@ -416,6 +500,7 @@ int OnCalculate( // MA ... int maFastCalculatedBars = BarsCalculated(maFastHandler); int maSlowCalculatedBars = BarsCalculated(maSlowHandler); + int maSuperSlowCalculatedBars = BarsCalculated(maSuperSlowHandler); // bool isPassedRequiredCalculatedBars = @@ -428,7 +513,8 @@ int OnCalculate( // // MA ... maFastCalculatedBars >= maxLength && - maSlowCalculatedBars >= maxLength + maSlowCalculatedBars >= maxLength && + maSuperSlowCalculatedBars >= maxLength // ; if (!isPassedRequiredCalculatedBars) @@ -456,6 +542,7 @@ int OnCalculate( // MA ... int copiedMAFasts = CopyBuffer(maFastHandler, MAIN_LINE, 0, limit, maFastBuffer); int copiedMASlows = CopyBuffer(maSlowHandler, MAIN_LINE, 0, limit, maSlowBuffer); + int copiedMASuperSlows = CopyBuffer(maSuperSlowHandler, MAIN_LINE, 0, limit, maSuperSlowBuffer); // // Validate Copied Items ... @@ -469,7 +556,8 @@ int OnCalculate( // // MA ... copiedMAFasts >= limit && - copiedMASlows >= limit + copiedMASlows >= limit && + copiedMASuperSlows >= limit // ; if (!isPassedRequiredCopiedItems) @@ -527,6 +615,12 @@ bool ValidateInputs() // KI ... kiFastLength >= 5 && kiSlowLength > kiFastLength && + kiSuperSlowLength > kiSlowLength && + // + // MA ... + maFastLength >= 2 && + maSlowLength > maFastLength && + maSuperSlowLength > maSlowLength && // // ATR ... atrLength >= 5 && @@ -552,8 +646,12 @@ int ExtractMaxLengthOfInputs() // result = MathMax(kiFastLength, atrLength); - result = MathMax(result, kiSlowLength); result = MathMax(result, rsiLength); + result = MathMax(result, kiSlowLength); + result = MathMax(result, maFastLength); + result = MathMax(result, maSlowLength); + result = MathMax(result, maSuperSlowLength); + result = MathMax(result, kiSuperSlowLength); // if (atrSmoothingLength > 0) @@ -610,6 +708,24 @@ void DefineBuffers() SetIndexBuffer(kiSlowStateBufferIndex, kiSlowStateBuffer, INDICATOR_CALCULATIONS); // #endregion + // #region KI Super Slow ... + // + ArraySetAsSeries(kiSuperSlowBuffer, true); + SetIndexBuffer(kiSuperSlowBufferIndex, kiSuperSlowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(kiSuperSlowBufferPlotIndex, PLOT_SHOW_DATA, showKISuperSlow); + PlotIndexSetDouble(kiSuperSlowBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(kiSuperSlowColorBuffer, true); + SetIndexBuffer(kiSuperSlowColorBufferIndex, kiSuperSlowColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(kiSuperSlowStateBuffer, true); + SetIndexBuffer(kiSuperSlowStateBufferIndex, kiSuperSlowStateBuffer, INDICATOR_CALCULATIONS); + // #endregion + // #region KI Upper ... // ENUM_DRAW_TYPE kiUpperDrawType = showKIUpper ? DRAW_LINE : DRAW_NONE; @@ -666,6 +782,44 @@ void DefineBuffers() SetIndexBuffer(kiWaveStateBufferIndex, kiWaveStateBuffer, INDICATOR_CALCULATIONS); // #endregion + // #region PV ... + // + // PEAK / VALE ... + + // + ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE; + + // + // PEAK ... + + // + ArraySetAsSeries(peakBuffer, true); + SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode); + + // + // VALE ... + + // + ArraySetAsSeries(valeBuffer, true); + SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode); + // #endregion + // #region ATR ... // ArraySetAsSeries(atrBuffer, true); @@ -714,6 +868,21 @@ void DefineBuffers() PlotIndexSetInteger(maSlowBufferPlotIndex, PLOT_DRAW_TYPE, maSlowDrawType); PlotIndexSetDouble(maSlowBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); // #endregion + + // #region Super Slow ... + // + ENUM_DRAW_TYPE maSuperSlowDrawType = showMaSuperSlow ? DRAW_LINE : DRAW_NONE; + + // + // Slow ... + ArraySetAsSeries(maSuperSlowBuffer, true); + SetIndexBuffer(maSuperSlowBufferIndex, maSuperSlowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(maSuperSlowBufferPlotIndex, PLOT_SHOW_DATA, showMaSuperSlow); + PlotIndexSetInteger(maSuperSlowBufferPlotIndex, PLOT_DRAW_TYPE, maSuperSlowDrawType); + PlotIndexSetDouble(maSuperSlowBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + // #endregion // #endregion } @@ -773,6 +942,7 @@ bool InitRequirements() { return result; } + // // MA Slow ... maSlowHandler = iMA( @@ -789,6 +959,22 @@ bool InitRequirements() return result; } + // + // MA Super Slow ... + maSuperSlowHandler = iMA( + _Symbol, + _Period, + maSuperSlowLength, + 0, + maMethod, + maAppliedTo // + ); + result = maSuperSlowHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + // return result; } @@ -904,6 +1090,19 @@ void CalculateValues( // // Common Requirements ... + // #region PV ... + CalculatePV( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + // #endregion + // #region KI ... CalculateKI( barIndex, @@ -930,6 +1129,19 @@ void CalculateValues( ); // #endregion + // #region KI Super Slow ... + CalculateKISuperSlow( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + // #endregion + // #region ATR (Ki Upper/Lower) ... CalculateATR( barIndex, @@ -1147,6 +1359,185 @@ void CalculateKISlow( iBar.Clean(); } +/** + * Calculate KI Super Slow Bufer ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void CalculateKISuperSlow( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + double iClose = close[barIndex]; + + // + // Calculate KI / Color ... + double lastKI = + isFirstBar + ? emptyValue + : kiSuperSlowBuffer[lastBarIndex]; + double iKI = lastKI; + if (isInited) + { + // + double iLLKI = iBar.FindLowest(kiSuperSlowLength, MODE_LOW); + double iHHKI = iBar.FindHighest(kiSuperSlowLength, MODE_HIGH); + + // + iKI = (iHHKI + iLLKI) / 2; + if (iLLKI == 0 || iHHKI == 0) + { + iKI = lastKI; + } + } + else + { + iKI = lastKI; + } + kiSuperSlowBuffer[barIndex] = iKI; + + // + double iKIState = neuturalState; + double iKIColor = neuturalColorIDX; + if (iClose > iKI) + { + // + iKIState = bullishState; + iKIColor = + !showKISuperSlow + ? hideColorIDX + : bullishColorIDX; + } + else if (iClose < iKI) + { + // + iKIState = bearishState; + iKIColor = + !showKISuperSlow + ? hideColorIDX + : bearishColorIDX; + } + kiSuperSlowStateBuffer[barIndex] = iKIState; + kiSuperSlowColorBuffer[barIndex] = iKIColor; + + // + iBar.Clean(); +} + +/** + * Calculate PV Bufer ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void CalculatePV( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + // Calculate Peak ... + double lastPeak = + isFirstBar + ? emptyValue + : peakBuffer[lastBarIndex]; + double lastVale = + isFirstBar + ? emptyValue + : valeBuffer[lastBarIndex]; + double iPeak = lastPeak; + double iVale = lastVale; + if (isInited) + { + // + int length = maxLength; + + // + double iLL = iBar.FindLowest(length, MODE_LOW); + double iHH = iBar.FindHighest(length, MODE_HIGH); + + // + double iLL2 = iBar.FindLowest(length / 2, MODE_LOW); + double iHH2 = iBar.FindHighest(length / 2, MODE_HIGH); + + // + iPeak = iHH == iHH2 ? iHH : lastPeak; + iVale = iLL == iLL2 ? iLL : lastVale; + + // + lastPeak = iPeak; + lastVale = iVale; + } + else + { + // + iPeak = lastPeak; + iVale = lastVale; + } + peakBuffer[barIndex] = iPeak; + valeBuffer[barIndex] = iVale; + + // + iBar.Clean(); +} + /** * Calculate ATR and Ki Upper/Lower Buffers ... * diff --git a/X121XKIEA/Classes/x-saherelm.x121.xki.parser.class.mq5 b/X121XKIEA/Classes/x-saherelm.x121.xki.parser.class.mq5 index e1300407..51231eca 100644 --- a/X121XKIEA/Classes/x-saherelm.x121.xki.parser.class.mq5 +++ b/X121XKIEA/Classes/x-saherelm.x121.xki.parser.class.mq5 @@ -544,6 +544,378 @@ class XCX121XKIHelperParser : XCBase // return result; } + + int CountKISlowTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetKISlow(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } + // #endregion + + // #region KI Super Slow ... + bool IsKISuperSlowBullish(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double state = helper.GetKISuperSlowState(barIndex); + result = state >= 1; + + // + return result; + } + + bool IsKISuperSlowBearish(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double state = helper.GetKISuperSlowState(barIndex); + result = state <= -1; + + // + return result; + } + + bool IsKISuperSlowSwitchedToBullish(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + result = IsKISuperSlowBullish(barIndex) && + !IsKISuperSlowBullish(barIndex + 1); + + // + return result; + } + + bool IsKISuperSlowSwitchedToBearish(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + result = IsKISuperSlowBearish(barIndex) && + !IsKISuperSlowBearish(barIndex + 1); + + // + return result; + } + + bool IsKISuperSlowOverLast( + int barIndex = 0, + double distancePoint = 5 // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double value = helper.GetKISuperSlow(barIndex); + double pValue = helper.GetKISuperSlow(barIndex + 1); + double point = GetPoints(symbol); + double distance = point * distancePoint; + + // + result = value >= pValue + distance; + + // + return result; + } + + bool IsKISuperSlowUnderLast( + int barIndex = 0, + double distancePoint = 5 // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double value = helper.GetKISuperSlow(barIndex); + double pValue = helper.GetKISuperSlow(barIndex + 1); + double point = GetPoints(symbol); + double distance = point * distancePoint; + + // + result = value <= pValue - distance; + + // + return result; + } + + int CountKISuperSlowTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetKISuperSlow(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } // #endregion // #region KI Wave ... @@ -761,9 +1133,838 @@ class XCX121XKIHelperParser : XCBase // return result; } + + int CountKIUpperTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetKIUpper(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } + + int CountKILowerTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetKILower(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } + // #endregion + + // #region MA Fast/Slow/SuperSlow ... + + // #region MA Fast ... + bool IsMAFastBullish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + XOHCL iBar; + result = IsValid() && + iBar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = iBar.GetPrice(priceType) > helper.GetMAFast(barIndex); + + // + iBar.Clean(); + + // + return result; + } + + bool IsMAFastBearish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + XOHCL iBar; + result = IsValid() && + iBar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = iBar.GetPrice(priceType) < helper.GetMAFast(barIndex); + + // + iBar.Clean(); + + // + return result; + } + + bool IsMAFastSwitchedToBullish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid() && + IsMAFastBullish(barIndex) && + !IsMAFastBullish(barIndex + 1); + + // + return result; + } + + bool IsMAFastSwitchedToBearish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid() && + IsMAFastBearish(barIndex) && + !IsMAFastBearish(barIndex + 1); + + // + return result; + } + + int CountMAFastTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetMAFast(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } + // #endregion + + // #region MA Slow ... + bool IsMASlowBullish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + XOHCL iBar; + result = IsValid() && + iBar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = iBar.GetPrice(priceType) > helper.GetMASlow(barIndex); + + // + iBar.Clean(); + + // + return result; + } + + bool IsMASlowBearish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + XOHCL iBar; + result = IsValid() && + iBar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = iBar.GetPrice(priceType) < helper.GetMASlow(barIndex); + + // + iBar.Clean(); + + // + return result; + } + + bool IsMASlowSwitchedToBullish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid() && + IsMASlowBullish(barIndex) && + !IsMASlowBullish(barIndex + 1); + + // + return result; + } + + bool IsMASlowSwitchedToBearish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid() && + IsMASlowBearish(barIndex) && + !IsMASlowBearish(barIndex + 1); + + // + return result; + } + + int CountMASlowTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetMASlow(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } + // #endregion + + // #region MA Super Slow ... + bool IsMASuperSlowBullish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + XOHCL iBar; + result = IsValid() && + iBar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = iBar.GetPrice(priceType) > helper.GetMASuperSlow(barIndex); + + // + iBar.Clean(); + + // + return result; + } + + bool IsMASuperSlowBearish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + XOHCL iBar; + result = IsValid() && + iBar.Init(symbol, period, barIndex); + if (!result) + { + return result; + } + + // + result = iBar.GetPrice(priceType) < helper.GetMASuperSlow(barIndex); + + // + iBar.Clean(); + + // + return result; + } + + bool IsMASuperSlowSwitchedToBullish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid() && + IsMASuperSlowBullish(barIndex) && + !IsMASuperSlowBullish(barIndex + 1); + + // + return result; + } + + bool IsMASuperSlowSwitchedToBearish( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid() && + IsMASuperSlowBearish(barIndex) && + !IsMASuperSlowBearish(barIndex + 1); + + // + return result; + } + + int CountMASuperSlowTouches( + int barIndex = 0, + int loopback = 5, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 1); + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + double iValue = 0; + double affectedValue = 0; + double iConfirnValue = 0; + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_UP; + ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_DOWN; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + has = iBar.Init(symbol, period, i); + if (!has) + { + continue; + } + + // + affectedValue = helper.GetMASuperSlow(i); + + // + // Bullish Touches ... + if (isBullish) + { + // + iValue = iBar.GetPrice(bullishTouchLowerPriceType); + iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue <= affectedValue && + iConfirnValue >= affectedValue; + if (has) + { + result++; + } + } + + // + // Bearish Touches ... + if (isBearish) + { + // + iValue = iBar.GetPrice(bearishTouchUpperPriceType); + iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType); + has = + NotEmptyZero(iValue) && + NotEmptyZero(affectedValue) && + NotEmptyZero(iConfirnValue) && + iValue >= affectedValue && + iConfirnValue <= affectedValue; + if (has) + { + result++; + } + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; + } // #endregion - // #region MA Fast/Slow ... bool IsMACrossoverBullish(int barIndex = 0) { // @@ -853,18 +2054,18 @@ class XCX121XKIHelperParser : XCBase !IsMACrossoverBearish(barIndex + 1); return result; } + // #endregion - bool IsMAFastAboveKI(int barIndex = 0) + // #region PV ... + bool IsPeakSameAsLast(int barIndex = 0) { // bool result = false; // - // Normalize ... barIndex = NormalizeBarIndex(barIndex); // - // Validate ... result = IsValid(); if (!result) { @@ -872,21 +2073,21 @@ class XCX121XKIHelperParser : XCBase } // - result = helper.GetMAFast(barIndex) > helper.GetKIFast(barIndex); + result = helper.GetPeak(barIndex) == helper.GetPeak(barIndex + 1); + + // return result; } - bool IsMASlowAboveKI(int barIndex = 0) + bool IsPeakOverLast(int barIndex = 0) { // bool result = false; // - // Normalize ... barIndex = NormalizeBarIndex(barIndex); // - // Validate ... result = IsValid(); if (!result) { @@ -894,7 +2095,161 @@ class XCX121XKIHelperParser : XCBase } // - result = helper.GetMASlow(barIndex) > helper.GetKISlow(barIndex); + result = helper.GetPeak(barIndex) > helper.GetPeak(barIndex + 1); + + // + return result; + } + + bool IsPeakUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = helper.GetPeak(barIndex) < helper.GetPeak(barIndex + 1); + + // + return result; + } + + int CountSamePeaks( + int barIndex = 0, + int loopback = 10 // + ) + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + loopback = NormalizeInt(loopback, 2); + barIndex = NormalizeBarIndex(barIndex); + + // + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + if (IsPeakSameAsLast(i)) + { + result++; + } + } + + // + return result; + } + + bool IsValeSameAsLast(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = helper.GetVale(barIndex) == helper.GetVale(barIndex + 1); + + // + return result; + } + + bool IsValeOverLast(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = helper.GetVale(barIndex) > helper.GetVale(barIndex + 1); + + // + return result; + } + + bool IsValeUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + barIndex = NormalizeBarIndex(barIndex); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = helper.GetVale(barIndex) < helper.GetVale(barIndex + 1); + + // + return result; + } + + int CountSameVales( + int barIndex = 0, + int loopback = 10 // + ) + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + loopback = NormalizeInt(loopback, 2); + barIndex = NormalizeBarIndex(barIndex); + + // + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + if (IsValeSameAsLast(i)) + { + result++; + } + } + + // return result; } // #endregion @@ -1581,6 +2936,183 @@ class XCX121XKIHelperParser : XCBase // return result; } + + /** + * Counting Touches ... + * + * @param bullish: int reference to holds bullih touches ... + * @param bearish: int reference to holds bearish touches ... + * @param barIndex: int, start Bar Index ... + * @param loopback: int, loopback length for counting ... + * @param countKIFast: boolean, Count KI Fast ... + * @param countKISlow: boolean, Count KI Slow ... + * @param countKIUpper: boolean, Count KI Upper ... + * @param countKILower: boolean, Count KI Lower ... + * @param countMAFast: boolean, Count MA Fast ... + * @param countMASlow: boolean, Count MA Slow ... + * @param forceClean: boolean, Force Clean results before Start Counting ... + * @param priceType: ENUM_X_BOUNDARY_PRICE, Specified Price Type for Boundary Countinf ... + */ + void CountTouches( + int &bullish, + int &bearish, + int barIndex = 0, + int loopback = 5, + bool countKIFast = true, + bool countKISlow = true, + bool countKIUpper = true, + bool countKILower = true, + bool countMAFast = true, + bool countMASlow = true, + bool forceClean = true, + ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW // + ) + { + // + if (forceClean) + { + bullish = 0; + bearish = 0; + } + + // + // KI Fast ... + if (countKIFast) + { + // + // Bullish ... + bullish += CountKIFastTouches( + barIndex, + loopback, + X_DIRECTION_BULLISH, + priceType // + ); + + // + // Bearish ... + bearish += CountKIFastTouches( + barIndex, + loopback, + X_DIRECTION_BEARISH, + priceType // + ); + } + + // + // KI Slow ... + if (countKISlow) + { + // + // Bullish ... + bullish += CountKISlowTouches( + barIndex, + loopback, + X_DIRECTION_BULLISH, + priceType // + ); + + // + // Bearish ... + bearish += CountKISlowTouches( + barIndex, + loopback, + X_DIRECTION_BEARISH, + priceType // + ); + } + + // + // KI Upper ... + if (countKIUpper) + { + // + // Bullish ... + bullish += CountKIUpperTouches( + barIndex, + loopback, + X_DIRECTION_BULLISH, + priceType // + ); + + // + // Bearish ... + bearish += CountKIUpperTouches( + barIndex, + loopback, + X_DIRECTION_BEARISH, + priceType // + ); + } + + // + // KI Lower ... + if (countKILower) + { + // + // Bullish ... + bullish += CountKILowerTouches( + barIndex, + loopback, + X_DIRECTION_BULLISH, + priceType // + ); + + // + // Bearish ... + bearish += CountKILowerTouches( + barIndex, + loopback, + X_DIRECTION_BEARISH, + priceType // + ); + } + + // + // KI MA Fast ... + if (countMAFast) + { + // + // Bullish ... + bullish += CountMAFastTouches( + barIndex, + loopback, + X_DIRECTION_BULLISH, + priceType // + ); + + // + // Bearish ... + bearish += CountMAFastTouches( + barIndex, + loopback, + X_DIRECTION_BEARISH, + priceType // + ); + } + + // + // KI MA Slow ... + if (countMASlow) + { + // + // Bullish ... + bullish += CountMASlowTouches( + barIndex, + loopback, + X_DIRECTION_BULLISH, + priceType // + ); + + // + // Bearish ... + bearish += CountMASlowTouches( + barIndex, + loopback, + X_DIRECTION_BEARISH, + priceType // + ); + } + } // #endregion // diff --git a/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 b/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 index 5c318476..e0ee60d5 100644 --- a/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 +++ b/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 @@ -1067,8 +1067,51 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller } // - // Validate Conditions ... + // Summarize Result ... result = isBullish || isBearish; + + // + // Count Touches ... + int bullishTouches = 0; + int bearishTouches = 0; + if (result) + { + // + kiParser.CountTouches( + bullishTouches, + bearishTouches, + barIndex, + 4 // Loopback ... + ); + + // + isBullish = + isBullish && + bullishTouches >= bearishTouches; + + // + isBearish = + isBearish && + bearishTouches >= bullishTouches; + + // + // Summarize Result ... + result = isBullish || isBearish; + if (!result) + { + // + isBullish = false; + isBearish = false; + } + + // + if (bullishTouches > 0 || bearishTouches > 0) + { + // DebugBreak(); + } + } + + // if (!result) { // @@ -1617,326 +1660,6 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller } // #endregion - // #region Signals ... - - // #region POI ... - bool IsBullishPOILongEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - // IMPORTANT: Use near Support/Resistance ... - bool result = poiDetector.IsBullishPOI(barIndex) && - kiParser.IsSafeBullishEntry(barIndex) && - IsTFBullishPattern(barIndex, lowerTF); - - // - return result; - } - - bool IsBearishPOIShortEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - // IMPORTANT: Use near Support/Resistance ... - bool result = poiDetector.IsBearishPOI(barIndex) && - kiParser.IsSafeBearishEntry(barIndex) && - IsTFBearishPattern(barIndex, lowerTF); - - // - return result; - } - - bool ExitBullishPOILong(int barIndex = 0) - { - // - bool result = - poiDetector.IsBearishReversalPOI(barIndex) || - poiDetector.IsBearishBreakoutPOI(barIndex) || - poiDetector.IsBearishExhaustionPOI(barIndex); - - // - return result; - } - - bool ExitBearishPOIShort(int barIndex = 0) - { - // - bool result = - poiDetector.IsBullishReversalPOI(barIndex) || - poiDetector.IsBullishBreakoutPOI(barIndex) || - poiDetector.IsBullishExhaustionPOI(barIndex); - - // - return result; - } - // #endregion - - // #region Breakout ... - bool IsBreakoutLongEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = false; - - // - result = - kiParser.IsVolatilityHigh(barIndex) && - IsTFBullishPattern(barIndex, lowerTF) && - poiDetector.IsBullishBreakoutPOI(barIndex); - - // - return result; - } - - bool IsBreakoutShortEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = false; - - // - result = - kiParser.IsVolatilityHigh(barIndex) && - IsTFBearishPattern(barIndex, lowerTF) && - poiDetector.IsBearishBreakoutPOI(barIndex); - - // - return result; - } - - bool ExitBreakoutLong(int barIndex = 0) - { - // - bool result = - poiDetector.IsBearishReversalPOI(barIndex) || - poiDetector.IsBearishExhaustionPOI(barIndex); - - // - return result; - } - - bool ExitBreakoutShort(int barIndex = 0) - { - // - bool result = - poiDetector.IsBullishReversalPOI(barIndex) || - poiDetector.IsBullishExhaustionPOI(barIndex); - - // - return result; - } - // #endregion - - // #region Reversal ... - bool IsReversalLongEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - kiParser.IsRSIBullish(barIndex) && - IsTFBullishPattern(barIndex, lowerTF) && - poiDetector.IsBullishReversalPOI(barIndex); - - // - return result; - } - - bool IsReversalShortEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - kiParser.IsRSIBearish(barIndex) && - IsTFBearishPattern(barIndex, lowerTF) && - poiDetector.IsBearishReversalPOI(barIndex); - - // - return result; - } - - bool ExitReversalLong(int barIndex = 0) - { - // - bool result = - poiDetector.IsBearishBreakoutPOI(barIndex) || - poiDetector.IsBearishContinuationPOI(barIndex); - - // - return result; - } - - bool ExitReversalShort(int barIndex = 0) - { - // - bool result = - poiDetector.IsBullishBreakoutPOI(barIndex) || - poiDetector.IsBullishContinuationPOI(barIndex); - - // - return result; - } - // #endregion - - // #region Continuation ... - bool IsContinuationLongEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - IsTFBullishPattern(barIndex, lowerTF) && - kiParser.IsTrendStrongBullish(barIndex) && - poiDetector.IsBullishContinuationPOI(barIndex); - - // - return result; - } - - bool IsContinuationShortEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - IsTFBearishPattern(barIndex, lowerTF) && - kiParser.IsTrendStrongBearish(barIndex) && - poiDetector.IsBearishContinuationPOI(barIndex); - - // - return result; - } - - bool ExitContinuationLong(int barIndex = 0) - { - // - bool result = - poiDetector.IsBearishReversalPOI(barIndex) || - poiDetector.IsBearishExhaustionPOI(barIndex); - - // - return result; - } - - bool ExitContinuationShort(int barIndex = 0) - { - // - bool result = - poiDetector.IsBullishReversalPOI(barIndex) || - poiDetector.IsBullishExhaustionPOI(barIndex); - - // - return result; - } - // #endregion - - // #region Exhaustion ... - bool IsExhaustionLongEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - IsTFBullishPattern(barIndex, lowerTF) && - poiDetector.IsBearishExhaustionPOI(barIndex); - - // - return result; - } - - bool IsExhaustionShortEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - IsTFBearishPattern(barIndex, lowerTF) && - poiDetector.IsBullishExhaustionPOI(barIndex); - - // - return result; - } - - bool ExitExhaustionLong(int barIndex = 0) - { - return poiDetector.IsBearishBreakoutPOI(barIndex); - } - - bool ExitExhaustionShort(int barIndex = 0) - { - return poiDetector.IsBullishBreakoutPOI(barIndex); - } - // #endregion - - // #region Trend Exhaustion ... - bool IsTrendExhaustionLongEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - IsTFBullishPattern(barIndex, lowerTF) && - poiDetector.IsBearishTrendExhaustedPOI(barIndex); - - // - return result; - } - - bool IsTrendExhaustionShortEntry( - int barIndex = 0, - ENUM_TIMEFRAMES lowerTF = PERIOD_M5 // - ) - { - // - bool result = - IsTFBearishPattern(barIndex, lowerTF) && - poiDetector.IsBullishTrendExhaustedPOI(barIndex); - - // - return result; - } - - bool ExitTrendExhaustionLong(int barIndex = 0) - { - // - bool result = - poiDetector.IsBearishBreakoutPOI(barIndex) || - poiDetector.IsBearishContinuationPOI(barIndex); - - // - return result; - } - - bool ExitTrendExhaustionShort(int barIndex = 0) - { - // - bool result = - poiDetector.IsBullishBreakoutPOI(barIndex) || - poiDetector.IsBullishContinuationPOI(barIndex); - - // - return result; - } - // #endregion - - // #endregion - // #region TF Patterns ... bool IsTFBullishPattern( int barIndex = 0, 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 3cceca21..2cbc7512 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 @@ -77,1199 +77,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // // Actions and Tools ... - // #region POI Detectors ... - bool NearestKIFastBullish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKIFastBullish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKIFastBearish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKIFastBearish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKIFastSwitchedToBullish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKIFastSwitchedToBullish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKIFastSwitchedToBearish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKIFastSwitchedToBearish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKISlowBullish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKISlowBullish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKISlowBearish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKISlowBearish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKISlowSwitchedToBullish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKISlowSwitchedToBullish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool NearestKISlowSwitchedToBearish( - int &index, - int barIndex = 0, - int loopback = 50 // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Normalize ... - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Loop Back ... - bool isPassed = false; - for (int i = barIndex; i < barIndex + loopback; i++) - { - // - isPassed = kiParser.IsKISlowSwitchedToBearish(i); - if (isPassed) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - // #endregion - - // #region Detectors ... - bool IsPOI( - ENUM_X_DIRECTION &forDir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Normalize ... - forDir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isBullish = IsBullishPOI(barIndex); - bool isBearish = IsBearishPOI(barIndex); - result = isBullish || isBearish; - if (!result) - { - return result; - } - - // - forDir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(forDir); - - // - return result; - } - - bool IsBullishPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsTrendBullish(barIndex) && - kiParser.IsRSIBullish(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BULLISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsBearishPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsTrendBearish(barIndex) && - kiParser.IsRSIBearish(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BEARISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsBreakoutPOI( - ENUM_X_DIRECTION &forDir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Normalize ... - forDir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isBullish = IsBullishBreakoutPOI(barIndex); - bool isBearish = IsBearishBreakoutPOI(barIndex); - result = isBullish || isBearish; - if (!result) - { - return result; - } - - // - forDir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(forDir); - - // - return result; - } - - bool IsBullishBreakoutPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsBullishBreakout(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BULLISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsBearishBreakoutPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsBearishBreakout(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BEARISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsReversalPOI( - ENUM_X_DIRECTION &forDir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Normalize ... - forDir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isBullish = IsBullishReversalPOI(barIndex); - bool isBearish = IsBearishReversalPOI(barIndex); - result = isBullish || isBearish; - if (!result) - { - return result; - } - - // - forDir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(forDir); - - // - return result; - } - - bool IsBullishReversalPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsBullishReversal(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BULLISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsBearishReversalPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsBearishReversal(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BEARISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsContinuationPOI( - ENUM_X_DIRECTION &forDir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Normalize ... - forDir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isBullish = IsBullishContinuationPOI(barIndex); - bool isBearish = IsBearishContinuationPOI(barIndex); - result = isBullish || isBearish; - if (!result) - { - return result; - } - - // - forDir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(forDir); - - // - return result; - } - - bool IsBullishContinuationPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsTrendStrongBullish(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - ENUM_X_DIRECTION dir; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - XOHCL swingBar; - result = result && - IsFlagPattern(bar, dir, swingBar) && - IsXBullish(dir); - - // - bar.Clean(); - swingBar.Clean(); - - // - return result; - } - - bool IsBearishContinuationPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = kiParser.IsTrendStrongBearish(barIndex); - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - ENUM_X_DIRECTION dir; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - XOHCL swingBar; - result = result && - IsFlagPattern(bar, dir, swingBar) && - IsXBearish(dir); - - // - bar.Clean(); - swingBar.Clean(); - - // - return result; - } - - bool IsExhaustionPOI( - ENUM_X_DIRECTION &forDir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Normalize ... - forDir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isBullish = IsBullishExhaustionPOI(barIndex); - bool isBearish = IsBearishExhaustionPOI(barIndex); - result = isBullish || isBearish; - if (!result) - { - return result; - } - - // - forDir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(forDir); - - // - return result; - } - - bool IsBullishExhaustionPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isTrendOk = kiParser.IsTrendStrongBullish(barIndex); - bool isRSIOk = kiParser.IsRSIOverbought(barIndex); - result = isTrendOk && isRSIOk; - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BEARISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsBearishExhaustionPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isTrendOk = kiParser.IsTrendStrongBearish(barIndex); - bool isRSIOk = kiParser.IsRSIOversold(barIndex); - result = isTrendOk && isRSIOk; - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BULLISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsTrendExhaustedPOI( - ENUM_X_DIRECTION &forDir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Normalize ... - forDir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isBullish = IsBullishTrendExhaustedPOI(barIndex); - bool isBearish = IsBearishTrendExhaustedPOI(barIndex); - result = isBullish || isBearish; - if (!result) - { - return result; - } - - // - forDir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(forDir); - - // - return result; - } - - bool IsBullishTrendExhaustedPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Trend was strong in last 3 bars ... - bool isTrendOk = kiParser.IsTrendStrongBullish(barIndex + 1); - for (int i = 1; i <= 3; i++) - { - // - if (kiParser.IsTrendStrongBullish(barIndex + i)) - { - isTrendOk = true; - break; - } - } - - // - // RSI rolling over from overbought ... - double rsiNow = kiHelper.GetRSI(barIndex); - double rsiPrev = kiHelper.GetRSI(barIndex + 1); - bool rsiFlip = (rsiPrev > 70 && rsiNow < rsiPrev); - bool isRSIOk = rsiFlip || kiParser.IsRSIOverbought(barIndex); - - // - bool volCooling = kiHelper.GetATR(barIndex) <= kiHelper.GetATRSmoothed(barIndex) * 1.05; - bool isVolatilityOk = volCooling || kiParser.IsVolatilityLow(barIndex); - - // - result = isRSIOk && - isTrendOk && - isVolatilityOk; - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BEARISH // - ); - - // - bar.Clean(); - - // - return result; - } - - bool IsBearishTrendExhaustedPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - bool isTrendOk = kiParser.IsTrendStrongBearish(barIndex + 1); - for (int i = 1; i <= 3; i++) - { - // - if (kiParser.IsTrendStrongBearish(barIndex + i)) - { - isTrendOk = true; - break; - } - } - - // - // RSI rolling over from overbought ... - double rsiNow = kiHelper.GetRSI(barIndex); - double rsiPrev = kiHelper.GetRSI(barIndex + 1); - bool rsiFlip = (rsiPrev < 30 && rsiNow > rsiPrev); - bool isRSIOk = rsiFlip || kiParser.IsRSIOversold(barIndex); - - // - bool volCooling = kiHelper.GetATR(barIndex) <= kiHelper.GetATRSmoothed(barIndex) * 1.05; - bool isVolatilityOk = volCooling || kiParser.IsVolatilityLow(barIndex); - - // - result = isRSIOk && - isTrendOk && - isVolatilityOk; - if (!result) - { - return result; - } - - // - // Add candlestick confirmation ... - XOHCL bar; - result = result && - bar.Init(symbol, period, barIndex); - if (!result) - { - return result; - } - - // - result = result && - HasCandlestickDirection( - bar, - X_DIRECTION_BULLISH // - ); - - // - bar.Clean(); - - // - return result; - } - // #endregion - - // #region XDetectors ... - bool IsKIPOI( - ENUM_X_DIRECTION &dir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - bool isBullish = IsKIBullishPOI(barIndex); - bool isBearish = IsKIBearishPOI(barIndex); - - // - dir = isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - - // - result = HasDirection(dir); - - // - return result; - } - - bool IsKIBullishPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = - kiParser.IsValid() && - kiParser.IsKISlowBullish(barIndex) && - kiParser.IsKIFastBearish(barIndex); - - // - return result; - } - - bool IsKIBearishPOI(int barIndex = 0) - { - // - bool result = false; - - // - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - result = - kiParser.IsValid() && - kiParser.IsKISlowBearish(barIndex) && - kiParser.IsKIFastBullish(barIndex); - - // - return result; - } - - bool IsKISignal( - ENUM_X_DIRECTION &dir, // - int barIndex = 0 // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - barIndex = kiParser.NormalizeBarIndex(barIndex); - - // - // Retrieve KI State ... - bool isBullish = kiParser.IsKIFastSwitchedToBullish(barIndex + 1) && - kiParser.IsKIFastBullish(barIndex) && - kiParser.IsKISlowBullish(barIndex); - bool isBearish = kiParser.IsKIFastSwitchedToBearish(barIndex + 1) && - kiParser.IsKIFastBearish(barIndex) && - kiParser.IsKISlowBearish(barIndex); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - dir = isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - result = HasDirection(dir); - if (!result) - { - return result; - } - - // - XOHCL bar; - result = bar.Init(symbol, period, barIndex + 1); - if (!result) - { - return result; - } - - // - // Bar Direction Same as Dir ... - - // - // Price Place Check ... - double kiFast = kiHelper.GetKIFast(barIndex + 1); - double kiSlow = kiHelper.GetKISlow(barIndex + 1); - isBullish = - isBullish && - bar.close > kiFast && - kiFast > kiSlow && - (kiParser.IsKIFastOverLast(barIndex + 1) || - kiParser.IsKISlowOverLast(barIndex + 1)); - isBearish = - isBearish && - bar.close < kiFast && - kiFast < kiSlow && - (kiParser.IsKIFastUnderLast(barIndex + 1) || - kiParser.IsKISlowUnderLast(barIndex + 1)); - - // - result = - result && - (isBullish || - isBearish); - - // - // Cleanup Resources ... - bar.Clean(); - - // - return result; - } - // #endregion - // #region Zone Detectors ... int DetectSupports( XBoxZone &zones[], @@ -1277,9 +84,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector int loopback = 50, bool forceValidation = true, int validationLength = 7, - int minimumRetests = 2, - double retestThreshold = 10, - int retestLoopback = 100, string forSymbol = NULL, ENUM_TIMEFRAMES forPeriod = NULL // ) @@ -1402,10 +206,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // ValidateZones( zones, - barIndex, - minimumRetests, - retestThreshold, - retestLoopback // + barIndex // ); } @@ -1422,9 +223,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector int loopback = 50, bool forceValidation = true, int validationLength = 7, - int minimumRetests = 2, - double retestThreshold = 10, - int retestLoopback = 100, string forSymbol = NULL, ENUM_TIMEFRAMES forPeriod = NULL // ) @@ -1545,10 +343,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // ValidateZones( zones, - barIndex, - minimumRetests, - retestThreshold, - retestLoopback // + barIndex // ); } @@ -1562,9 +357,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector void ValidateZones( XBoxZone &zones[], int barIndex = 0, - int minimumRetests = 2, - double retestThreshold = 10, - int retestLoopback = 100, ENUM_X_BOUNDARY_PRICE forPriceType = X_BOUNDARY_PRICE_UP_DOWN // ) { @@ -1583,9 +375,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // // Normalizetion ... barIndex = kiParser.NormalizeBarIndex(barIndex); - minimumRetests = NormalizeInt(minimumRetests, 0); - retestLoopback = NormalizeInt(retestLoopback, 50); - retestThreshold = NormalizeDouble(retestThreshold, 5, 10); // XOHCL tmpBar; @@ -1597,17 +386,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // tmp = zones[i]; - // - if (minimumRetests > 0) - { - // - int retests = CounteZoneTouches(tmp, retestThreshold, retestLoopback); - if (retests < minimumRetests) - { - continue; - } - } - // // Validate Zone ... has = false; @@ -1686,10 +464,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector ENUM_TIMEFRAMES forMajorPeriod = NULL, int loopback = 50, int minorValidation = 7, - int majorValidation = 14, - int minimumRetests = 2, - double retestThreshold = 10, - int retestLoopback = 100 // + int majorValidation = 14 // ) { // @@ -1736,9 +511,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector loopback, true, // Force Validation ... minorValidation, - minimumRetests, - retestThreshold, - retestLoopback, forSymbol, forMinorPeriod // ); @@ -1765,9 +537,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector loopback, true, // Force Validation ... minorValidation, - minimumRetests, - retestThreshold, - retestLoopback, forSymbol, forMinorPeriod // ); @@ -1801,9 +570,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector loopback, true, // Force Validation ... majorValidation, - minimumRetests, - retestThreshold, - retestLoopback, forSymbol, forMajorPeriod // ); @@ -1833,9 +599,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector loopback, true, // Force Validation ... majorValidation, - minimumRetests, - retestThreshold, - retestLoopback, forSymbol, forMajorPeriod // ); @@ -1870,10 +633,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector ENUM_TIMEFRAMES forMajorPeriod = NULL, int loopback = 50, int minorValidation = 7, - int majorValidation = 14, - int minimumRetests = 2, - double retestThreshold = 10, - int retestLoopback = 100 // + int majorValidation = 14 // ) { // @@ -1898,10 +658,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector forMajorPeriod, loopback, minorValidation, - majorValidation, - minimumRetests, - retestThreshold, - retestLoopback // + majorValidation // ); // @@ -2000,151 +757,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector ); } - int CounteZoneTouches( - XBoxZone &zone, - double threshold = 10, - int loopback = 100 // - ) - { - // - int result = 0; - - // - // Normalize ... - loopback = NormalizeInt(loopback, 50); - threshold = NormalizeDouble(threshold, 10); - - // - if (!zone.IsValid()) - { - return result; - } - - // - XOHCL tmpBar; - int start = zone.ToIndex(); - bool isUpperTouched = false; - bool isLowerTouched = false; - double points = GetPoints(zone.symbol); - double distance = points * threshold; - int end = MathMin(start + loopback, zone.FromIndex()); - for (int i = start; i < end; i++) - { - // - if (tmpBar.Init(zone.symbol, zone.period, i)) - { - // - isUpperTouched = MathAbs(tmpBar.high - zone.upper) <= distance; - isLowerTouched = MathAbs(tmpBar.low - zone.lower) <= distance; - - // - if ( - (zone.IsBullish() && - (isLowerTouched || - MathAbs(tmpBar.close - zone.lower) <= distance)) || - (zone.IsBearish() && - (isUpperTouched || - MathAbs(tmpBar.close - zone.upper) <= distance))) - { - // - result++; - Add( - tmpBar.time, - zone.tests // - ); - } - - // - tmpBar.Clean(); - } - } - - // - tmpBar.Clean(); - - // - return result; - } - - bool HasNearZone( - int &index, - double price, - double threshold, - XBoxZone &zones[] // - ) - { - // - bool result = false; - - // - index = -1; - - // - // Validate ... - result = HasChild(zones) && - NotEmptyZero(price) && - NotEmptyZero(threshold) && - price > 0 && - threshold > 0; - if (!result) - { - return result; - } - - // - double points = GetPoints(zones[0].symbol); - double distance = points * threshold; - for (int i = 0; i < ArraySize(zones); i++) - { - // - // Check Price Distance by Upper ... - result = price >= zones[i].lower - distance && - price <= zones[i].upper + distance; - if (result) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; - } - - bool IsNearZone( - double price, - XBoxZone &zone, - double threshold = 0 // - ) - { - // - bool result = false; - - // - result = - zone.IsValid() && - NotEmptyZero(price); - if (!result) - { - return result; - } - - // - double points = GetPoints(zone.symbol); - double distance = points * threshold; - - // - result = price >= zone.lower - distance && - price <= zone.upper + distance; - - // - return result; - } - void RefineZone( XBoxZone &zone, int loopback = 500, @@ -2649,8 +1261,8 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector } // #endregion - // #region VolatilitySwitchedHigh ... - bool IsVolatilitySwitchedHigh( + // #region Hasers ... + bool HasVolatilitySwitchedHigh( int barIndex = 0, int loopback = 3 // ) @@ -2757,203 +1369,6 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector toBar.Clean(); } - /* - * Check Recently Pattern Zone is Touched 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 threshold: double, threshold for Pattern touch ... - * @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ... - * @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ... - * - * @return ( bool ) - */ - bool HasRecentPatternTouched( - XBoxZone &zone, - ENUM_X_BAR_PATTERN &patterns[], - ENUM_X_DIRECTION &patternsDir[], - double price, - int barIndex = 0, - int loopback = 5, - double threshold = 5, - ENUM_TIMEFRAMES forPeriod = NULL, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // - ) - { - // - bool result = false; - - // - zone.Clean(); - - // - // Validate ... - result = - HasChild(patterns) && - NotEmptyZero(price) && - 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 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 // - ); - - // - // XAUUSD ... - iConfig.AddPattern(X_BAR_PATTERN_FVG); - iConfig.AddPattern(X_BAR_PATTERN_PIERCING); - - // - // 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); - has = HasChild(iBullishZones); - if (has) - { - // - has = HasNearZone( - iBullishIDX, - price, - threshold, - iBullishZones // - ); - if (has) - { - isBullish = true; - } - } - } - - // - // Bearish ... - has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0; - if (has) - { - // - iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH); - has = HasChild(iBearishZones); - if (has) - { - // - has = HasNearZone( - iBearishIDX, - price, - threshold, - iBearishZones // - ); - if (has) - { - isBearish = true; - } - } - } - - // - // 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 ... - iBar.Clean(); - iConfig.Clean(); - iAnalysis.Clean(); - XClean(iBullishZones); - XClean(iBearishZones); - - // - return result; - } - /* * Check Recently Pattern Zone is Rejected or not ... * @@ -3131,6 +1546,1068 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector } // #endregion + // #region Switches ... + // TODO: Implement Switches Checkers in Loopback ... + // #endregion + + // #region Peak and Vale ... + // TODO: Implement Root of Changes when IsPeakOverLast or IsValeUnderLast Happens ... + // #endregion + + // #region Rejecteds ... + bool IsKIFastRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetKIFast(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsKISlowRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetKISlow(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsKISuperSlowRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetKISuperSlow(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsKIUpperRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetKIUpper(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsKILowerRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetKILower(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsMAFastRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetMAFast(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsMASlowRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetMASlow(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsMASuperSlowRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetMASuperSlow(barIndex); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsPrevPeakRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetPeak(barIndex + 1); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + + bool IsPrevValeRejected( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + if (!IsXValid(forSymbol)) + { + forSymbol = symbol; + } + if (!IsXValid(forPeriod)) + { + forPeriod = period; + } + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + XOHCL bar; + result = + kiParser.IsValid() && + bar.Init(forSymbol, forPeriod, barIndex); + if (!result) + { + return result; + } + + // + double iValue = kiHelper.GetVale(barIndex + 1); + + // + bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false); + bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false); + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + result = HasDirection(dir); + + // + bar.Clean(); + + // + return result; + } + // #endregion + + // #region Counters ... + int CountKIFastRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsKIFastRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountKISlowRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsKISlowRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountKISuperSlowRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsKISuperSlowRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountKIUpperRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsKIUpperRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountKILowerRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsKILowerRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountMAFastRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsMAFastRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountMASlowRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsMASlowRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountMASuperSlowRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsMASuperSlowRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountPrevPeakRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsPrevPeakRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + + int CountPrevValeRejects( + int barIndex = 0, + int loopback = 10, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + string forSymbol = NULL, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + loopback = NormalizeInt(loopback, 2); + barIndex = kiParser.NormalizeBarIndex(barIndex); + + // + bool isBullish = !HasDirection(forDir) || IsXBullish(forDir); + bool isBearish = !HasDirection(forDir) || IsXBearish(forDir); + + // + bool is = false; + bool hasBullish = false; + bool hasBearish = false; + ENUM_X_DIRECTION tmpDir; + for (int i = barIndex; i < barIndex + loopback; i++) + { + // + is = IsPrevValeRejected( + tmpDir, + i, + forSymbol, + forPeriod // + ); + hasBullish = is && IsXBullish(tmpDir); + hasBearish = is && IsXBearish(tmpDir); + + // + if ((isBullish && hasBullish) || + (isBearish && hasBearish)) + { + result++; + } + } + + // + return result; + } + // #endregion + // // Others ...