/////////////////////////////////////////////////////// // // 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_KI_BULL, // KIBull XCA_KI_BEAR, // KIBear XCA_TKI_BULL, // TKIBull XCA_TKI_BEAR, // TKIBear XCA_PEAKSWHRES, // PeakSWHRes XCA_VALESWLSUP, // ValeSWLSup XCA_TREND_BULL, // TrendBull XCA_TREND_BEAR, // TrendBear XCA_TKITRND_BULL, // TKITRNDBull XCA_TKITRND_BEAR, // TKITRNDBear }; // 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; // double values[]; // // Constructor ... XCAPivot() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // value = 0; to = NULL; reserve = 0; from = NULL; symbol = NULL; period = NULL; type = XCA_NONE; // Clean(values); } /** * 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_KI_BULL: case XCA_TKI_BULL: case XCA_TREND_BULL: case XCA_VALESWLSUP: case XCA_TKITRND_BULL: iDir = X_DIRECTION_BULLISH; break; // case XCA_SWH: case XCA_PEAK: case XCA_KI_BEAR: case XCA_TKI_BEAR: case XCA_TREND_BEAR: case XCA_PEAKSWHRES: case XCA_TKITRND_BEAR: 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; // string typeStr = ToString(type); if (type == XCA_KI_BULL || type == XCA_KI_BEAR) { // typeStr = "XCA_KI"; } else if (type == XCA_TKI_BULL || type == XCA_TKI_BEAR) { // typeStr = "XCA_TKI"; } else if (type == XCA_TREND_BULL || type == XCA_TREND_BEAR) { // typeStr = "XCA_TREND"; } else if (type == XCA_TKITRND_BULL || type == XCA_TKITRND_BEAR) { // typeStr = "XCA_TKITRND"; } box.type = typeStr; // 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 ... // // Active Pivots ... XCAPivot swhPivot; XCAPivot swlPivot; XCAPivot peakPivot; XCAPivot valePivot; XCAPivot kiBullishPivot; XCAPivot kiBearishPivot; XCAPivot tkiBullishPivot; XCAPivot tkiBearishPivot; XCAPivot peakSWHResPivot; XCAPivot valeSWLSupPivot; XCAPivot trendBullishPivot; XCAPivot trendBearishPivot; XCAPivot tkitrndBullishPivot; XCAPivot tkitrndBearishPivot; // // UnActive Pivots ... XCAPivot swhPivots[]; XCAPivot swlPivots[]; XCAPivot peakPivots[]; XCAPivot valePivots[]; XCAPivot kiBullishPivots[]; XCAPivot kiBearishPivots[]; XCAPivot tkiBullishPivots[]; XCAPivot tkiBearishPivots[]; XCAPivot peakSWHResPivots[]; XCAPivot valeSWLSupPivots[]; XCAPivot trendBullishPivots[]; XCAPivot trendBearishPivots[]; XCAPivot tkitrndBullishPivots[]; XCAPivot tkitrndBearishPivots[]; // // 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() { // maxAllowedPivots = 50; 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; } // // Provide Some Conditions ... // double points = GetPoints(zBar.symbol); // // PEAK ... // double cPeak = iConditions.peakBuffer[cIDX]; double pPeak = iConditions.peakBuffer[pIDX]; double p2Peak = iConditions.peakBuffer[p2IDX]; // bool isPeakStartSameLast = cPeak == pPeak && pPeak != p2Peak; // bool isPeakFinishedSameLast = cPeak != pPeak && pPeak == p2Peak; // // VALE ... // double cVale = iConditions.valeBuffer[cIDX]; double pVale = iConditions.valeBuffer[pIDX]; double p2Vale = iConditions.valeBuffer[p2IDX]; // bool isValeStartSameLast = cVale == pVale && pVale != p2Vale; // bool isValeFinishedSameLast = cVale != pVale && pVale == p2Vale; // // SWH ... // double cSWH = iConditions.swingHighBuffer[cIDX]; double pSWH = iConditions.swingHighBuffer[pIDX]; double p2SWH = iConditions.swingHighBuffer[p2IDX]; // bool isSWHStartSameLast = cSWH == pSWH && pSWH != p2SWH; // bool isSWHFinishedSameLast = cSWH != pSWH && pSWH == p2SWH; // // SWL ... // double pSWL = iConditions.swingLowBuffer[pIDX]; double cSWL = iConditions.swingLowBuffer[cIDX]; double p2SWL = iConditions.swingLowBuffer[p2IDX]; // bool isSWLStartSameLast = cSWL == pSWL && pSWL != p2SWL; // bool isSWLFinishedSameLast = cSWL != pSWL && pSWL == p2SWL; // // SUPPORT ... // double cSupport = iConditions.supportBuffer[cIDX]; double pSupport = iConditions.supportBuffer[pIDX]; double p2Support = iConditions.supportBuffer[p2IDX]; // bool isSupportStartSameLast = cSupport == pSupport && pSupport != p2Support; // bool isSupportFinishedSameLast = cSupport != pSupport && pSupport == p2Support; // // RESISTANCE ... // double pResistance = iConditions.resistanceBuffer[pIDX]; double cResistance = iConditions.resistanceBuffer[cIDX]; double p2Resistance = iConditions.resistanceBuffer[p2IDX]; // bool isResistanceStartSameLast = cResistance == pResistance && pResistance != p2Resistance; // bool isResistanceFinishedSameLast = cResistance != pResistance && pResistance == p2Resistance; // // PEAK SWH RES ... // bool isCPeakIsPivot = cPeak == cSWH && cSWH == cResistance; // bool isPPeakIsPivot = pPeak == pSWH && pSWH == pResistance; // bool isStartPeakIsPivot = isCPeakIsPivot && !isPPeakIsPivot; // bool isFinishedPeakIsPivot = !isCPeakIsPivot && isPPeakIsPivot; // // VALE SWL SUP ... // bool isCValeIsPivot = cVale == cSWL && cSWL == cSupport; // bool isPValeIsPivot = pVale == pSWL && pSWL == pSupport; // bool isStartValeIsPivot = isCValeIsPivot && !isPValeIsPivot; // bool isFinishedValeIsPivot = !isCValeIsPivot && isPValeIsPivot; // // TKITRND ... // double cKI = iConditions.kiBuffer[cIDX]; double pKI = iConditions.kiBuffer[pIDX]; double p2KI = iConditions.kiBuffer[p2IDX]; // double cKIState = iConditions.kiStateBuffer[cIDX]; double pKIState = iConditions.kiStateBuffer[pIDX]; double p2KIState = iConditions.kiStateBuffer[p2IDX]; // double cTKI = iConditions.tkiBuffer[cIDX]; double pTKI = iConditions.tkiBuffer[pIDX]; double p2TKI = iConditions.tkiBuffer[p2IDX]; // double cTKIState = iConditions.tkiStateBuffer[cIDX]; double pTKIState = iConditions.tkiStateBuffer[pIDX]; double p2TKIState = iConditions.tkiStateBuffer[p2IDX]; // double cTrend = iConditions.trendBuffer[cIDX]; double pTrend = iConditions.trendBuffer[pIDX]; double p2Trend = iConditions.trendBuffer[p2IDX]; // double cTrendState = iConditions.trendStateBuffer[cIDX]; double pTrendState = iConditions.trendStateBuffer[pIDX]; double p2TrendState = iConditions.trendStateBuffer[p2IDX]; // double cTKITRNDs[] = { cKI, cTKI, cTrend // }; // double cTKITRNDMin = GetMin(cTKITRNDs); double cTKITRNDMax = GetMax(cTKITRNDs); // double pTKITRNDs[] = { pKI, pTKI, pTrend // }; // double pTKITRNDMin = GetMin(pTKITRNDs); double pTKITRNDMax = GetMax(pTKITRNDs); // bool isCTKITRNDBullish = cKIState > 0 && cTKIState > 0 && cTrendState > 0; // bool isPTKITRNDBullish = pKIState > 0 && pTKIState > 0 && pTrendState > 0; // bool isTKITRNDSwitchedBullish = isCTKITRNDBullish && !isPTKITRNDBullish; // bool isCTKITRNDBearish = cKIState < 0 && cTKIState < 0 && cTrendState < 0; // bool isPTKITRNDBearish = pKIState < 0 && pTKIState < 0 && pTrendState < 0; // bool isTKITRNDSwitchedBearish = isCTKITRNDBearish && !isPTKITRNDBearish; // // Checking Pivots ... // bool detectSWHPivot = true; bool detectSWLPivot = true; bool detectPeakPivot = true; bool detectValePivot = true; bool detectTKITRNDBullish = true; bool detectTKITRNDBearish = true; bool detectKIBullishPivot = true; bool detectKIBearishPivot = true; bool detectTKIBullishPivot = true; bool detectTKIBearishPivot = true; bool detectPeakSWHResPivot = true; bool detectValeSWLSupPivot = true; bool detectTrendBullishPivot = true; bool detectTrendBearishPivot = true; // // Peak Pivot ... if (detectPeakPivot) { // if (!peakPivot.IsValid()) { // peakPivot.type = XCA_PEAK; peakPivot.symbol = iConditions.symbol; peakPivot.period = iConditions.period; // if (isPeakFinishedSameLast) { // peakPivot.Clean(); // peakPivot.type = XCA_PEAK; peakPivot.symbol = iConditions.symbol; peakPivot.period = iConditions.period; // peakPivot.to = pBar.time; peakPivot.from = pBar.time; peakPivot.value = iConditions.peakBuffer[pIDX]; peakPivot.reserve = iConditions.peakGoldenBuffer[pIDX]; } } // if (iConditions.isPeakSameLast) { // peakPivot.from = pBar.time; // peakPivot.reserve = peakPivot.reserve == 0 ? iConditions.peakGoldenBuffer[cIDX] : MathMax(peakPivot.reserve, iConditions.peakGoldenBuffer[cIDX]); } // if (isPeakStartSameLast) { // has = peakPivot.IsValid() && peakPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( peakPivot, peakPivots // ); } // peakPivot.Clean(); } } // // Vale Pivot ... if (detectValePivot) { // if (!valePivot.IsValid()) { // valePivot.type = XCA_VALE; valePivot.symbol = iConditions.symbol; valePivot.period = iConditions.period; // if (isValeFinishedSameLast) { // valePivot.Clean(); // valePivot.type = XCA_VALE; valePivot.symbol = iConditions.symbol; valePivot.period = iConditions.period; // valePivot.to = pBar.time; valePivot.from = pBar.time; valePivot.value = iConditions.valeBuffer[pIDX]; valePivot.reserve = iConditions.valeGoldenBuffer[pIDX]; } } // if (iConditions.isValeSameLast) { // valePivot.from = pBar.time; // valePivot.reserve = valePivot.reserve == 0 ? iConditions.valeGoldenBuffer[cIDX] : MathMin(valePivot.reserve, iConditions.valeGoldenBuffer[cIDX]); } // if (isValeStartSameLast) { // has = valePivot.IsValid() && valePivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( valePivot, valePivots // ); } // valePivot.Clean(); } } // // SWH Pivot ... if (detectSWHPivot) { // if (!swhPivot.IsValid()) { // swhPivot.type = XCA_SWH; swhPivot.symbol = iConditions.symbol; swhPivot.period = iConditions.period; // if (isSWHFinishedSameLast) { // swhPivot.Clean(); // swhPivot.type = XCA_SWH; swhPivot.symbol = iConditions.symbol; swhPivot.period = iConditions.period; // swhPivot.to = pBar.time; swhPivot.from = pBar.time; swhPivot.value = iConditions.swingHighBuffer[pIDX]; } } // if (iConditions.isSwingHighSameLast) { // swhPivot.from = pBar.time; // double reserve = swhPivot.reserve; if (pBar.high == pSWH) { // reserve = reserve == 0 ? pBar.GetUp() : MathMin(reserve, pBar.GetUp()); } swhPivot.reserve = reserve; } // if (isSWHStartSameLast) { // double reserve = swhPivot.reserve; if (cBar.high == cSWH) { // reserve = reserve == 0 ? cBar.GetUp() : MathMin(reserve, cBar.GetUp()); } if (pBar.high == pSWH) { // reserve = reserve == 0 ? pBar.GetUp() : MathMin(reserve, pBar.GetUp()); } if (reserve == 0 || reserve == swhPivot.value) { reserve = swhPivot.value - (5 * points); } swhPivot.reserve = reserve; // has = swhPivot.IsValid() && swhPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( swhPivot, swhPivots // ); } // swhPivot.Clean(); } } // // SWL Pivot ... if (detectSWLPivot) { // if (!swlPivot.IsValid()) { // swlPivot.type = XCA_SWL; swlPivot.symbol = iConditions.symbol; swlPivot.period = iConditions.period; // if (isSWLFinishedSameLast) { // swlPivot.Clean(); // swlPivot.type = XCA_SWL; swlPivot.symbol = iConditions.symbol; swlPivot.period = iConditions.period; // swlPivot.to = cBar.time; swlPivot.from = pBar.time; swlPivot.value = iConditions.swingLowBuffer[cIDX]; } } // if (iConditions.isSwingLowSameLast) { // swlPivot.from = pBar.time; // double reserve = swlPivot.reserve; if (pBar.low == pSWL) { // reserve = reserve == 0 ? pBar.GetDown() : MathMax(reserve, pBar.GetDown()); } swlPivot.reserve = reserve; } // if (isSWLStartSameLast) { // double reserve = swlPivot.reserve; if (cBar.low == cSWL) { // reserve = reserve == 0 ? cBar.GetDown() : MathMax(reserve, cBar.GetDown()); } if (pBar.low == pSWL) { // reserve = reserve == 0 ? pBar.GetDown() : MathMax(reserve, pBar.GetDown()); } if (reserve == 0 || reserve == swlPivot.value) { reserve = swlPivot.value + (5 * points); } swlPivot.reserve = reserve; // has = swlPivot.IsValid() && swlPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( swlPivot, swlPivots // ); } // swlPivot.Clean(); } } // // Peak SWH Res Pivot ... if (detectPeakSWHResPivot) { // if (!peakSWHResPivot.IsValid()) { // peakSWHResPivot.type = XCA_PEAKSWHRES; peakSWHResPivot.symbol = iConditions.symbol; peakSWHResPivot.period = iConditions.period; // if (isFinishedPeakIsPivot) { // peakSWHResPivot.Clean(); // peakSWHResPivot.type = XCA_PEAKSWHRES; peakSWHResPivot.symbol = iConditions.symbol; peakSWHResPivot.period = iConditions.period; // peakSWHResPivot.to = pBar.time; peakSWHResPivot.from = pBar.time; peakSWHResPivot.value = iConditions.peakBuffer[pIDX]; peakSWHResPivot.reserve = iConditions.peakGoldenBuffer[pIDX]; } } // if (iConditions.isPeakIsPivot) { // peakSWHResPivot.from = pBar.time; // peakSWHResPivot.reserve = peakSWHResPivot.reserve == 0 ? iConditions.peakGoldenBuffer[pIDX] : MathMax(peakSWHResPivot.reserve, iConditions.peakGoldenBuffer[pIDX]); } // if (isStartPeakIsPivot) { // has = peakSWHResPivot.IsValid() && peakSWHResPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( peakSWHResPivot, peakSWHResPivots // ); } // peakSWHResPivot.Clean(); } } // // Vale SWL Sup Pivot ... if (detectValeSWLSupPivot) { // if (!valeSWLSupPivot.IsValid()) { // valeSWLSupPivot.type = XCA_VALESWLSUP; valeSWLSupPivot.symbol = iConditions.symbol; valeSWLSupPivot.period = iConditions.period; // if (isFinishedValeIsPivot) { // valeSWLSupPivot.Clean(); // valeSWLSupPivot.type = XCA_VALESWLSUP; valeSWLSupPivot.symbol = iConditions.symbol; valeSWLSupPivot.period = iConditions.period; // valeSWLSupPivot.to = pBar.time; valeSWLSupPivot.from = pBar.time; valeSWLSupPivot.value = iConditions.valeBuffer[pIDX]; valeSWLSupPivot.reserve = iConditions.valeGoldenBuffer[pIDX]; } } // if (iConditions.isValeIsPivot) { // valeSWLSupPivot.from = pBar.time; // valeSWLSupPivot.reserve = valeSWLSupPivot.reserve == 0 ? iConditions.valeGoldenBuffer[pIDX] : MathMin(valeSWLSupPivot.reserve, iConditions.valeGoldenBuffer[pIDX]); } // if (isStartValeIsPivot) { // has = valeSWLSupPivot.IsValid() && valeSWLSupPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( valeSWLSupPivot, valeSWLSupPivots // ); } // valeSWLSupPivot.Clean(); } } // // KI Bullish ... if (detectKIBullishPivot) { // if (!kiBullishPivot.IsValid()) { // kiBullishPivot.type = XCA_KI_BULL; kiBullishPivot.symbol = iConditions.symbol; kiBullishPivot.period = iConditions.period; // if (iConditions.isKISwitchedToBearish) { // kiBullishPivot.Clean(); // kiBullishPivot.type = XCA_KI_BULL; kiBullishPivot.symbol = iConditions.symbol; kiBullishPivot.period = iConditions.period; // kiBullishPivot.to = pBar.time; kiBullishPivot.from = pBar.time; kiBullishPivot.value = iConditions.kiBuffer[pIDX]; kiBullishPivot.reserve = iConditions.kiBuffer[pIDX]; } } // if (iConditions.isKIBullish) { // kiBullishPivot.from = cBar.time; // Add( iConditions.kiBuffer[cIDX], kiBullishPivot.values // ); // kiBullishPivot.value = kiBullishPivot.value == 0 ? iConditions.kiBuffer[cIDX] : MathMin(iConditions.kiBuffer[cIDX], kiBullishPivot.value); // kiBullishPivot.reserve = kiBullishPivot.reserve == 0 ? iConditions.kiBuffer[cIDX] : MathMax(iConditions.kiBuffer[cIDX], kiBullishPivot.reserve); } // if (iConditions.isKISwitchedToBullish) { // has = kiBullishPivot.IsValid() && kiBullishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( kiBullishPivot, kiBullishPivots // ); } // kiBullishPivot.Clean(); } } // // KI Bearish ... if (detectKIBearishPivot) { // if (!kiBearishPivot.IsValid()) { // kiBearishPivot.type = XCA_KI_BEAR; kiBearishPivot.symbol = iConditions.symbol; kiBearishPivot.period = iConditions.period; // if (iConditions.isKISwitchedToBullish) { // kiBearishPivot.Clean(); // kiBearishPivot.type = XCA_KI_BEAR; kiBearishPivot.symbol = iConditions.symbol; kiBearishPivot.period = iConditions.period; // kiBearishPivot.to = pBar.time; kiBearishPivot.from = pBar.time; kiBearishPivot.value = iConditions.kiBuffer[pIDX]; kiBearishPivot.reserve = iConditions.kiBuffer[pIDX]; } } // if (iConditions.isKIBearish) { // kiBearishPivot.from = cBar.time; // Add( iConditions.kiBuffer[cIDX], kiBearishPivot.values // ); // kiBearishPivot.value = kiBearishPivot.value == 0 ? iConditions.kiBuffer[cIDX] : MathMax(iConditions.kiBuffer[cIDX], kiBearishPivot.value); // kiBearishPivot.reserve = kiBearishPivot.reserve == 0 ? iConditions.kiBuffer[cIDX] : MathMin(iConditions.kiBuffer[cIDX], kiBearishPivot.reserve); } // if (iConditions.isKISwitchedToBearish) { // has = kiBearishPivot.IsValid() && kiBearishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( kiBearishPivot, kiBearishPivots // ); } // kiBearishPivot.Clean(); } } // // TKI Bullish ... if (detectTKIBullishPivot) { // if (!tkiBullishPivot.IsValid()) { // tkiBullishPivot.type = XCA_TKI_BULL; tkiBullishPivot.symbol = iConditions.symbol; tkiBullishPivot.period = iConditions.period; // if (iConditions.isTKISwitchedToBearish) { // tkiBullishPivot.Clean(); // tkiBullishPivot.type = XCA_TKI_BULL; tkiBullishPivot.symbol = iConditions.symbol; tkiBullishPivot.period = iConditions.period; // tkiBullishPivot.to = pBar.time; tkiBullishPivot.from = pBar.time; tkiBullishPivot.value = iConditions.tkiBuffer[pIDX]; tkiBullishPivot.reserve = iConditions.tkiBuffer[pIDX]; } } // if (iConditions.isTKIBullish) { // tkiBullishPivot.from = cBar.time; // Add( iConditions.tkiBuffer[cIDX], tkiBullishPivot.values // ); // tkiBullishPivot.value = tkiBullishPivot.value == 0 ? iConditions.tkiBuffer[cIDX] : MathMin(iConditions.tkiBuffer[cIDX], tkiBullishPivot.value); // tkiBullishPivot.reserve = tkiBullishPivot.reserve == 0 ? iConditions.tkiBuffer[cIDX] : MathMax(iConditions.tkiBuffer[cIDX], tkiBullishPivot.reserve); } // if (iConditions.isTKISwitchedToBullish) { // has = tkiBullishPivot.IsValid() && tkiBullishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( tkiBullishPivot, tkiBullishPivots // ); } // tkiBullishPivot.Clean(); } } // // TKI Bearish ... if (detectTKIBearishPivot) { // if (!tkiBearishPivot.IsValid()) { // tkiBearishPivot.type = XCA_TKI_BEAR; tkiBearishPivot.symbol = iConditions.symbol; tkiBearishPivot.period = iConditions.period; // if (iConditions.isTKISwitchedToBullish) { // tkiBearishPivot.Clean(); // tkiBearishPivot.type = XCA_TKI_BEAR; tkiBearishPivot.symbol = iConditions.symbol; tkiBearishPivot.period = iConditions.period; // tkiBearishPivot.to = pBar.time; tkiBearishPivot.from = pBar.time; tkiBearishPivot.value = iConditions.tkiBuffer[pIDX]; tkiBearishPivot.reserve = iConditions.tkiBuffer[pIDX]; } } // if (iConditions.isTKIBearish) { // tkiBearishPivot.from = cBar.time; // Add( iConditions.tkiBuffer[cIDX], tkiBearishPivot.values // ); // tkiBearishPivot.value = tkiBearishPivot.value == 0 ? iConditions.tkiBuffer[cIDX] : MathMax(iConditions.tkiBuffer[cIDX], tkiBearishPivot.value); // tkiBearishPivot.reserve = tkiBearishPivot.reserve == 0 ? iConditions.tkiBuffer[cIDX] : MathMin(iConditions.tkiBuffer[cIDX], tkiBearishPivot.reserve); } // if (iConditions.isTKISwitchedToBearish) { // has = tkiBearishPivot.IsValid() && tkiBearishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( tkiBearishPivot, tkiBearishPivots // ); } // tkiBearishPivot.Clean(); } } // // TREND Bullish ... if (detectTrendBullishPivot) { // if (!trendBullishPivot.IsValid()) { // trendBullishPivot.type = XCA_TREND_BULL; trendBullishPivot.symbol = iConditions.symbol; trendBullishPivot.period = iConditions.period; // if (iConditions.isTrendSwitchedToBearish) { // trendBullishPivot.Clean(); // trendBullishPivot.type = XCA_TREND_BULL; trendBullishPivot.symbol = iConditions.symbol; trendBullishPivot.period = iConditions.period; // trendBullishPivot.to = pBar.time; trendBullishPivot.from = pBar.time; trendBullishPivot.value = iConditions.trendBuffer[pIDX]; trendBullishPivot.reserve = iConditions.trendBuffer[pIDX]; } } // if (iConditions.isTrendBullish) { // trendBullishPivot.from = cBar.time; // Add( iConditions.trendBuffer[cIDX], trendBullishPivot.values // ); // trendBullishPivot.value = trendBullishPivot.value == 0 ? iConditions.trendBuffer[cIDX] : MathMin(iConditions.trendBuffer[cIDX], trendBullishPivot.value); // trendBullishPivot.reserve = trendBullishPivot.reserve == 0 ? iConditions.trendBuffer[cIDX] : MathMax(iConditions.trendBuffer[cIDX], trendBullishPivot.reserve); } // if (iConditions.isTrendSwitchedToBullish) { // has = trendBullishPivot.IsValid() && trendBullishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( trendBullishPivot, trendBullishPivots // ); } // trendBullishPivot.Clean(); } } // // TREND Bearish ... if (detectTrendBearishPivot) { // if (!trendBearishPivot.IsValid()) { // trendBearishPivot.type = XCA_TREND_BEAR; trendBearishPivot.symbol = iConditions.symbol; trendBearishPivot.period = iConditions.period; // if (iConditions.isTrendSwitchedToBullish) { // trendBearishPivot.Clean(); // trendBearishPivot.type = XCA_TREND_BEAR; trendBearishPivot.symbol = iConditions.symbol; trendBearishPivot.period = iConditions.period; // trendBearishPivot.to = pBar.time; trendBearishPivot.from = pBar.time; trendBearishPivot.value = iConditions.trendBuffer[pIDX]; trendBearishPivot.reserve = iConditions.trendBuffer[pIDX]; } } // if (iConditions.isTrendBearish) { // trendBearishPivot.from = cBar.time; // Add( iConditions.trendBuffer[cIDX], trendBearishPivot.values // ); // trendBearishPivot.value = trendBearishPivot.value == 0 ? iConditions.trendBuffer[cIDX] : MathMax(iConditions.trendBuffer[cIDX], trendBearishPivot.value); // trendBearishPivot.reserve = trendBearishPivot.reserve == 0 ? iConditions.trendBuffer[cIDX] : MathMin(iConditions.trendBuffer[cIDX], trendBearishPivot.reserve); } // if (iConditions.isTrendSwitchedToBearish) { // has = trendBearishPivot.IsValid() && trendBearishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( trendBearishPivot, trendBearishPivots // ); } // trendBearishPivot.Clean(); } } // // TKITRND Bullish ... if (detectTKITRNDBullish) { // if (!tkitrndBullishPivot.IsValid()) { // tkitrndBullishPivot.type = XCA_TKITRND_BULL; tkitrndBullishPivot.symbol = iConditions.symbol; tkitrndBullishPivot.period = iConditions.period; // if (!isCTKITRNDBullish && isPTKITRNDBullish) { // tkitrndBullishPivot.Clean(); // tkitrndBullishPivot.type = XCA_TKITRND_BULL; tkitrndBullishPivot.symbol = iConditions.symbol; tkitrndBullishPivot.period = iConditions.period; // tkitrndBullishPivot.to = pBar.time; tkitrndBullishPivot.from = pBar.time; tkitrndBullishPivot.value = pTKITRNDMin; tkitrndBullishPivot.reserve = pTKITRNDMax; } } // if (isCTKITRNDBullish) { // tkitrndBullishPivot.from = cBar.time; // Add( cTKITRNDMin, tkitrndBullishPivot.values // ); // Add( cTKITRNDMax, tkitrndBullishPivot.values // ); // tkitrndBullishPivot.value = tkitrndBullishPivot.value == 0 ? cTKITRNDMin : MathMin(cTKITRNDMin, tkitrndBullishPivot.value); // tkitrndBullishPivot.reserve = tkitrndBullishPivot.reserve == 0 ? cTKITRNDMax : MathMax(cTKITRNDMax, tkitrndBullishPivot.reserve); } // if (!isCTKITRNDBullish) { // has = tkitrndBullishPivot.IsValid() && tkitrndBullishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( tkitrndBullishPivot, tkitrndBullishPivots // ); } // trendBullishPivot.Clean(); } } // // TKITRND Bearish ... if (detectTKITRNDBearish) { // if (!tkitrndBearishPivot.IsValid()) { // tkitrndBearishPivot.type = XCA_TKITRND_BEAR; tkitrndBearishPivot.symbol = iConditions.symbol; tkitrndBearishPivot.period = iConditions.period; // if (!isCTKITRNDBearish && isPTKITRNDBearish) { // tkitrndBearishPivot.Clean(); // tkitrndBearishPivot.type = XCA_TKITRND_BEAR; tkitrndBearishPivot.symbol = iConditions.symbol; tkitrndBearishPivot.period = iConditions.period; // tkitrndBearishPivot.to = pBar.time; tkitrndBearishPivot.from = pBar.time; tkitrndBearishPivot.value = pTKITRNDMax; tkitrndBearishPivot.reserve = pTKITRNDMin; } } // if (isCTKITRNDBearish) { // tkitrndBearishPivot.from = cBar.time; // Add( cTKITRNDMin, tkitrndBearishPivot.values // ); // Add( cTKITRNDMax, tkitrndBearishPivot.values // ); // tkitrndBearishPivot.value = tkitrndBearishPivot.value == 0 ? cTKITRNDMax : MathMax(cTKITRNDMax, tkitrndBearishPivot.value); // tkitrndBearishPivot.reserve = tkitrndBearishPivot.reserve == 0 ? cTKITRNDMin : MathMin(cTKITRNDMin, tkitrndBearishPivot.reserve); } // if (!isCTKITRNDBearish) { // has = tkitrndBearishPivot.IsValid() && tkitrndBearishPivot.GetAge() >= pivotVerifications; if (has) { // AddPivot( tkitrndBearishPivot, tkitrndBearishPivots // ); } // trendBearishPivot.Clean(); } } // start++; // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); iConditions.Clean(); } // } // // POI Handlers ... // // Peaks ... // bool HasPeakPivots() { return HasChild(peakPivots); } // int CountPeakPivots() { return ArraySize(peakPivots); } // // Peak SWH Res ... // bool HasPeakSWHResPivots() { return HasChild(peakSWHResPivots); } // int CountPeakSWHResPivots() { return ArraySize(peakSWHResPivots); } // // Vale ... // bool HasValePivots() { return HasChild(valePivots); } // int CountValePivots() { return ArraySize(valePivots); } // // ValeSWLSup ... // bool HasValeSWLSupPivots() { return HasChild(valeSWLSupPivots); } // int CountValeSWLSupPivots() { return ArraySize(valeSWLSupPivots); } // // Swing High ... // bool HasSWHPivots() { return HasChild(swhPivots); } // int CountSWHPivots() { return ArraySize(swhPivots); } // // Swing Low ... // bool HasSWLPivots() { return HasChild(swlPivots); } // int CountSWLPivots() { return ArraySize(swlPivots); } // // KI ... // bool HasKIBullishPivots() { return HasChild(kiBullishPivots); } // int CountKIBullishPivots() { return ArraySize(kiBullishPivots); } // bool HasKIBearishPivots() { return HasChild(kiBearishPivots); } // int CountKIBearishPivots() { return ArraySize(kiBearishPivots); } // // TKI ... // bool HasTKIBullishPivots() { return HasChild(tkiBullishPivots); } // int CountTKIBullishPivots() { return ArraySize(tkiBullishPivots); } // bool HasTKIBearishPivots() { return HasChild(tkiBearishPivots); } // int CountTKIBearishPivots() { return ArraySize(tkiBearishPivots); } // // TREND ... // bool HasTrendBullishPivots() { return HasChild(trendBullishPivots); } // int CountTrendBullishPivots() { return ArraySize(trendBullishPivots); } // bool HasTrendBearishPivots() { return HasChild(trendBearishPivots); } // int CountTrendBearishPivots() { return ArraySize(trendBearishPivots); } // // TKITRND ... // bool HasTKITRNDBullishPivots() { return HasChild(tkitrndBullishPivots); } // int CountTKITRNDBullishPivots() { return ArraySize(tkitrndBullishPivots); } // bool HasTKITRNDBearishPivots() { return HasChild(tkitrndBearishPivots); } // int CountTKITRNDBearishPivots() { return ArraySize(tkitrndBearishPivots); } // // Protected ... protected: // // Props ... // // Prrivate ... private: // // Props ... int pivotVerifications; // Pivots Verifications ... int maxAllowedPivots; // Max Allowed Holding Pibots ... // XCPOIDrawer *drawer; XCXCAEAHelper *helper; XCBarAnalyser *barAnalyser; // 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; } // // Apply Max Allowed ... CleanupArray( pivots, maxAllowedPivots // ); } // }; //