/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCXFIMAPoiDetector ... // Description: XFIMA POI Detector Class ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XFIMA POI Detector Class" #property strict // // Imports ... #include "../../Classes/x-saherelm.base.class.mq5" #include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../../Classes/x-saherelm.x-market.pattern.class.mq5" #include "../Libraries/x-saherelm.xfima.lib.mq5" // // Implementation ... class XCXFIMAPOIDetector : public XCMarketPatternDetector { // // Public ... public: // // Props ... XCBarAnalyser *barAnalyser; // Bar Analyser ... XCXFIMAHelper *fimaHelper; // XFIMA Helper ... // XBoxZone obs[]; XBoxZone fvgs[]; XBoxZone supports[]; XBoxZone resistances[]; // // Constructor ... XCXFIMAPOIDetector( XCXFIMAHelper *_fimaHelper // ) : XCMarketPatternDetector() { // barAnalyser = new XCBarAnalyser(); fimaHelper = _fimaHelper; } // // Deconstructor ... ~XCXFIMAPOIDetector() { Destroy(); } // // Actions and Tools ... // // Pivot Analysors ... /** * Analyse Market based on Specified Kind of Pivots ... * * @param analysis: XPivotAnalysis, reference to hold result ... * @param barIndex: int, Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... * * @return ( bool ) */ bool AnalysePVPivots( XPivotAnalysis &analysis, int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500, int validationLength = 0 // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Reading Pivots ... XPivot pivots[]; int count = ExtractPVPivots( pivots, // Result ... barIndex, // Bar Index ... requiredNumberOFPivots, // Required Number of Pivots ... maxAllowedLoopbackLength, // Max Allowed Loopback ... validationLength // Validation Length ... ); result = IsValidSize(count); if (!result) { // SpecifiedClean(pivots); return result; } // string symbol = fimaHelper.GetSymbol(); ENUM_TIMEFRAMES period = fimaHelper.GetPeriod(); // // Initialize Analysis ... result = analysis.Init( "XFIMA_XPV", symbol, period, pivots // ); // // Cleanup Resources ... if (!result) { analysis.Clean(); } SpecifiedClean(pivots); // return result; } /** * Analyse Market based on Specified Kind of Pivots ... * * @param analysis: XPivotAnalysis, reference to hold result ... * @param barIndex: int, Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... * * @return ( bool ) */ bool AnalyseMAPivots( XPivotAnalysis &analysis, int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500, int validationLength = 0 // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Reading Pivots ... XPivot pivots[]; int count = ExtractMAPivots( pivots, // Result ... barIndex, // Bar Index ... requiredNumberOFPivots, // Required Number of Pivots ... maxAllowedLoopbackLength, // Max Allowed Loopback ... validationLength // Validation Length ... ); result = IsValidSize(count); if (!result) { // SpecifiedClean(pivots); return result; } // string symbol = fimaHelper.GetSymbol(); ENUM_TIMEFRAMES period = fimaHelper.GetPeriod(); // // Initialize Analysis ... result = analysis.Init( "XFIMA_XMA", symbol, period, pivots // ); // // Cleanup Resources ... if (!result) { analysis.Clean(); } SpecifiedClean(pivots); // return result; } /** * Analyse Market based on Specified Kind of Pivots ... * * @param analysis: XPivotAnalysis, reference to hold result ... * @param barIndex: int, Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * * @return ( bool ) */ bool AnalyseSARPivots( XPivotAnalysis &analysis, int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500 // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Reading Pivots ... XPivot pivots[]; int count = ExtractSARPivots( pivots, // Result ... barIndex, // Bar Index ... requiredNumberOFPivots, // Required Number of Pivots ... maxAllowedLoopbackLength // Max Allowed Loopback ... ); result = IsValidSize(count); if (!result) { // SpecifiedClean(pivots); return result; } // string symbol = fimaHelper.GetSymbol(); ENUM_TIMEFRAMES period = fimaHelper.GetPeriod(); // // Initialize Analysis ... result = analysis.Init( "XFIMA_XSAR", symbol, period, pivots // ); // // Cleanup Resources ... if (!result) { analysis.Clean(); } SpecifiedClean(pivots); // return result; } /** * Analyse Market based on Specified Kind of Pivots ... * * @param analysis: XPivotAnalysis, reference to hold result ... * @param barIndex: int, Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * * @return ( bool ) */ bool AnalyseZigZagPivots( XPivotAnalysis &analysis, int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500 // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Reading Pivots ... XPivot pivots[]; int count = ExtractZigZagPivots( pivots, // Result ... barIndex, // Bar Index ... requiredNumberOFPivots, // Required Number of Pivots ... maxAllowedLoopbackLength // Max Allowed Loopback ... ); result = IsValidSize(count); if (!result) { // SpecifiedClean(pivots); return result; } // string symbol = fimaHelper.GetSymbol(); ENUM_TIMEFRAMES period = fimaHelper.GetPeriod(); // // Initialize Analysis ... result = analysis.Init( "XFIMA_XZG", symbol, period, pivots // ); // // Cleanup Resources ... if (!result) { analysis.Clean(); } SpecifiedClean(pivots); // return result; } // // Pivot Extractors ... /** * Extract Specified Kind of Pivots ... * * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... * * @return ( int ) */ int ExtractPVPivots( XPivot &pivots[], int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500, int validationLength = 0 // ) { // int result = 0; // result = fimaHelper.ExtractPVPivots( pivots, barIndex, requiredNumberOFPivots, maxAllowedLoopbackLength, validationLength // ); // return result; } /** * Extract Specified Kind of Pivots ... * * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... * * @return ( int ) */ int ExtractMAPivots( XPivot &pivots[], int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500, int validationLength = 0 // ) { // int result = 0; // result = fimaHelper.ExtractMAPivots( pivots, barIndex, requiredNumberOFPivots, maxAllowedLoopbackLength, validationLength // ); // return result; } /** * Extract Specified Kind of Pivots ... * * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * * @return ( int ) */ int ExtractSARPivots( XPivot &pivots[], int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // result = fimaHelper.ExtractSARPivots( pivots, barIndex, requiredNumberOFPivots, maxAllowedLoopbackLength // ); // return result; } /** * Extract Specified Kind of Pivots ... * * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * * @return ( int ) */ int ExtractZigZagPivots( XPivot &pivots[], int barIndex = 0, int requiredNumberOFPivots = 50, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // result = fimaHelper.ExtractZigZagPivots( pivots, barIndex, requiredNumberOFPivots, maxAllowedLoopbackLength // ); // return result; } /** * Destroy ... */ void Destroy() { // SpecifiedClean(obs); SpecifiedClean(fvgs); SpecifiedClean(supports); SpecifiedClean(resistances); // delete barAnalyser; ZeroMemory(barAnalyser); } // // Testers ... /** * 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 // ); } } // // 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 // ); } } // // 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 ... 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; } // 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 ... // // Detect Recently Tested Zones ... if ((config.detectSupport || config.detectResistance) && config.recentlyZonesMaxLookupLength > 0) { // XOHCL iBar; int idx = -1; bool has = false; // int start = forBar.Index(); int end = start + config.recentlyZonesMaxLookupLength; 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 // ); } // // Check Breaked ... has = IsBreaked(iBar, supports[idx]); if (has) { // AddIfNotExists( supports[idx], structure.recentlyBreakedZones // ); } } // // 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 // ); } // // Check Breaked ... has = IsBreaked(iBar, resistances[idx]); if (has) { // AddIfNotExists( resistances[idx], structure.recentlyBreakedZones // ); } } } } // // Checkup for FakeBreaked Zones ... if ((config.detectSupport || config.detectResistance) && HasChild(structure.recentlyBreakedZones)) { // int idx = -1; bool has = false; // // Detect Youngest Recently Breaked Zones ... idx = GetYoungest(structure.recentlyBreakedZones); has = IsValidIndex(idx); if (has) { // structure.fakeBreakedZone = structure.recentlyBreakedZones[idx]; // // Update To Time ... structure.fakeBreakedZone.to = forBar.time; } // // Check Price Going Back to Zone Area ... has = structure.fakeBreakedZone.IsValid(); if (has) { // // Check Current Bar Acted Based on Zone ... has = structure.fakeBreakedZone.IsBullish() ? forBar.close > structure.fakeBreakedZone.upper : forBar.close < structure.fakeBreakedZone.lower; } // // Try to Validate Breake Length ... // // Get Youngest Breaker Bar ... XOHCL breakerBar; if (has) { // XOHCL breakerBars[]; int breakerBarsCount = GetBreakerBars( structure.fakeBreakedZone, breakerBars // ); has = IsValidSize(breakerBarsCount); if (has) { // idx = GetYoungestBar(breakerBars); has = IsValidIndex(idx); if (has) { breakerBar = breakerBars[idx]; } } SpecifiedClean(breakerBars); } has = breakerBar.IsValid(); // // Validate BreakerBars Length ... if (has) { // int diff = breakerBar.Index() - forBar.Index(); // has = config.supportAndResistanceBreakeValidationLength <= 0 ? true : diff <= config.supportAndResistanceBreakeValidationLength; } // if (!has) { structure.fakeBreakedZone.Clean(); } // // Cleanup Resources ... breakerBar.Clean(); } // // Detect Recently Patterns ... if (config.recentlyPatternsMaxLookupLength > 0) { // XOHCL iBar; XPivot iPivot; XBoxZone iBox; bool has = false; string iPrefix = NULL; int start = forBar.Index(); ENUM_X_SORT_BY iSortBy = X_SORT_BY_DATE; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; ENUM_X_DIRECTION iSortDir = X_DIRECTION_BULLISH; int end = start + config.recentlyPatternsMaxLookupLength; // // Order Blocks ... if (config.detectOB) { // Copy( obs, structure.obs // ); Sort( structure.obs, iSortBy, iSortDir, config.recentlyPatternsMaxAllowedCollecting // ); } // // Fair Value Gaps ... if (config.detectFVG) { // Copy( fvgs, structure.fvgs // ); Sort( structure.fvgs, iSortBy, iSortDir, config.recentlyPatternsMaxAllowedCollecting // ); } // // Supports ... if (config.detectSupport) { // Copy( supports, structure.supports // ); Sort( structure.supports, iSortBy, iSortDir, config.recentlyPatternsMaxAllowedCollecting // ); } // // Resistances ... if (config.detectResistance) { // Copy( resistances, structure.resistances // ); Sort( structure.resistances, iSortBy, iSortDir, config.recentlyPatternsMaxAllowedCollecting // ); } // // Loop through Items ... for (int i = start; i < end; i++) { // iPivot.Clean(); // // Initialize Indexed Bar ... has = forBar.BarAt(i, iBar); if (!has) { // iBar.Clean(); continue; } // // Bars Detecting ... // // Momentum Bars ... if (config.detectMomentum) { // iPrefix = "MomentumBar"; has = IsMomentumBar( iBar, iDir, config.momentumBarRangeLength, config.momentumBarApprovedMultiplier // ); has = has && ToPivot( iBar, iPivot, iDir, iPrefix // ); if (has) { // AddIfNotExists( iPivot, structure.momentumBars // ); } iPivot.Clean(); } // // Engulfed Bars ... if (config.detectEngulfed) { // iPrefix = "EngulfedBar"; has = IsEngulfedBar( iBar, iDir // ); has = has && ToPivot( iBar, iPivot, iDir, iPrefix // ); if (has) { // AddIfNotExists( iPivot, structure.engulfBars // ); } iPivot.Clean(); } // // TruGaped Bars ... if (config.detectTrueGaped) { // iPrefix = "TruGapedBar"; has = IsTrueGapedBar( iBar, iDir, config.truwGapApprovedPointMultiplier // ); has = has && ToPivot( iBar, iPivot, iDir, iPrefix // ); if (has) { // AddIfNotExists( iPivot, structure.trueGapBars // ); } iPivot.Clean(); } // // Pin Bars ... if (config.detectTrueGaped) { // iPrefix = "PinBar"; has = IsPinnedBar( iBar, iDir, config.pinnedBaarShadowApprovedMultiplier, config.pinnedBarMinimumPinBarRangeMultiplier, config.pinnedBarForceDirection // ); has = has && ToPivot( iBar, iPivot, iDir, iPrefix // ); if (has) { // AddIfNotExists( iPivot, structure.pinBars // ); } iPivot.Clean(); } // // Patterns Detecting ... // // Star Pattern ... if (config.detectStarPattern) { // iPrefix = "Star"; has = IsStartPattern( iBar, iDir // ); has = has && ToBox( iBar, iBox, iDir, iPrefix // ); if (has) { // AddIfNotExists( iBox, structure.starPatterns // ); } iBox.Clean(); } // // Piercing Pattern ... if (config.detectPiercingPattern) { // iPrefix = "Piercing"; has = IsPiercingPattern( iBar, iDir // ); has = has && ToBox( iBar, iBox, iDir, iPrefix // ); if (has) { // AddIfNotExists( iBox, structure.piercingPatterns // ); } iBox.Clean(); } // // Rising Pattern ... if (config.detectRisingPattern) { // iPrefix = "Rising"; has = IsRisingPattern( iBar, iDir // ); has = has && ToBox( iBar, iBox, iDir, iPrefix // ); if (has) { // AddIfNotExists( iBox, structure.risingPatterns // ); } iBox.Clean(); } // // Flag Pattern ... if (config.detectFlagPattern) { // iPrefix = "Flag"; XOHCL swingBar; has = IsFlagPattern( iBar, iDir, swingBar, config.flagPatternMinimumPullbackBars // ); has = has && ToBox( iBar, iBox, iDir, iPrefix // ); if (has) { // AddIfNotExists( iBox, structure.flagPatterns // ); } iBox.Clean(); } // // SignalKey Bar Pattern ... if (config.detectSignalKeyBarPattern) { // iPrefix = "SignalKeyBar"; has = IsSignalKeyBarPattern( iBar, iDir, config.signalKeyBarShadowApprovedMultiplier, config.signalKeyBarMinimumPinBarRangeMultiplier, config.signalKeyBarForceDirection // ); has = has && ToBox( iBar, iBox, iDir, iPrefix // ); if (has) { // AddIfNotExists( iBox, structure.signalKeyBarPatterns // ); } iBox.Clean(); } // iBar.Clean(); } // // Cleanup Resources ... iBar.Clean(); iBox.Clean(); iPivot.Clean(); } } // // Protected ... protected: // // Props ... // // Tools / Actions ... // // Private ... private: // // }; //