diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index 199b7953..6fe04690 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -297,6 +297,168 @@ class XCMarketPatternDetector : public XCBase return result; } + /** + * Detect Confluence Statck based on Given Bar ... + * + * @param bar: XOHCL, Specified Bar for Start Detection ... + * @param zone: XBoxZone, confluence Zone, if exists ... + * @param forDir: ENUM_X_DIRECTION, Specified Required Zone Confluence ... + * @param retests: int, Number of Zone retesting ... + * @param loopback: int, Max allowed Loopback for Confluence Detection ... + * @param rangeLength: int, Loopback for Range Detecttion ... + * @param upperPriceType: ENUM_X_PRICE, zone upper Price Type ... + * @param lowerPriceType: ENUM_X_PRICE, + * @return ( bool ) + */ + bool HasConfluence( + XOHCL &bar, + XBoxZone &confluence, + ENUM_X_DIRECTION forDir, + int retests = 2, + int loopback = 15, + int rangeLength = 5, + ENUM_X_PRICE upperPriceType = X_PRICE_HIGH, + ENUM_X_PRICE lowerPriceType = X_PRICE_LOW // + ) + { + // + bool result = false; + + // + // Normalize ... + confluence.Clean(); + if (retests < 0) + { + retests = 0; + } + if (loopback < 2) + { + loopback = 2; + } + if (rangeLength < 2) + { + rangeLength = 2; + } + + // + // Validate ... + result = + bar.IsValid() && + HasDirection(forDir) && + IsXValid(upperPriceType) && + IsXValid(lowerPriceType); + if (!result) + { + return result; + } + + // + // Retrieve Upper and Lower ... + int mIndex = -1; + double upper = bar.FindHighest( + mIndex, + rangeLength, + upperPriceType // + ); + double lower = bar.FindLowest( + mIndex, + rangeLength, + lowerPriceType // + ); + + // + // Validate Upper/Lower ... + result = + NotEmptyZero(upper) && + NotEmptyZero(lower) && + upper > lower; + if (!result) + { + return result; + } + + // + // Validate Confluence ... + XOHCL tmpBar; + bool has = false; + int tmpCount = 0; + double tmpPrice = EMPTY_VALUE; + for (int i = bar.Index() + 1; i < bar.Index() + loopback; i++) + { + // + has = tmpBar.Init(bar.symbol, bar.period, i); + if (!has) + { + continue; + } + + // + tmpPrice = + IsXBullish(forDir) + ? tmpBar.GetPrice(upperPriceType) + : tmpBar.GetPrice(lowerPriceType); + has = + NotEmptyZero(tmpPrice) && + (IsXBullish(forDir) + ? tmpPrice < upper + : tmpPrice > lower); + if (!has) + { + // + tmpBar.Clean(); + + // + result = false; + break; + } + + // + // Counting retests ... + has = IsXBullish(forDir) + ? tmpPrice > lower + : tmpPrice > upper; + if (has) + { + tmpCount++; + } + + // + tmpBar.Clean(); + } + + // + // Validating Retests ... + if (result && retests > 0) + { + // + result = + result && + tmpCount >= retests; + } + + // + if (!result) + { + return result; + } + + // + result = confluence.Init( + bar.symbol, + bar.period, + upper, + lower, + GetBarTime(bar.symbol, bar.period, bar.Index() + loopback + 1), + bar.time, + forDir, + "XConfluence", + NULL // At ... + ); + + // + return result; + } + // // Detectors ... diff --git a/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 b/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 index e2f67cd7..f44bb53c 100644 --- a/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 +++ b/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5 @@ -1770,8 +1770,8 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller bar.period, 100, 4, - 2, - 100 // + 1, + 15 // ); // 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 bc131edd..02738030 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 @@ -87,7 +87,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector int minAllowedSameDirectionalBars = 4, double minFVGAllowedPoints = 30, int confluence = 1, - int confluenceLoopback = 50 // + int confluenceLoopback = 10 // ) { // @@ -159,11 +159,11 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector double lower = 0; XBoxZone tmpZone; int tmpCount = 0; - XBoxZone tmpFVGs[]; string type = NULL; double tmpValue = 0; datetime from = NULL; int start = barIndex; + XBoxZone confluenceZone; int end = barIndex + loopback; ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; datetime to = GetBarTime(forSymbol, forPeriod, barIndex); @@ -341,17 +341,40 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // continue; } - + // // Validating Confluence if Provided ... - if (confluence > 0 && confluenceLoopback > 0) { + if (confluence > 0 && confluenceLoopback > 0) + { // - for (int j = tmpZoneBar.Index(); j < tmpZoneBar.Index() + confluenceLoopback; j++) { - + has = HasConfluence( + tmpZoneBar, + confluenceZone, + X_DIRECTION_BULLISH, + confluence, + confluenceLoopback, + structureLength, + X_PRICE_HIGH, + X_PRICE_LOW // + ); + + // + if (!has) + { + // + tmpCount = 0; + tmpBar.Clean(); + tmpFVG.Clean(); + tmpFVGBar.Clean(); + tmpZoneBar.Clean(); + breakerBar.Clean(); + tmpDir = X_DIRECTION_NONE; + + // + continue; } } - // DebugBreak(); @@ -364,6 +387,7 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector tmpFVGBar.Clean(); tmpZoneBar.Clean(); breakerBar.Clean(); + confluenceZone.Clean(); tmpDir = X_DIRECTION_NONE; }