diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index be4d215f..199b7953 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -266,7 +266,9 @@ class XCMarketPatternDetector : public XCBase // XOHCL tmpBar; bar.GetPreviousBar(tmpBar); - while (tmpBar.GetDirection() == bar.GetDirection()) + while ((tmpBar.GetDirection() == bar.GetDirection()) || + ((bar.IsBullish() && !tmpBar.IsBearish()) || + (bar.IsBearish() && !tmpBar.IsBullish()))) { // count++; diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index d17d4878..22444b8c 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -6551,4 +6551,102 @@ int RemoveBreakedZones( // #endregion //+------------------------------------------------------------------+ +// #region Bar Extensions ... +/** + * Check Specified Bar is Breaked or not ... + * + * @param bar: XOHCL, Specified Bar for Checking Proce ... + * @param breakerBar: XOHCL, Hold's Breaker Bar if Exists ... + * @param barIndex: int, Start Checking Bar till Bar's Index ... + * @param breakDir: ENUM_X_DIRECTION, Checking Direction Type, if Bullish Break Price must bigger, otherwise must lower ... + * @param barPriceType: ENUM_X_PRICE, Price type to Check Break ... + * @param breakPriceType: ENUM_X_PRICE, Price Type to Break Bar's Price ... + * + * @return ( bool ) + */ +bool IsBarBreaked( + XOHCL &bar, + XOHCL &breakerBar, + int barIndex = 0, + ENUM_X_DIRECTION breakDir = X_DIRECTION_NONE, + ENUM_X_PRICE barPriceType = X_PRICE_CLOSE, + ENUM_X_PRICE breakPriceType = X_PRICE_CLOSE // +) +{ + // + bool result = false; + + // + // Normalize ... + breakerBar.Clean(); + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Validate ... + result = + bar.IsValid() && + HasDirection(breakDir) && + IsXValid(barPriceType) && + IsXValid(breakPriceType) && + barIndex < bar.Index(); + if (!result) + { + return result; + } + + // + // Loop for Validating ... + XOHCL tmpBar; + bool has = false; + double tmpPrice = EMPTY_VALUE; + double barPrice = bar.GetPrice(barPriceType); + for (int i = barIndex; i < bar.Index(); i++) + { + // + has = tmpBar.Init(bar.symbol, bar.period, i); + if (!has) + { + continue; + } + + // + tmpPrice = tmpBar.GetPrice(breakPriceType); + has = NotEmptyZero(tmpPrice); + if (!has) + { + // + tmpBar.Clean(); + + // + continue; + } + + // + has = + IsXBullish(breakDir) + ? tmpPrice > barPrice + : tmpPrice < barPrice; + if (has) + { + // + breakerBar = tmpBar; + tmpBar.Clean(); + break; + } + + // + tmpBar.Clean(); + } + + // + result = breakerBar.IsValid(); + + // + return result; +} +// #endregion + // \ No newline at end of file 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 4f7ace0e..bc131edd 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 @@ -151,6 +151,9 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector // Here We have to Detect Zones ... // Preparing Loops ... XOHCL tmpBar; + XOHCL tmpFVGBar; + XBoxZone tmpFVG; + XOHCL tmpZoneBar; bool has = false; double upper = 0; double lower = 0; @@ -190,61 +193,178 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector continue; } + // + // Prepare Zone Bar ... + has = tmpZoneBar.Init(tmpBar.symbol, tmpBar.period, i + tmpCount + 1); + has = has && + tmpZoneBar.GetDirection() == XOpposit(tmpDir); + if (!has) + { + // + tmpCount = 0; + tmpBar.Clean(); + tmpZoneBar.Clean(); + tmpDir = X_DIRECTION_NONE; + + // + continue; + } + + // + // Validate Price Based on Zone Bar ... + XOHCL breakerBar; + has = !IsBarBreaked( + tmpZoneBar, + breakerBar, + start, // Bar Index to Start Price Validation ... + X_DIRECTION_BEARISH, // Demand Zones Must Breaked Bearish for Invalidating ... + X_PRICE_LOW, // Bars Price to Validate ... + X_PRICE_LOW // Breaker Bar Price for Validation ... + ); + if (!has) + { + // + tmpCount = 0; + tmpBar.Clean(); + tmpZoneBar.Clean(); + breakerBar.Clean(); + tmpDir = X_DIRECTION_NONE; + + // + continue; + } + + // + // Validate FVG Exists ... + for (int j = tmpZoneBar.Index(); j > tmpBar.Index(); j--) + { + // + has = tmpFVGBar.Init(tmpBar.symbol, tmpBar.period, j); + if (!has) + { + continue; + } + + // + has = barAnalyser.IsFVG( + tmpFVGBar, + tmpFVG, + true // Force Type ... + ); + has = has && + tmpFVG.IsBullish(); + + // + // Validate FVG Gap if required ... + if (has && minFVGAllowedPoints > 0) + { + // + double pointsDistance = GetXPoints(tmpBar.symbol) * minFVGAllowedPoints; + has = has && + MathAbs(tmpFVG.upper - tmpFVG.lower) > pointsDistance; + } + + // + if (has) + { + break; + } + + // + tmpFVG.Clean(); + tmpFVGBar.Clean(); + } + + // + // Check Breake Of Structure ... + int structureIndex = -1; + int prevStructureIndex = -1; + int structureLength = tmpZoneBar.Index() - tmpBar.Index(); + double structurePrice = tmpBar.FindHighest( + structureIndex, + structureLength, + X_PRICE_HIGH // + ); + double prevStructurePrice = tmpZoneBar.FindHighest( + prevStructureIndex, + structureLength, + X_PRICE_HIGH // + ); + has = + NotEmptyZero(structurePrice) && + NotEmptyZero(prevStructurePrice) && + structurePrice > prevStructurePrice; + if (!has) + { + // + tmpCount = 0; + tmpBar.Clean(); + tmpFVG.Clean(); + tmpFVGBar.Clean(); + tmpZoneBar.Clean(); + breakerBar.Clean(); + tmpDir = X_DIRECTION_NONE; + + // + continue; + } + + // + // Validate Market Structure ... + structureIndex = -1; + prevStructureIndex = -1; + structurePrice = tmpBar.FindLowest( + structureIndex, + structureLength, + X_PRICE_LOW // + ); + prevStructurePrice = tmpZoneBar.FindHighest( + prevStructureIndex, + structureLength, + X_PRICE_LOW // + ); + has = + NotEmptyZero(structurePrice) && + NotEmptyZero(prevStructurePrice) && + structurePrice < prevStructurePrice; + if (!has) + { + // + tmpCount = 0; + tmpBar.Clean(); + tmpFVG.Clean(); + tmpFVGBar.Clean(); + tmpZoneBar.Clean(); + breakerBar.Clean(); + tmpDir = X_DIRECTION_NONE; + + // + continue; + } + + // + // Validating Confluence if Provided ... + if (confluence > 0 && confluenceLoopback > 0) { + // + for (int j = tmpZoneBar.Index(); j < tmpZoneBar.Index() + confluenceLoopback; j++) { + + } + } + + // DebugBreak(); // // Cleanup Resources ... + // tmpCount = 0; tmpBar.Clean(); + tmpFVG.Clean(); + tmpFVGBar.Clean(); + tmpZoneBar.Clean(); + breakerBar.Clean(); tmpDir = X_DIRECTION_NONE; - - // - - // if (has) - // { - // // - // // Next Step is Detect Sequence Same Directional Bars ... - // has = HasSameBars(tmpBar, tmpDir, tmpCount, minAllowedSameDirectionalBars); - // if (has) - // { - // // - // // Zone Bar ... - // XOHCL zoneBar; - // has = zoneBar.Init(tmpBar.symbol, tmpBar.period, i + tmpCount + 1); - - // // - // // Validate Zone Bar Direction ... - // has = has && - // zoneBar.GetDirection() != tmpBar.GetDirection(); - // if (has) - // { - // // - // // Validate FVG Exists ... - // CollectFVGs(tmpBar, tmpFVGs, 5, 0, zoneBar.Index() - tmpBar.Index()); - // FilterZones(tmpBar, tmpFVGs, tmpBar.GetDirection(), X_PRICE_CLOSE, tmpBar.GetDirection()); - // has = ArraySize(tmpFVGs) > 0; - // if (has && minFVGAllowedPoints > 0) - // { - // // - // // Validate FVG Gap - // } - - // // - // if (has) - // { - // DebugBreak(); - // } - // } - - // // - // zoneBar.Clean(); - // } - - // // - // tmpBar.Clean(); - - // } } //