/////////////////////////////////////////////////////// // // 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 XCBase { // // Public ... public: // // Props ... XCBarAnalyser *barAnalyser; // Bar Analyser ... XCMarketPatternDetector *patternDetector; // Pattern Detector ... // // Constructor ... XCXFIMAPOIDetector() { // barAnalyser = new XCBarAnalyser(); patternDetector = new XCMarketPatternDetector(); } // // Deconstructor ... ~XCXFIMAPOIDetector() { Destroy(); } // // Actions and Tools ... /** * Get Specified Number of Recent ZigZag Points ... * * @param bar: XOHCL, Specified Bar for Start ... * @param fimaHelper: XCXFIMAHelper, instance of XFIMA Helper ... * @param zigzagPoints: XZigZagPoint, Array of Founded Points ... * @param numberOfRequiredPoints: int, Specified Number of required ZigZag Points ... * * @return ( int ) */ int GetZigZagPoint( XOHCL &bar, XCXFIMAHelper *&fimaHelper, XZigZagPoint &zigzagPoints[], int numberOfRequiredPoints = 5 // ) { // int result = 0; // // Normalize ... SpecifiedClean(zigzagPoints); numberOfRequiredPoints = NormalizeInt(numberOfRequiredPoints, 3); // // Validate ... result = bar.IsValid() && bar.symbol == fimaHelper.GetSymbol() && bar.period == fimaHelper.GetPeriod(); if (!result) { return result; } // // Update Fima Helper ... int index = bar.Index(); fimaHelper.Update(index); // // Start Reading ZigZag Values ... double iZG = 0; double iPZG = 0; int iZGIdx = -1; int iPZGIdx = -1; bool has = false; int start = index; XZigZagPoint iZGPoint; datetime iZGTime = NULL; datetime iPZGTime = NULL; int lastZGDetected = start; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; ENUM_X_ZIGZAG_POINT_TYPE iType = X_ZIGZAG_POINT_TYPE_NONE; while (ArraySize(zigzagPoints) < numberOfRequiredPoints) { // // Reading Last two ZigZag Value ... // // Detect Last ZG Value ... has = GetZigZagValue(lastZGDetected, iZG, iZGIdx, iZGTime, fimaHelper); if (!has) { // iZG = 0; iPZG = 0; iZGIdx = -1; iPZGIdx = -1; iZGTime = NULL; iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; iType = X_ZIGZAG_POINT_TYPE_NONE; // start++; lastZGDetected++; // continue; } // // Detect Previous ZG Value ... has = GetZigZagValue(lastZGDetected + 1, iPZG, iPZGIdx, iPZGTime, fimaHelper); if (!has) { // iZG = 0; iPZG = 0; iZGIdx = -1; iPZGIdx = -1; iZGTime = NULL; iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; iType = X_ZIGZAG_POINT_TYPE_NONE; // start++; lastZGDetected++; // continue; } // // Check Direction ... iDir = (iZG > iPZG) ? X_DIRECTION_BULLISH : (iZG < iPZG) ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; // // Check Point Type ... iType = IsSpecifiedBullish(iDir) ? X_ZIGZAG_POINT_TYPE_PEAK : IsSpecifiedBearish(iDir) ? X_ZIGZAG_POINT_TYPE_VALE : X_ZIGZAG_POINT_TYPE_NONE; has = IsXValid(iType) && HasDirection(iDir); if (!has) { // iZG = 0; iPZG = 0; iZGIdx = -1; iPZGIdx = -1; iZGTime = NULL; iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; iType = X_ZIGZAG_POINT_TYPE_NONE; // start++; lastZGDetected++; // continue; } // // Initialize ZigZag Point ... has = iZGPoint.Init( iZG, iZGTime, bar.symbol, iDir, bar.period, iType // ); if (has) { // iZGPoint.AddIfNotExists(zigzagPoints); lastZGDetected = iZGIdx + 1; } // // Reset Resources ... iZG = 0; iPZG = 0; iZGIdx = -1; iPZGIdx = -1; iZGTime = NULL; iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; iType = X_ZIGZAG_POINT_TYPE_NONE; // start++; } // result = ArraySize(zigzagPoints); // return result; } // bool AnalyseMarketUsingZigZag( XOHCL &bar, ENUM_TIMEFRAMES forPeriod, XZigZagAnalysis &analysis // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Normalize ... if (!IsSpecifiedValid(forPeriod)) { forPeriod = bar.period; } // // Reading XZigZag Points ... // return result; } // // Implementing Patrren Detector ... /** * Check Specified Bar is Momentum Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param requiredBars: int, bar range for approve Momentum ... * @param approvedMultiplier: int, a Multipler for approve Momentum ... * * @return ( bool ) */ bool IsMomentumBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int requiredBars = 3, int approvedMultiplier = 2 // ) { // return patternDetector.IsMomentumBar( bar, dir, requiredBars, approvedMultiplier // ); } /** * Check Specified Bar is Engulfed Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsEngulfedBar( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // return patternDetector.IsEngulfedBar( bar, dir // ); } /** * Check Specified Bar is True Gapped Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param approvedPointMultiplier: double, Gap Validation Multiplier in Point ... * * @return ( bool ) */ bool IsTrueGapedBar( XOHCL &bar, ENUM_X_DIRECTION &dir, double approvedPointMultiplier = 1 // ) { // return patternDetector.IsTrueGapedBar( bar, dir, approvedPointMultiplier // ); } /** * Check Specified Bar is Pinned Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ... * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... * @param forceDirection: bool, Apply Force Bar Type ... * * @return ( bool ) */ bool IsPinnedBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int shadowApprovedMultiplier = 3, double minimumPinBarRangeMultiplier = 4, bool forceDirection = false // ) { // return patternDetector.IsPinnedBar( bar, dir, shadowApprovedMultiplier, minimumPinBarRangeMultiplier, forceDirection // ); } /** * Check Specified Bar has Star Pattern or not ... * Morning Star => Bullish * Evening Star => Bearish * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsStartPattern( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // return patternDetector.IsStartPattern( bar, dir // ); } /** * Check Specified Bar has Pirecing Pattern or not ... * Piercing => Bullish * Dark Cloud Cover => Bearish * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsPiercingPattern( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // return patternDetector.IsPiercingPattern( bar, dir // ); } /** * Check Specified Bar has Rising Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsRisingPattern( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // return patternDetector.IsRisingPattern( bar, dir // ); } /** * Check Specified Bar has Flag Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param swingBar: XOHCL, Detected Swing Bar ... * @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ... * @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ... * * @return ( bool ) */ bool IsFlagPattern( XOHCL &bar, ENUM_X_DIRECTION &dir, XOHCL &swingBar, int minimumPullbackBars = 3 // ) { // return patternDetector.IsFlagPattern( bar, dir, swingBar, minimumPullbackBars // ); } /** * Check Specified Bar has SignalKey Bar Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ... * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... * @param forceDirection: bool, Apply Force Bar Type ... * * @return ( bool ) */ bool IsSignalKeyBarPattern( XOHCL &bar, ENUM_X_DIRECTION &dir, int shadowApprovedMultiplier = 3, double minimumPinBarRangeMultiplier = 4, bool forceDirection = false // ) { // return patternDetector.IsSignalKeyBarPattern( bar, dir, shadowApprovedMultiplier, minimumPinBarRangeMultiplier, forceDirection // ); } /** * Check For FVG Exists in Specified Loopback Period ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param fvg: XBoxZone, reference for Holding FVG ... * @param maxLoopback: int, Max Allowed Loopback to Lookup FVG ... * * @return ( bool ) */ bool HasFVG( XOHCL &bar, ENUM_X_DIRECTION &dir, XBoxZone &fvg, int maxLoopback = 5 // ) { // return patternDetector.HasFVG( bar, dir, fvg, maxLoopback // ); } /** * Check For OB Exists in Specified Loopback Period ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param ob: XBoxZone, reference for Holding OB ... * @param maxLoopback: int, Max Allowed Loopback to Lookup OB ... * * @return ( bool ) */ bool HasOB( XOHCL &bar, ENUM_X_DIRECTION &dir, XBoxZone &ob, int maxLoopback = 5 // ) { // return patternDetector.HasOB( bar, dir, ob, maxLoopback // ); } /** * Check Trend Exists Based on Swings ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param swings: XOHCL Array, Holds Swings ... * @param numberOfSwings: int, Number of Swing Points for Detect Trend ... * @param swingShoulders: int, Swing Shoulders Approvement Length ... * * @return ( bool ) */ bool HasSwingTrend( XOHCL &bar, ENUM_X_DIRECTION &dir, XOHCL &swings[], int numberOfSwings = 3, int swingShoulders = 7 // ) { // return patternDetector.HasSwingTrend( bar, dir, swings, numberOfSwings, swingShoulders // ); } /** * Check Specified Bar Has Support or not ... * * @param bar: XOHCL, Specified Bar ... * @param support: XOHCL, Supported Bar ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... * * @return ( bool ) */ bool HasSupport( XOHCL &bar, XOHCL &support, int validationLength = 21, int maxAllowedLoopback = 1500 // ) { // return patternDetector.HasSupport( bar, support, validationLength, maxAllowedLoopback // ); } /** * Check Specified Bar Has Resistance or not ... * * @param bar: XOHCL, Specified Bar ... * @param resistence: XOHCL, Resistanced Bar ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... * * @return ( bool ) */ bool HasResistance( XOHCL &bar, XOHCL &resistence, int validationLength = 21, int maxAllowedLoopback = 1500 // ) { // return patternDetector.HasResistance( bar, resistence, validationLength, maxAllowedLoopback // ); } // // Tools ... /** * Destroy ... */ void Destroy() { // delete barAnalyser; ZeroMemory(barAnalyser); // delete patternDetector; ZeroMemory(patternDetector); } // // Protected ... protected: // // Props ... // // Tools / Actions ... /** * Read Specified Value of ZigZag ... * * @param fromBarIndex: int, Specified Start Bar Index ... * @param value: double, reference to Hold ZigZag Value ... * @param index: int, reference to Hold ZigZag Value's Bar Index ... * @param time: datetime, reference to Hold ZigZag Value's Time ... * @param maxAllowedLoopback: int, Maximum Allowe Loopback to Detect Specified Point ... * * @return ( bool ) */ bool GetZigZagValue( int fromBarIndex, double &value, int &index, datetime &time, XCXFIMAHelper *&fimaHelper, int maxAllowedLoopback = 100 // ) { // bool result = false; // // Normalize ... fromBarIndex = NormalizeInt(fromBarIndex, 0); maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 10, 100); // // Prepare ... value = 0; index = -1; time = NULL; // // Validate ... result = fimaHelper != NULL; if (!result) { return result; } // int start = fromBarIndex; int end = start + maxAllowedLoopback; while (start < end) { // fimaHelper.Update(start); // value = fimaHelper.GetZigZag(start); result = value > 0 && value != EMPTY_VALUE; if (result) { // time = GetBarTime( fimaHelper.GetSymbol(), fimaHelper.GetPeriod(), start // ); // index = start; // break; } // value = 0; index = -1; time = NULL; // start++; } // result = value > 0 && IsValidIndex(index) && value != EMPTY_VALUE && IsSpecifiedValid(time); if (!result) { // value = 0; index = -1; time = NULL; } // return result; } // // Private ... private: // // }; //