// // Detectors ... /** * Detect Zones (Support / Resistance) based on XFIMA Validators ... * * @param zones: XBoxZone, reference to Collection for holding Detected Zones ... * @param barIndex: int, Specified Start Looking Bar Index ... * @param onlyValidZones: bool, Only Validation Zones ... * @param requiredNumberOfZones: int, Specified how many zones looking for ... * @param shadowMultiplier: double, a valid zone's Shadow side multiplier ... * @param validationStrength: double, Validation Strength ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ... * * @return ( int ) */ int DetectXFIMAZones( XBoxZone &zones[], int barIndex = 0, bool onlyValidZones = false, int requiredNumberOfZones = 50, double shadowMultiplier = 4, double validationStrength = 1, int validationLength = 7, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // // Prepare ... XClean(zones); // // Normalize ... barIndex = NormalizeBarIndex(barIndex); validationLength = NormalizeInt(validationLength, 3); shadowMultiplier = NormalizeDouble(shadowMultiplier, 2); validationStrength = NormalizeDouble(validationStrength, 1); requiredNumberOfZones = NormalizeInt(requiredNumberOfZones, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // // Validate ... XOHCL bar; bool has = IsValid() && bar.Init( mSymbol, mPeriod, barIndex + 1 // ); if (!has) { return result; } // // Define Requirements ... XOHCL iBar; XBoxZone iBox; bool isBullish = false; bool isBearish = false; double iUpper = EMPTY_VALUE; double iLower = EMPTY_VALUE; double iHKUpper = EMPTY_VALUE; double iHKLower = EMPTY_VALUE; double iMAUpper = EMPTY_VALUE; double iMALower = EMPTY_VALUE; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // // Create a Loop to Detect Zones ... int start = barIndex; int idx = start - 1; int end = start + maxAllowedLoopbackLength; while (ArraySize(zones) < requiredNumberOfZones && idx < end) { // idx++; // // Initialize Indexed Bar ... has = bar.BarAt(idx, iBar); if (!has) { continue; } // // Reading Bars ... iMAUpper = GetMABondUpper(idx); iMALower = GetMABondLower(idx); iHKUpper = GetHKBondUpper(idx); iHKLower = GetHKBondLower(idx); // iUpper = MathMax(iMAUpper, iHKUpper); iLower = MathMin(iMALower, iHKLower); // // Check Bar State ... has = NotEmptyZero(iUpper) && NotEmptyZero(iLower); if (!has) { continue; } // // Check Direction of Zone ... isBullish = iBar.low < iLower; isBearish = iBar.high > iUpper; has = (isBullish && !isBearish) || (isBearish && !isBullish); if (!has) { continue; } // // Validate Price Based on Bar ... // Validate Shadow Multiplier ... has = isBullish ? iBar.low < bar.low : iBar.high > bar.high; has = has && (isBullish ? iBar.GetLowShadow() > iBar.GetHighShadow() * shadowMultiplier : iBar.GetHighShadow() > iBar.GetLowShadow() * shadowMultiplier); if (!has) { continue; } // iDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // // Fill Bax ... iBox.dir = iDir; iBox.symbol = mSymbol; iBox.period = mPeriod; iBox.upper = isBullish ? iBar.GetDown() : iBar.high; iBox.lower = isBullish ? iBar.low : iBar.GetUp(); iBox.type = (isBullish ? "XFIMA_Support" : "XFIMA_Resistance") + "_" + ToXString(NormalizePrice(iBox.upper, iBox.symbol)) + "_" + ToXString(NormalizePrice(iBox.lower, iBox.symbol)); // iBox.at = iBar.time; iBox.to = bar.time; // // Loopback to Detect From Time ... XOHCL pBar; datetime fromTime = NULL; has = iBar.GetPreviousBar(pBar); if (has) { // while (!IsXValid(fromTime)) { // // Check Price Inside ... has = isBullish ? pBar.GetDown() < iBox.lower : pBar.GetUp() > iBox.upper; if (has) { fromTime = pBar.time; } // // Retrieve PrevBar ... has = pBar.GetPreviousBar(pBar); if (!has) { break; } } } has = IsXValid(fromTime); if (has) { iBox.from = fromTime; } // // Validate Zone Length ... has = iBox.IsValid() && (validationStrength >= 1 ? iBox.GetRange() >= validationStrength * GetPoints(iBox.symbol) : true) && (iBox.FromIndex() - iBox.AtIndex() >= validationLength); // // Validate Zone State ... if (has) { // // Cleanup Bar ... iBar.Clean(); // // Loopingh through At Index ... for (int i = iBox.ToIndex(); i < iBox.AtIndex(); i++) { // // Initialized Indexed Bar ... has = bar.BarAt(i, iBar); if (!has) { break; } // // Validate Bar ... has = iBox.IsBullish() ? iBar.low > iBox.lower : iBar.high < iBox.upper; if (!has) { break; } } } // if (has) { // AddIfNotExists( iBox, zones // ); } // // Cleanup Resources ... iBar.Clean(); pBar.Clean(); iBox.Clean(); } // result = ArraySize(zones); // // Cleanup Resources ... if (!result) { XClean(zones); } bar.Clean(); iBar.Clean(); iBox.Clean(); // return result; } int DetecteXFIMAPivots( XPivot &pivots[], int barIndex = 0, int requiredNumberOfPivots = 50, int validationLength = 7, int maxAllowedLoopbackLength = 1500, // // // PV ... int pvValidationLength = 7, // // Momentum ... int momentumBarValidationLength = 3, double momentumBarApprovedMultiplier = 3, // // TrueGap ... double trueGapApprovedStrength = 2, // // Pin ... double pinBarShadowApprovedMultiplier = 3, double pinBarRangeMultiplier = 4, bool pinBarForceDirection = false, // // Flag ... int flagPatternPullbackLength = 3 // ) { // int result = 0; // // Prepare ... XClean(pivots); // // Normalize ... barIndex = NormalizeBarIndex(barIndex); validationLength = NormalizeInt(validationLength, 1); requiredNumberOfPivots = NormalizeInt(requiredNumberOfPivots, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // pvValidationLength = NormalizeInt(pvValidationLength, 0); // momentumBarValidationLength = NormalizeInt(momentumBarValidationLength, 2); momentumBarApprovedMultiplier = NormalizeDouble(momentumBarApprovedMultiplier, 1); // trueGapApprovedStrength = NormalizeDouble(trueGapApprovedStrength, 1); // pinBarRangeMultiplier = NormalizeDouble(pinBarRangeMultiplier, 4); pinBarShadowApprovedMultiplier = NormalizeDouble(pinBarShadowApprovedMultiplier, 3); // flagPatternPullbackLength = NormalizeInt(flagPatternPullbackLength, 3); // // Validate ... bool has = IsValid(); if (!has) { return result; } // XOHCL iBar; XOHCL tmpBar; XPivot iPivot; int count = 0; string iPrefix = NULL; int idx = barIndex - 1; double iMin = EMPTY_VALUE; double iMax = EMPTY_VALUE; double iValue = EMPTY_VALUE; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; int end = barIndex + maxAllowedLoopbackLength; while ( idx < end && ArraySize(pivots) < requiredNumberOfPivots) { // idx++; // iBar.Clean(); iPivot.Clean(); tmpBar.Clean(); iPrefix = NULL; iDir = X_DIRECTION_NONE; // has = iBar.Init( mSymbol, mPeriod, idx // ); if (!has) { break; } // // Pivots List ... // // PV ... bool isPV = false; bool isPeak = false; bool isVale = false; tmpDir = X_DIRECTION_NONE; if (pvValidationLength > 0) { // isPV = patternDetector.IsPV( iBar, tmpDir, pvValidationLength // ); isPeak = isPV && IsXBearish(tmpDir); isVale = isPV && IsXBullish(tmpDir); if (isPV) { iPrefix += isPeak ? "XPK" : "XVL"; } // // Continue Loopback if PV Validation Provided and not isPV ... if (!isPV) { continue; } } // // Momentum Bar ... bool isMomentum = patternDetector.IsMomentumBar( iBar, iDir, momentumBarValidationLength, momentumBarApprovedMultiplier // ); if (isMomentum) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isMomentum = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "MNTM"; } } // // Engulf Bar ... bool isEngulfed = patternDetector.IsEngulfedBar( iBar, iDir // ); if (isEngulfed) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isEngulfed = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "ENGLF"; } } // // True Gap ... bool isTrueGaped = patternDetector.IsTrueGapedBar( iBar, iDir, trueGapApprovedStrength // ); if (isTrueGaped) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isTrueGaped = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "TG"; } } // // Pin Bar ... bool isPinned = patternDetector.IsPinnedBar( iBar, iDir, pinBarShadowApprovedMultiplier, pinBarRangeMultiplier, pinBarForceDirection // ); if (isPinned) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isPinned = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PND"; } } // // Patterns ... // // Star Pattern ... bool isStarPattern = patternDetector.IsStarPattern( iBar, iDir // ); if (isStarPattern) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isStarPattern = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "STR"; } } // // Piercing Pattern ... bool isPiercingPattern = patternDetector.IsPiercingPattern( iBar, iDir // ); if (isPiercingPattern) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isPiercingPattern = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PRCG"; } } // // Rising Pattern ... bool isRisingPattern = patternDetector.IsRisingPattern( iBar, iDir // ); if (isRisingPattern) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isRisingPattern = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "RSG"; } } // // Flag Pattern ... bool isFlagPattern = patternDetector.IsFlagPattern( iBar, iDir, tmpBar, flagPatternPullbackLength // ); if (isFlagPattern) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isFlagPattern = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "FLG"; } } // // Signal Key Pattern ... bool isSignalKeyPattern = patternDetector.IsSignalKeyBarPattern( iBar, iDir, pinBarShadowApprovedMultiplier, pinBarRangeMultiplier, pinBarForceDirection // ); if (isSignalKeyPattern) { // if (!IsXValid(tmpDir)) { tmpDir = iDir; } // if (iDir != tmpDir) { isSignalKeyPattern = false; } else { // count++; iPrefix += (IsXValid(iPrefix) ? "_" : "") + "SKB"; } } // has = isPinned || isMomentum || isEngulfed || isTrueGaped || isStarPattern || isFlagPattern || isRisingPattern || isPiercingPattern || isSignalKeyPattern; if (!has) { continue; } // // // // Validate Pivot Length ... // // Validate Pivot vs XFIMA Values ... // for (int i = iBar.Index(); i < iBar.Index() + validationLength; i++) // { // // // tmpBar.Clean(); // has = iBar.BarAt(i, tmpBar); // if (!has) // { // break; // } // // // iMin = EMPTY_VALUE; // iMax = EMPTY_VALUE; // has = GetBoundaryValues( // iMin, // iMax, // i // // ); // // // // Validate Bar vs TmpBar and Also Boundary Values ... // has = // has && // (IsXBullish(iDir) // ? // // tmpBar.low < iMin && // (tmpBar.low > iBar.low || // tmpBar.GetDown() || iBar.GetDown()) // : // // tmpBar.high > iMax && // (tmpBar.high < iBar.high || // tmpBar.GetUp() < iBar.GetUp())); // if (!has) // { // break; // } // // // iValue = IsXBullish(iDir) // ? iBar.low // : iBar.high; // // // iType = IsXBullish(iDir) // ? X_PIVOT_TYPE_VALE // : X_PIVOT_TYPE_PEAK; // // // tmpBar.Clean(); // } // has = IsXValid(iPrefix); if (has) { // iValue = IsXBullish(iDir) ? iBar.low : iBar.high; // iType = IsXBullish(iDir) ? X_PIVOT_TYPE_VALE : X_PIVOT_TYPE_PEAK; // // Preparing Pivot ... has = iPivot.Init( iValue, iBar.time, iBar.symbol, iDir, iBar.period, iType // ); if (has) { // iPivot.prefix = iPrefix; // AddIfNotExists( iPivot, pivots // ); } } // } // // Cleanup Resources ... iBar.Clean(); iPivot.Clean(); tmpBar.Clean(); // result = ArraySize(pivots); // return result; } /** * Detect XFIMA Based POI Bars ... * * @param bars: XOHCL, reference collection to holds detected bars ... * @param dirs: ENUM_X_DIRECTION, reference collection to holds detected bars Direction ... * @param barIndex: int, Specified Bar Index ... * @param forDir: ENUM_X_DIRECTION, specified which Direction of potential bars looking for ... * @param requiredNumberOfBars: int, Specified how many bars looking for ... * @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ... * @return ( int ) */ int DetectXFIMAPOIBars( XOHCL &bars[], ENUM_X_DIRECTION &dirs[], int barIndex = 0, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, int requiredNumberOfBars = 300, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // // Prepare ... XClean(bars); XClean(dirs); // // Normalize ... barIndex = NormalizeBarIndex(barIndex); requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // // Validate ... bool has = IsValid(); if (!has) { return result; } // XOHCL iBar; int idx = barIndex - 1; int start = barIndex; bool isBullish = false; bool isBearish = false; double iMin = EMPTY_VALUE; double iMax = EMPTY_VALUE; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; int end = start + maxAllowedLoopbackLength; while (ArraySize(bars) < requiredNumberOfBars || idx < maxAllowedLoopbackLength) { // idx++; has = iBar.Init( mSymbol, mPeriod, idx // ); if (!has) { continue; } // has = GetBoundaryValues( iMin, iMax, idx // ); if (!has) { continue; } // isBullish = iBar.low < iMin; isBearish = iBar.high > iMax; has = !HasDirection(forDir) ? ((isBullish && !isBearish) || (isBearish && !isBullish)) : IsXBullish(forDir) ? (isBullish && !isBearish) : (isBearish && !isBullish); if (has) { // iDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // AddRef( iBar, bars // ); // Add( iDir, dirs // ); } } // result = ArraySize(bars); // // Cleanup Resources ... iBar.Clean(); // return result; } int DetectXFIMAReversalPOIBars( XOHCL &bars[], ENUM_X_DIRECTION &dirs[], int barIndex = 0, bool forceTouchBoundary = false, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, int requiredNumberOfBars = 300, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // // Prepare ... XClean(bars); XClean(dirs); // // Normalize ... barIndex = NormalizeBarIndex(barIndex); requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // // Validate ... bool has = IsValid(); if (!has) { return result; } // // Detect POI Bars ... XOHCL decisionBars[]; ENUM_X_DIRECTION decisionBarDirs[]; int decisionBarsCount = DetectXFIMAPOIBars( decisionBars, decisionBarDirs, barIndex, forDir, requiredNumberOfBars, maxAllowedLoopbackLength // ); has = IsValidSize(decisionBarsCount); if (!has) { // XClean(decisionBars); XClean(decisionBarDirs); // return result; } // bool isBullish = false; bool isBearish = false; double iMin = EMPTY_VALUE; double iMax = EMPTY_VALUE; bool isCond1Bullish = false; bool isCond1Bearish = false; for (int i = 0; i < decisionBarsCount; i++) { // // Read Boundary Values ... has = GetBoundaryValues(iMin, iMax, i); if (!has) { continue; } // // Check Bar Decision Direction ... isBullish = IsXBullish(decisionBarDirs[i]); isBearish = IsXBearish(decisionBarDirs[i]); // // Validate ... // isCond1Bullish = decisionBars[i].IsBullish(); // isCond1Bearish = decisionBars[i].IsBearish(); // isBullish = isBullish && (isCond1Bullish); // isBearish = isBearish && (isCond1Bearish); // if (forceTouchBoundary) { // isBullish = isBullish && (decisionBars[i].high > iMin || decisionBars[i].GetUp() > iMin); // isBearish = isBearish && (decisionBars[i].low < iMax || decisionBars[i].GetDown() < iMax); } // has = isBullish || isBearish; if (has) { // AddRef( decisionBars[i], bars // ); // Add( decisionBarDirs[i], dirs // ); } } // result = ArraySize(bars); // // Cleanup Resources ... XClean(decisionBars); XClean(decisionBarDirs); // return result; } int DetectXFIMAContinuationalPOIBars( XOHCL &bars[], ENUM_X_DIRECTION &dirs[], int barIndex = 0, bool forceTouchBoundary = false, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, int requiredNumberOfBars = 300, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // // Prepare ... XClean(bars); XClean(dirs); // // Normalize ... barIndex = NormalizeBarIndex(barIndex); requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // // Validate ... bool has = IsValid(); if (!has) { return result; } // // Detect POI Bars ... XOHCL decisionBars[]; ENUM_X_DIRECTION decisionBarDirs[]; int decisionBarsCount = DetectXFIMAPOIBars( decisionBars, decisionBarDirs, barIndex, forDir, requiredNumberOfBars, maxAllowedLoopbackLength // ); has = IsValidSize(decisionBarsCount); if (!has) { // XClean(decisionBars); XClean(decisionBarDirs); // return result; } // bool isBullish = false; bool isBearish = false; double iMin = EMPTY_VALUE; double iMax = EMPTY_VALUE; bool isCond1Bullish = false; bool isCond1Bearish = false; for (int i = 0; i < decisionBarsCount; i++) { // // Read Indexed Bars Boundaries ... has = GetBoundaryValues(iMin, iMax, decisionBars[i].Index()); if (!has) { continue; } // // Make Direction Opposit ... decisionBarDirs[i] = Opposit(decisionBarDirs[i]); // isBullish = IsXBullish(decisionBarDirs[i]); isBearish = IsXBearish(decisionBarDirs[i]); // // Check Bar Validations ... // // Cond 1 ... // isCond1Bullish = decisionBars[i].IsBearish() && (decisionBars[i].low >= iMax || (decisionBars[i].low <= iMax && decisionBars[i].GetUp() >= iMax)); // isCond1Bearish = decisionBars[i].IsBullish() && (decisionBars[i].high <= iMin || (decisionBars[i].high >= iMin && decisionBars[i].GetDown() <= iMin)); // isBullish = isBullish && (isCond1Bullish); // isBearish = isBearish && (isCond1Bearish); // if (forceTouchBoundary) { // isBullish = isBullish && (decisionBars[i].low >= iMax || (decisionBars[i].low <= iMax && decisionBars[i].GetUp() >= iMax)); // isBearish = isBearish && (decisionBars[i].high <= iMin || (decisionBars[i].high >= iMin && decisionBars[i].GetDown() <= iMin)); } // has = isBullish || isBearish; if (has) { // AddRef( decisionBars[i], bars // ); // Add( decisionBarDirs[i], dirs // ); } } // result = MathMin(ArraySize(bars), ArraySize(dirs)); // // Cleanup Resources ... XClean(decisionBars); XClean(decisionBarDirs); // return result; }