/////////////////////////////////////////////////////// // // 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 ... // // Constructor ... XCXFIMAPOIDetector() { // barAnalyser = new XCBarAnalyser(); } // // 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 numberOfRequiredPivots: int, Specified Number of required ZigZag Points ... * * @return ( int ) */ int GetZigZagPivot( XOHCL &bar, XCXFIMAHelper *&fimaHelper, XZigZagPivot &zigzagPivots[], int numberOfRequiredPivots = 5 // ) { // int result = 0; // // Normalize ... SpecifiedClean(zigzagPivots); numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 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; XZigZagPivot 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_PIVOT_TYPE_NONE; while (ArraySize(zigzagPivots) < numberOfRequiredPivots) { // // 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_PIVOT_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_PIVOT_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_PIVOT_TYPE_PEAK : IsSpecifiedBearish(iDir) ? X_ZIGZAG_PIVOT_TYPE_VALE : X_ZIGZAG_PIVOT_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_PIVOT_TYPE_NONE; // start++; lastZGDetected++; // continue; } // // Initialize ZigZag Point ... has = iZGPoint.Init( iZG, iZGTime, bar.symbol, iDir, bar.period, iType // ); if (has) { // iZGPoint.AddIfNotExists(zigzagPivots); 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_PIVOT_TYPE_NONE; // start++; } // result = ArraySize(zigzagPivots); // return result; } // bool AnalyseMarketUsingZigZag( XOHCL &bar, ENUM_TIMEFRAMES forPeriod, XCXFIMAHelper *&fimaHelper, XZigZagAnalysis &analysis, int numberOfRequiredPivots = 20 // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Normalize ... numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 5); if (!IsSpecifiedValid(forPeriod)) { forPeriod = bar.period; } // // Reading XZigZag Points ... XOHCL iPeriodBar; result = iPeriodBar.Init( bar.symbol, forPeriod, bar.Index() // ); if (!result) { // iPeriodBar.Clean(); return result; } // // Reading Required Pivots ... XZigZagPivot pivots[]; int pivotsCount = GetZigZagPivot( iPeriodBar, fimaHelper, pivots, numberOfRequiredPivots // ); result = IsValidSize(pivotsCount); if (!result) { // analysis.Clean(); iPeriodBar.Clean(); SpecifiedClean(pivots); } // // Initialize Analysis Model ... result = analysis.Analyse( bar, pivots // ); if (!result) { // analysis.Clean(); iPeriodBar.Clean(); SpecifiedClean(pivots); } // return result; } // // Tools ... /** * Destroy ... */ void Destroy() { // delete barAnalyser; ZeroMemory(barAnalyser); } // // 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: // // }; //