/////////////////////////////////////////////////////// // // 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 ... // // 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() { // 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; // bool has = false; 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(); } } // // Fair Value Gap ... if (config.detectFVG) { // bool isFVG = HasFVG( forBar, iDir, structure.fvg, config.fvgLoopback // ); bool isBullishOB = isFVG && IsSpecifiedBullish(iDir); bool isBearishOB = isFVG && IsSpecifiedBearish(iDir); if (!isFVG) { structure.fvg.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.detectSupports) { // XOHCL support; bool hasSupport = HasSupport( forBar, support, config.supportAndResistanceValidationLength, config.supportAndResistanceMaxAllowedLoopback // ); if (hasSupport) { // XBoxZone supportBox; has = ToSupportBox(support, supportBox); if (has) { structure.support = supportBox; } // 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); if (has) { 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; } } } // // Protected ... protected: // // Props ... // // Tools / Actions ... // // Private ... private: // // }; //