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); }