/** * Analyse Market based on Specified Bar ... * * @param forBar: XOHCL, reference Specified Bar for Analyse Market ... * @param structure: XFIMAMarketStructure, reference to holds result ... * @param config: XFIMAPatternDetectorConfig, reference to Configure Detector ... */ void AnalyseMarket( XOHCL &forBar, XFIMAMarketStructure &structure, XFIMAPatternDetectorConfig &config // ) { // // Prepare ... structure.Clean(); // // Validate ... if (!forBar.IsValid()) { return; } // // Do Analysis ... // structure.bar = forBar; // int idx = -1; bool has = false; int maxAllowedCollecting = 50; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // // Detecting POI Based on Config ... // // Order Block ... if (config.detectOB) { // bool isOB = HasOB( forBar, iDir, structure.ob, config.obLoopback // ); bool isBullishOB = isOB && IsSpecifiedBullish(iDir); bool isBearishOB = isOB && IsSpecifiedBearish(iDir); if (!isOB) { structure.ob.Clean(); } // // Detect Touches ... if (isOB) { // AddIfNotExists( structure.ob, obs, maxAllowedCollecting // ); // XOHCL pBar; bool has = forBar.GetPreviousBar(pBar); if (has) { // structure.isOBTouched = isBullishOB ? pBar.low < structure.ob.upper : pBar.high > structure.ob.lower; } // pBar.Clean(); } } // // Fair Value Gap ... if (config.detectFVG) { // bool isFVG = HasFVG( forBar, iDir, structure.fvg, config.fvgLoopback // ); bool isBullishFVG = isFVG && IsSpecifiedBullish(iDir); bool isBearishFVG = isFVG && IsSpecifiedBearish(iDir); if (!isFVG) { structure.fvg.Clean(); } // // Detect Touches ... if (isFVG) { // AddIfNotExists( structure.fvg, fvgs, maxAllowedCollecting // ); // XOHCL pBar; bool has = forBar.GetPreviousBar(pBar); if (has) { // structure.isFVGTouched = isBullishFVG ? pBar.low < structure.fvg.upper : pBar.high > structure.fvg.lower; } // pBar.Clean(); } } // // Checking Momentum Bar ... if (config.detectMomentum) { // bool isMomentum = IsMomentumBar( forBar, iDir, config.momentumBarRangeLength, config.momentumBarApprovedMultiplier // ); bool isBullishMomentum = isMomentum && IsSpecifiedBullish(iDir); bool isBearishMomentum = isMomentum && IsSpecifiedBearish(iDir); if (isMomentum) { structure.momentumDir = iDir; } } // // Checking Engulfed Bar ... if (config.detectEngulfed) { // bool isEngulfed = IsEngulfedBar( forBar, iDir // ); bool isBullishEngulfed = isEngulfed && IsSpecifiedBullish(iDir); bool isBearishEngulfed = isEngulfed && IsSpecifiedBearish(iDir); if (isEngulfed) { structure.engulfedDir = iDir; } } // // Checking TruGaped Bar ... if (config.detectTrueGaped) { // bool isTrueGaped = IsTrueGapedBar( forBar, iDir, config.truwGapApprovedPointMultiplier // ); bool isBullishTrueGaped = isTrueGaped && IsSpecifiedBullish(iDir); bool isBearishTrueGaped = isTrueGaped && IsSpecifiedBearish(iDir); if (isTrueGaped) { structure.trueGapedDir = iDir; } } // // Checking Pinned Bar ... if (config.detectPinned) { // bool isPinned = IsPinnedBar( forBar, iDir, config.pinnedBaarShadowApprovedMultiplier, config.pinnedBarMinimumPinBarRangeMultiplier, config.pinnedBarForceDirection // ); bool isBullishPinned = isPinned && IsSpecifiedBullish(iDir); bool isBearishPinned = isPinned && IsSpecifiedBearish(iDir); if (isPinned) { structure.pinnedDir = iDir; } } // // Checking Star Pattern ... if (config.detectStarPattern) { // bool isStarPattern = IsStartPattern( forBar, iDir // ); bool isBullishStarPattern = isStarPattern && IsSpecifiedBullish(iDir); bool isBearishStarPattern = isStarPattern && IsSpecifiedBearish(iDir); if (isStarPattern) { structure.starPatternDir = iDir; } } // // Checking Piercing Pattern ... if (config.detectPiercingPattern) { // bool isPiercingPattern = IsPiercingPattern( forBar, iDir // ); bool isBullishPiercingPattern = isPiercingPattern && IsSpecifiedBullish(iDir); bool isBearishPiercingPattern = isPiercingPattern && IsSpecifiedBearish(iDir); if (isPiercingPattern) { structure.piercingPatternDir = iDir; } } // // Checking Rising Pattern ... if (config.detectRisingPattern) { // bool isRisingPattern = IsRisingPattern( forBar, iDir // ); bool isBullishRisingPattern = isRisingPattern && IsSpecifiedBullish(iDir); bool isBearishRisingPattern = isRisingPattern && IsSpecifiedBearish(iDir); if (isRisingPattern) { structure.risingPatternDir = iDir; } } // // Checking Flag Pattern ... if (config.detectFlagPattern) { // XOHCL swingBar; bool isFlagPattern = IsFlagPattern( forBar, iDir, swingBar, config.flagPatternMinimumPullbackBars // ); bool isBullishFlagPattern = isFlagPattern && IsSpecifiedBullish(iDir); bool isBearishFlagPattern = isFlagPattern && IsSpecifiedBearish(iDir); if (isFlagPattern) { // structure.flagSwing = swingBar; structure.flagPatternDir = iDir; } swingBar.Clean(); } // // Detect SignalKey Bar Pattern ... if (config.detectSignalKeyBarPattern) { // bool isSignalKeyBar = IsSignalKeyBarPattern( forBar, iDir, config.signalKeyBarShadowApprovedMultiplier, config.signalKeyBarMinimumPinBarRangeMultiplier, config.signalKeyBarForceDirection // ); bool isBullishSignalKeyBar = isSignalKeyBar && IsSpecifiedBullish(iDir); bool isBearishSignalKeyBar = isSignalKeyBar && IsSpecifiedBearish(iDir); if (isSignalKeyBar) { structure.signalKeyBarPatternDir = iDir; } } // // Detect Swing Trend ... if (config.detectSwingTrend) { // XOHCL swings[]; bool hasSwingTrend = HasSwingTrend( forBar, iDir, swings, config.trendingNumberOfSwings, config.trendingSwingShoulders // ); bool hasBullishSwingTrend = hasSwingTrend && IsSpecifiedBullish(iDir); bool hasBearishSwingTrend = hasSwingTrend && IsSpecifiedBearish(iDir); if (hasSwingTrend) { // Copy( swings, structure.trendSwings // ); structure.trendDir = iDir; } SpecifiedClean(swings); } // // Detect Supports ... if (config.detectSupport) { // XOHCL support; bool hasSupport = HasSupport( forBar, support, config.supportAndResistanceValidationLength, config.supportAndResistanceMaxAllowedLoopback // ); if (hasSupport) { // XBoxZone supportBox; has = ToSupportBox(support, supportBox); // // Validate Zone Strength if Provided ... if (config.minAllowdSupportAndResistanceStrength > 0) { // has = has && ValidateStrength( supportBox, config.minAllowdSupportAndResistanceStrength // ); } // if (has) { // AddIfNotExists( supportBox, supports, maxAllowedCollecting // ); // structure.support = supportBox; } // // Check for Support Touches ... XOHCL pBar; has = has && forBar.GetPreviousBar(pBar); if (has) { structure.isSupportTouched = pBar.low < supportBox.upper; } // pBar.Clean(); supportBox.Clean(); } support.Clean(); } // // Detect Resistance ... if (config.detectResistance) { // XOHCL resistance; bool hasResistance = HasResistance( forBar, resistance, config.supportAndResistanceValidationLength, config.supportAndResistanceMaxAllowedLoopback // ); if (hasResistance) { // XBoxZone resistanceBox; has = ToResistanceBox(resistance, resistanceBox); // // Validate Zone Strength if Provided ... if (config.minAllowdSupportAndResistanceStrength > 0) { // has = has && ValidateStrength( resistanceBox, config.minAllowdSupportAndResistanceStrength // ); } // if (has) { // AddIfNotExists( resistanceBox, resistances, maxAllowedCollecting // ); // structure.resistance = resistanceBox; } // // Check for Resistance Touches ... XOHCL pBar; has = has && forBar.GetPreviousBar(pBar); if (has) { structure.isResistanceTouched = pBar.high > resistanceBox.upper; } // pBar.Clean(); resistanceBox.Clean(); } resistance.Clean(); } // // Analysers ... // // Analyse Based on PV ... if (config.analyseFIMAPVPivots) { // XPivotAnalysis analysis; has = AnalysePVPivots( analysis, // Result ... forBar.Index(), // Bar Index ... config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ... config.pvPivotsValidationLength // Validation Length ... ); if (has) { structure.pvAnalysis = analysis; } } // // Analyse Based on MA ... if (config.analyseFIMAMAPivots) { // XPivotAnalysis analysis; has = AnalyseMAPivots( analysis, // Result ... forBar.Index(), // Bar Index ... config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ... config.pvPivotsValidationLength // Validation Length ... ); if (has) { structure.maAnalysis = analysis; } } // // Analyse Based on SAR ... if (config.analyseFIMASARPivots) { // XPivotAnalysis analysis; has = AnalyseSARPivots( analysis, // Result ... forBar.Index(), // Bar Index ... config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ... ); if (has) { structure.sarAnalysis = analysis; } } // // Analyse Based on ZigZag ... if (config.analyseFIMAZigZagPivots) { // XPivotAnalysis analysis; has = AnalyseZigZagPivots( analysis, // Result ... forBar.Index(), // Bar Index ... config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ... ); if (has) { structure.zigzagAnalysis = analysis; } } // // COMPLEX Actions ... // // Lockup For Previous Zone ... has = structure.isSupportTouched || structure.isResistanceTouched; if (has) { // if (structure.isSupportTouched) { // idx = GetYoungestBefore( structure.support.from, supports // ); has = IsValidIndex(idx); if (has) { structure.prevZone = supports[idx]; } } else if (structure.isResistanceTouched) { // idx = GetYoungestBefore( structure.resistance.from, resistances // ); has = IsValidIndex(idx); if (has) { structure.prevZone = resistances[idx]; } } } // // Detect Recently Tested Zones ... if ((config.detectSupport || config.detectResistance) && config.recentlyTestedZonesMaxLookup > 0) { // XOHCL iBar; int idx = -1; bool has = false; // int start = forBar.Index() + 1; int end = start + config.recentlyTestedZonesMaxLookup; for (int i = start; i < end; i++) { // // Initialize Indexed Bar ... has = forBar.BarAt(i, iBar); if (!has) { continue; } // // Selecting Support and Resistances ... // // Supports ... idx = GetYoungestBefore(iBar.time, supports); has = IsValidIndex(idx); if (has) { // // Check Testing ... has = IsTested(iBar, supports[idx]); if (has) { // AddIfNotExists( supports[idx], structure.recentlyTestedZones // ); } } // // Resistances ... idx = GetYoungestBefore(iBar.time, resistances); has = IsValidIndex(idx); if (has) { // // Check Testing ... has = IsTested(iBar, resistances[idx]); if (has) { // AddIfNotExists( resistances[idx], structure.recentlyTestedZones // ); } } } } // // Checkup for FakeBreaked Zones ... if (config.detectSupport || config.detectResistance) { // // Retrieve Previous Bar ... int idx = -1; XOHCL pForBar; XOHCL breakerBar; XBoxZone pSupport; XOHCL pBreakerBar; XBoxZone pResistance; // // Selecting Previously Touched Support / Resistance ... has = forBar.GetPreviousBar(pForBar); if (has) { // // Detecting Nearest Above Lows Support ... idx = GetYoungestAbove( pForBar.low, supports // ); has = IsValidIndex(idx) && IsBreaked( forBar, supports[idx] // ); if (has) { pSupport = supports[idx]; } // // Detecting Nearest Below Highs Resistance ... idx = GetYoungestBelow( pForBar.high, resistances // ); has = IsValidIndex(idx) && IsBreaked( forBar, resistances[idx] // ); if (has) { pResistance = resistances[idx]; } } // // Check at least a zone Exists ... // Selecting pTestedZone ... has = pSupport.IsValid() || pResistance.IsValid(); if (has) { // // Support ... has = pSupport.IsValid(); if (has) { // structure.isPTest = true; structure.pTestedZone = pSupport; } // // Resistance ... has = pResistance.IsValid(); if (has) { // structure.isPTest = true; structure.pTestedZone = pResistance; } } // // Check pTestedZone Existance ... has = structure.isPTest && structure.pTestedZone.IsValid(); if (has) { // // Get Breaker Bars ... XOHCL breakerBars[]; int breakerBarsCount = GetBreakerBars( structure.pTestedZone, breakerBars // ); has = IsValidSize(breakerBarsCount); if (has) { // idx = GetYoungestBar(breakerBars); has = IsValidIndex(idx); if (has) { breakerBar = breakerBars[idx]; } } // SpecifiedClean(breakerBars); } // // Check Zone Breaker Bar Exists ... // Validate Zone Fake Breake Langth ... has = breakerBar.IsValid(); if (has) { // // Validate Breake Length ... has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength; } // // Cleanup Resources ... // if (!has) { // structure.isPTest = false; structure.pTestedZone.Clean(); } pForBar.Clean(); pSupport.Clean(); breakerBar.Clean(); pBreakerBar.Clean(); pResistance.Clean(); } } // // Lockup For Previous Zone ... has = structure.isSupportTouched || structure.isResistanceTouched; if (has) { // if (structure.isSupportTouched) { // idx = GetYoungestBefore( structure.support.from, supports // ); has = IsValidIndex(idx); if (has) { structure.prevZone = supports[idx]; } } else if (structure.isResistanceTouched) { // idx = GetYoungestBefore( structure.resistance.from, resistances // ); has = IsValidIndex(idx); if (has) { structure.prevZone = resistances[idx]; } } }