/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: XCXCAEAPOIDetector ... // Description: Class for XCAEA POI Detector ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm Class for XCAEA POI Detector" #property strict // // Imports ... #include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Helpers/xcaea.helper.mq5" // // Definitions ... // enum ENUM_XCA_PIVOTS { XCA_NONE, // None XCA_SWL, // SWL XCA_SWH, // SWH XCA_VALE, // VALE XCA_PEAK, // PEAK XCA_PEAKSWHRES, // PeakSWHRes XCA_VALESWLSUP, // ValeSWLSup }; // bool IsValid(ENUM_XCA_PIVOTS value) { // bool result = false; // result = value != XCA_NONE; // return result; } // string ToString(ENUM_XCA_PIVOTS value) { // string result = NULL; // result = EnumToString(value); // return result; } // struct XCAPivot { // // Props ... datetime to; double value; string symbol; datetime from; double reserve; ENUM_XCA_PIVOTS type; ENUM_TIMEFRAMES period; // // Constructor ... XCAPivot() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // value = 0; to = NULL; reserve = 0; from = NULL; symbol = NULL; period = NULL; type = XCA_NONE; } /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = from < to && value != 0 && IsValid(to) && IsValid(from) && IsValid(type) && IsValid(symbol) && IsValid(period); // return result; } /** * Check a Model is Same as this or not ... * * @param pivot: XCAPivot ... * * @return ( bool ) */ bool IsSameAs(XCAPivot &pivot) { // bool result = false; // result = IsValid() && pivot.IsValid(); if (!result) { return result; } // result = to == pivot.to && from == pivot.from && type == pivot.type && value == pivot.value && symbol == pivot.symbol && period == pivot.period; // return result; } /** * Retrieve To Index ... * * @param forPeriod: ENUM_TIMEFRAMES, Specified Period ... * * @return ( int ) */ int ToIndex( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = -1; // if (!IsValid()) { return result; } // if (!IsValid(forPeriod)) { forPeriod = period; } // result = GetBarIndex( symbol, forPeriod, to // ); // return result; } /** * Retrieve From Index ... * * @param forPeriod: ENUM_TIMEFRAMES, Specified Period ... * * @return ( int ) */ int FromIndex( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = -1; // if (!IsValid()) { return result; } // if (!IsValid(forPeriod)) { forPeriod = period; } // result = GetBarIndex( symbol, forPeriod, from // ); // return result; } /** * Retrieve Age of Pivot ... * * @param forPeriod: ENUM_TIMEFRAMES, Specified Period ... * * @return ( int ) */ int GetAge( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = 0; // if (!IsValid()) { return result; } // if (!IsValid(forPeriod)) { forPeriod = period; } // int toIDX = ToIndex(forPeriod); int fromIDX = FromIndex(forPeriod); // result = fromIDX - toIDX; // return result; } /** * Converts Pivot to Box ... * * @param box: XBoxZone instance reference ... * * @return ( bool ) */ bool AsBox( XBoxZone &box // ) { // bool result = false; // box.Clean(); // result = IsValid(); if (!result) { return result; } // ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; switch (type) { // case XCA_SWL: case XCA_VALE: case XCA_VALESWLSUP: iDir = X_DIRECTION_BULLISH; break; // case XCA_SWH: case XCA_PEAK: case XCA_PEAKSWHRES: iDir = X_DIRECTION_BEARISH; break; } // result = HasDirection(iDir); if (!result) { return result; } // bool isBullish = IsBullish(iDir) && value < reserve; // bool isBearish = IsBearish(iDir) && value > reserve; // result = isBullish || isBearish; if (!result) { return result; } // box.to = to; box.dir = iDir; box.from = from; box.symbol = symbol; box.period = period; box.type = ToString(type); // box.upper = isBullish ? reserve : value; box.lower = isBullish ? value : reserve; // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } // }; /** * Find Specified Pivot Index inside a Collection of Pivots ... * * @param pivot: XCAPivot instance Reference ... * @param pivots: XCAPivot instance Reference Collection ... * * @return ( int ) */ bool FindPivotIndex( int &index, XCAPivot &pivot, XCAPivot &pivots[] // ) { // bool result = false; // index = -1; // int count = ArraySize(pivots); result = pivot.IsValid() && IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // XCAPivot iPivot = pivots[i]; // bool isSame = pivot.IsSameAs(iPivot); if (isSame) { // index = i; break; } } // result = IsValidIndex(index); // return result; } // // Implementations ... class XCXCAEAPOIDetector : public XCBase { // // Public ... public: // // Props ... XCAPivot swhPivots[]; XCAPivot swlPivots[]; XCAPivot peakPivots[]; XCAPivot valePivots[]; XCAPivot peakSWHResPivots[]; XCAPivot valeSWLSupPivots[]; // // Constructors ... XCXCAEAPOIDetector( XCXCAEAHelper *_helper // ) { // helper = _helper; drawer = new XCPOIDrawer(); barAnalyser = new XCBarAnalyser(); // Default(); } // // De Constructors ... ~XCXCAEAPOIDetector() { // peakPivot.Clean(); Clean(peakPivots); // valePivot.Clean(); Clean(valePivots); // peakSWHResPivot.Clean(); Clean(peakSWHResPivots); // valeSWLSupPivot.Clean(); Clean(valeSWLSupPivots); // ZeroMemory(helper); ZeroMemory(drawer); ZeroMemory(barAnalyser); } // // Properties ... // // Tools ... virtual void Default() { // pivotVerifications = 5; } // void Update( int barIndex = 0, int loopback = 400 // ) { // if (barIndex < 0) { barIndex = 0; } // loopback = NormalizeInt(loopback, 400); // int count = 0; bool has = false; // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; // int index = barIndex; int start = index; int end = index + loopback; while (start < end) { // // Retrieve Conditions ... XCAEAConditions iConditions; has = helper.GetConditions( iConditions, start, 5 // ); // // Retrieve Bars ... XOHCL zBar; XOHCL cBar; XOHCL pBar; XOHCL p2Bar; has = zBar.Init( iConditions.symbol, iConditions.period, start // ); has = has && zBar.GetPreviousBar(cBar); has = has && cBar.GetPreviousBar(pBar); has = has && pBar.GetPreviousBar(p2Bar); if (!has) { // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); iConditions.Clean(); // continue; } // // Checking Pivots ... // // Peak Pivot ... // if (!peakPivot.IsValid()) { // peakPivot.type = XCA_PEAK; peakPivot.symbol = iConditions.symbol; peakPivot.period = iConditions.period; // if (iConditions.isPeakSameLast) { // peakPivot.to = cBar.time; peakPivot.from = pBar.time; peakPivot.value = iConditions.peakBuffer[cIDX]; } } // if (iConditions.isPeakSameLast) { // peakPivot.from = pBar.time; peakPivot.reserve = peakPivot.reserve == 0 ? iConditions.peakGoldenBuffer[cIDX] : MathMax(peakPivot.reserve, iConditions.peakGoldenBuffer[cIDX]); } // if (!iConditions.isPeakSameLast) { // has = peakPivot.IsValid() && peakPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( peakPivot, peakPivots // ); } // peakPivot.Clean(); } // // Peak SWH Res Pivot ... // if (!peakSWHResPivot.IsValid()) { // peakSWHResPivot.type = XCA_PEAKSWHRES; peakSWHResPivot.symbol = iConditions.symbol; peakSWHResPivot.period = iConditions.period; // if (iConditions.isPeakIsPivot && iConditions.isPeakSameLast) { // peakSWHResPivot.to = cBar.time; peakSWHResPivot.from = pBar.time; peakSWHResPivot.value = iConditions.peakBuffer[cIDX]; } } // if (iConditions.isPeakIsPivot && iConditions.isPeakSameLast) { // peakSWHResPivot.from = pBar.time; peakSWHResPivot.reserve = peakSWHResPivot.reserve == 0 ? iConditions.peakGoldenBuffer[cIDX] : MathMax(peakSWHResPivot.reserve, iConditions.peakGoldenBuffer[cIDX]); } // if (!(iConditions.isPeakIsPivot && iConditions.isPeakSameLast)) { // has = peakSWHResPivot.IsValid() && peakSWHResPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( peakSWHResPivot, peakSWHResPivots // ); } // peakSWHResPivot.Clean(); } // // Vale Pivot ... // if (!valePivot.IsValid()) { // valePivot.type = XCA_VALE; valePivot.symbol = iConditions.symbol; valePivot.period = iConditions.period; // if (iConditions.isValeSameLast) { // valePivot.to = cBar.time; valePivot.from = pBar.time; valePivot.value = iConditions.valeBuffer[cIDX]; } } // if (iConditions.isValeSameLast) { // valePivot.from = pBar.time; valePivot.reserve = valePivot.reserve == 0 ? iConditions.valeGoldenBuffer[cIDX] : MathMin(valePivot.reserve, iConditions.valeGoldenBuffer[cIDX]); } // if (!iConditions.isValeSameLast) { // has = valePivot.IsValid() && valePivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( valePivot, valePivots // ); } // valePivot.Clean(); } // // Vale SWL Sup Pivot ... // if (!valeSWLSupPivot.IsValid()) { // valeSWLSupPivot.type = XCA_VALESWLSUP; valeSWLSupPivot.symbol = iConditions.symbol; valeSWLSupPivot.period = iConditions.period; // if (iConditions.isValeIsPivot && iConditions.isValeSameLast) { // valeSWLSupPivot.to = cBar.time; valeSWLSupPivot.from = pBar.time; valeSWLSupPivot.value = iConditions.valeBuffer[cIDX]; } } // if (iConditions.isValeIsPivot && iConditions.isValeSameLast) { // valeSWLSupPivot.from = pBar.time; valeSWLSupPivot.reserve = valeSWLSupPivot.reserve == 0 ? iConditions.valeGoldenBuffer[cIDX] : MathMin(valeSWLSupPivot.reserve, iConditions.valeGoldenBuffer[cIDX]); } // if (!(iConditions.isValeIsPivot && iConditions.isValeSameLast)) { // has = valeSWLSupPivot.IsValid() && valeSWLSupPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( valeSWLSupPivot, valeSWLSupPivots // ); } // valeSWLSupPivot.Clean(); } // // SWH Pivot ... // if (!swhPivot.IsValid()) { // swhPivot.type = XCA_SWH; swhPivot.symbol = iConditions.symbol; swhPivot.period = iConditions.period; // if (iConditions.isSwingHighSameLast) { // swhPivot.to = cBar.time; swhPivot.from = pBar.time; swhPivot.value = iConditions.swingHighBuffer[cIDX]; } } // if (iConditions.isSwingHighSameLast) { // swhPivot.from = pBar.time; } // if (!iConditions.isSwingHighSameLast) { // has = swhPivot.IsValid() && cBar.high > cBar.GetUp() && cBar.high == swhPivot.value && swhPivot.GetAge() >= pivotVerifications; if (has) { // swhPivot.reserve = cBar.GetUp(); // AddPivot( swhPivot, swhPivots // ); } // swhPivot.Clean(); } // // SWL Pivot ... // if (!swlPivot.IsValid()) { // swlPivot.type = XCA_SWL; swlPivot.symbol = iConditions.symbol; swlPivot.period = iConditions.period; // if (iConditions.isSwingLowSameLast) { // swlPivot.to = cBar.time; swlPivot.from = pBar.time; swlPivot.value = iConditions.swingLowBuffer[cIDX]; } } // if (iConditions.isSwingLowSameLast) { // swlPivot.from = pBar.time; } // if (!iConditions.isSwingLowSameLast) { // has = swlPivot.IsValid() && cBar.low < cBar.GetDown() && cBar.low == swlPivot.value && swlPivot.GetAge() >= pivotVerifications; if (has) { // swlPivot.reserve = cBar.GetDown(); // AddPivot( swlPivot, swlPivots // ); } // swlPivot.Clean(); } // start++; // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); iConditions.Clean(); } // } // // POI Handlers ... // bool HasPeakPivots() { return HasChild(peakPivots); } // int CountPeakPivots() { return ArraySize(peakPivots); } // bool HasPeakSWHResPivots() { return HasChild(peakSWHResPivots); } // int CountPeakSWHResPivots() { return ArraySize(peakSWHResPivots); } // bool HasValePivots() { return HasChild(valePivots); } // int CountValePivots() { return ArraySize(valePivots); } // bool HasValeSWLSupPivots() { return HasChild(valeSWLSupPivots); } // int CountValeSWLSupPivots() { return ArraySize(valeSWLSupPivots); } // bool HasSWHPivots() { return HasChild(swhPivots); } // int CountSWHPivots() { return ArraySize(swhPivots); } // bool HasSWLPivots() { return HasChild(swlPivots); } // int CountSWLPivots() { return ArraySize(swlPivots); } // // Protected ... protected: // // Props ... // // Prrivate ... private: // // Props ... int pivotVerifications; // Pivots Verifications ... // XCAPivot swhPivot; XCAPivot swlPivot; XCAPivot peakPivot; XCAPivot valePivot; XCAPivot peakSWHResPivot; XCAPivot valeSWLSupPivot; // XCPOIDrawer *drawer; XCXCAEAHelper *helper; XCBarAnalyser *barAnalyser; // void AddBox( XBoxZone &box, XBoxZone &boxes[] // ) { // bool has = box.IsValid(); if (!has) { return; } // int idx = -1; has = FindBoxIndex( idx, box, boxes // ); if (has) { return; } // AddRef( box, boxes // ); } // void AddPivot( XCAPivot &pivot, XCAPivot &pivots[] // ) { // bool has = pivot.IsValid(); if (!has) { return; } // int idx = -1; has = FindPivotIndex( idx, pivot, pivots // ); if (has) { return; } // int updateIDX = -1; int count = ArraySize(pivots); for (int i = 0; i < count; i++) { // XCAPivot iPivot = pivots[i]; // has = iPivot.to < pivot.to && iPivot.from == pivot.from && iPivot.value == pivot.value && iPivot.symbol == pivot.symbol && iPivot.period == pivot.period; if (has) { // updateIDX = i; break; } } // has = IsValidIndex(updateIDX); if (!has) { // AddRef( pivot, pivots // ); } else { // pivots[updateIDX].to = pivot.to; } } // }; //