/////////////////////////////////////////////////////// // // 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 library #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, // Swing Low XCA_SWH, // Swing High XCA_PEAK, // Peak XCA_VALE, // Vale XCA_OB_BULL, // OBBull XCA_OB_BEAR, // OBBear XCA_FVG_BULL, // FVGBull XCA_FVG_BEAR, // FVGBear XCA_RSI_COOS, // RSICOOS XCA_RSI_CUOB, // RSICUOB XCA_TREND_BULL, // TrendBull XCA_TREND_BEAR, // TrendBear XCA_TRIGGER_BULL, // TriggerBull XCA_TRIGGER_BEAR, // TriggerBear }; // 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; } // ENUM_X_DIRECTION GetDirection(ENUM_XCA_PIVOTS value) { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // switch (value) { // case XCA_SWL: case XCA_VALE: case XCA_OB_BULL: case XCA_FVG_BULL: case XCA_RSI_COOS: case XCA_TREND_BULL: case XCA_TRIGGER_BULL: result = X_DIRECTION_BULLISH; break; // case XCA_SWH: case XCA_PEAK: case XCA_OB_BEAR: case XCA_FVG_BEAR: case XCA_RSI_CUOB: case XCA_TREND_BEAR: case XCA_TRIGGER_BEAR: result = X_DIRECTION_BEARISH; break; } // return result; } // string GetBoxType(ENUM_XCA_PIVOTS value) { // string result = NULL; // switch (value) { // case XCA_SWL: case XCA_SWH: case XCA_VALE: case XCA_PEAK: case XCA_RSI_COOS: case XCA_RSI_CUOB: result = ToString(value); break; // case XCA_OB_BULL: case XCA_OB_BEAR: result = "XCA_OB"; break; // case XCA_FVG_BULL: case XCA_FVG_BEAR: result = "XCA_FVG"; break; // case XCA_TREND_BULL: case XCA_TREND_BEAR: result = "XCA_TREND"; break; // case XCA_TRIGGER_BULL: case XCA_TRIGGER_BEAR: result = "XCA_TRIGGER"; break; } // return result; } // ENUM_XCA_PIVOTS GetPivotType(XBoxZone &value) { // ENUM_XCA_PIVOTS result = XCA_NONE; // bool has = value.IsValid(); if (!has) { return result; } // bool isSWL = value.type == GetBoxType(XCA_SWL) && value.dir == GetDirection(XCA_SWL); bool isSWH = value.type == GetBoxType(XCA_SWH) && value.dir == GetDirection(XCA_SWH); bool isPeak = value.type == GetBoxType(XCA_PEAK) && value.dir == GetDirection(XCA_PEAK); bool isVale = value.type == GetBoxType(XCA_VALE) && value.dir == GetDirection(XCA_VALE); bool isOBBull = value.type == GetBoxType(XCA_OB_BULL) && value.dir == GetDirection(XCA_OB_BULL); bool isOBBear = value.type == GetBoxType(XCA_OB_BEAR) && value.dir == GetDirection(XCA_OB_BEAR); bool isFVGBull = value.type == GetBoxType(XCA_FVG_BULL) && value.dir == GetDirection(XCA_FVG_BULL); bool isFVGBear = value.type == GetBoxType(XCA_FVG_BEAR) && value.dir == GetDirection(XCA_FVG_BEAR); bool isRSICrossedOverOS = value.type == GetBoxType(XCA_RSI_COOS) && value.dir == GetDirection(XCA_RSI_COOS); bool isRSICrossedUnderOB = value.type == GetBoxType(XCA_RSI_CUOB) && value.dir == GetDirection(XCA_RSI_CUOB); bool isTrendBullish = value.type == GetBoxType(XCA_TREND_BULL) && value.dir == GetDirection(XCA_TREND_BULL); bool isTrendBearish = value.type == GetBoxType(XCA_TREND_BEAR) && value.dir == GetDirection(XCA_TREND_BEAR); bool isTriggerBullish = value.type == GetBoxType(XCA_TRIGGER_BULL) && value.dir == GetDirection(XCA_TRIGGER_BULL); bool isTriggerBearish = value.type == GetBoxType(XCA_TRIGGER_BEAR) && value.dir == GetDirection(XCA_TRIGGER_BEAR); // if (isSWL) { result = XCA_SWL; } else if (isSWH) { result = XCA_SWH; } else if (isPeak) { result = XCA_PEAK; } else if (isVale) { result = XCA_VALE; } else if (isOBBull) { result = XCA_OB_BULL; } else if (isOBBear) { result = XCA_OB_BEAR; } else if (isFVGBull) { result = XCA_FVG_BULL; } else if (isFVGBear) { result = XCA_FVG_BEAR; } else if (isRSICrossedOverOS) { result = XCA_RSI_COOS; } else if (isRSICrossedUnderOB) { result = XCA_RSI_CUOB; } else if (isTrendBullish) { result = XCA_TREND_BULL; } else if (isTrendBearish) { result = XCA_TREND_BEAR; } else if (isTriggerBullish) { result = XCA_TRIGGER_BULL; } else if (isTriggerBearish) { result = XCA_TRIGGER_BEAR; } // return result; } // int ExtractPivots( XBoxZone &extracted[], ENUM_XCA_PIVOTS type, XBoxZone &source[] // ) { // int result = 0; // Clean(extracted); // bool has = IsValid(type) && HasChild(source); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // ENUM_XCA_PIVOTS iType = GetPivotType(iBox); // has = iType == type; if (has) { // AddRef( iBox, extracted // ); } // iBox.Clean(); } // result = ArraySize(extracted); // return result; } // bool IsFakeBreakeout( XBoxZone &pivot, XCXCAEAHelper *helper, int barIndex = 0 // ) { // bool result = false; // barIndex = NormalizeInt(barIndex, 0); // result = pivot.IsValid(); if (!result) { return result; } // int fromIDX = pivot.FromIndex(); result = barIndex < fromIDX; if (!result) { return result; } // bool isBullish = pivot.IsBullish(); // // Retrieve Required Bars ... XOHCL cBar; XOHCL pBar; XOHCL p2Bar; XOHCL p3Bar; result = cBar.Init( pivot.symbol, pivot.period, barIndex // ); result = result && cBar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); result = result && p2Bar.GetPreviousBar(p3Bar); if (!result) { // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); // return result; } // // Bars Conditions ... // ENUM_X_DIRECTION cBarDir; // // Hammer ... bool isCBarHammer = helper .barAnalyser .IsHammer( cBar, cBarDir // ); bool isCBarBullishHammer = isCBarHammer && IsBullish(cBarDir); bool isCBarBearishHammer = isCBarHammer && IsBearish(cBarDir); // // Rejected ... bool isCBarRejected = helper .barAnalyser .IsRejected( cBar, cBarDir, false, // Force Type ... true // Force Fibo Pressure ... ); bool isCBarBullishRejected = isCBarRejected && IsBullish(cBarDir); bool isCBarBearishRejected = isCBarRejected && IsBearish(cBarDir); // // Engulfed ... bool isCBarEngulfed = helper .barAnalyser .IsEngulfed( cBar, cBarDir // ); bool isCBarBullishEngulfed = isCBarEngulfed && IsBullish(cBarDir); bool isCBarBearishEngulfed = isCBarEngulfed && IsBearish(cBarDir); // // Momentum ... bool isCBarMomentum = helper .barAnalyser .IsMomentum( cBar, cBarDir, 1 // ); bool isCBarBullishMomentum = isCBarMomentum && IsBullish(cBarDir); bool isCBarBearishMomentum = isCBarMomentum && IsBearish(cBarDir); // bool isCBarHasBullishPower = isCBarBullishRejected || isCBarBullishEngulfed || isCBarBullishMomentum; // bool isCBarHasBearishPower = isCBarBearishRejected || isCBarBearishEngulfed || isCBarBearishMomentum; // bool isBarPowerfull = isBullish ? isCBarHasBullishPower : isCBarHasBearishPower; // double breakPrice = isBullish ? pivot.lower : pivot.upper; // // CBar Must Go back InSide Box ... bool isBarInside = cBar.GetUp() > breakPrice && cBar.GetDown() < breakPrice && cBar.GetDirection() == pivot.dir; // result = // // Bar Must Inside Pivot ... isBarInside && // // Bar Must Has Required Direction Power ... isBarPowerfull // ; // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); // 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); // ZeroMemory(this); } /** * 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 = GetDirection(type); // 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 = GetBoxType(type); box.type = typeStr; // box.upper = isBullish ? reserve : value; box.lower = isBullish ? value : reserve; // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } // }; // // Implementations ... class XCXCAEAPOIDetector : public XCBase { // // Public ... public: // // Props ... // // Pivot Verifications and Max Allowed Holding Items ... int maxAllowedPivots; // Max Allowed Holding Pibots ... int pivotVerifications; // Pivots Verifications ... int pivotDetectionLoopbac; // Pivots Detection Loopback ... double ticksDividerInPoints; // Ticks and Volume Detection Divider in Point ... // // TREND ... XBoxZone trendPivotP; // Prev Pivot of Market Trend ... XBoxZone trendPivotC; // Current Pivot of Market Trend ... ENUM_X_DIRECTION trendDir; // Trend Direction ... // // Breaked Pivots ... XBoxZone invalidPivots[]; // // Constructors ... XCXCAEAPOIDetector( XCXCAEAHelper *_helper // ) { // helper = _helper; drawer = new XCPOIDrawer(); barAnalyser = new XCBarAnalyser(); // Default(); } // // De Constructors ... ~XCXCAEAPOIDetector() { // CleanPivots(); // ZeroMemory(helper); ZeroMemory(drawer); ZeroMemory(barAnalyser); } // // Properties ... // // Tools ... // virtual void Default() { // // COMMON ... // maxAllowedPivots = 50; pivotVerifications = 5; ticksDividerInPoints = 15; pivotDetectionLoopbac = 100; // // SWING ... // maxAllowedSwingLifetime = 0; // detectSWHPivots = false; detectSWLPivots = false; // // PV ... // detectPeakPivots = false; detectValePivots = false; // maxAllowedPVLifetime = 0; applySwingsOnPVPivots = false; selectRejectedPVPivots = false; selectEngulfedPVPivots = false; selectPVWhichStartByFVG = false; applySupportAndResistanceOnPVPivots = false; // // FVG ... // detectFVGBullishPivots = false; detectFVGBearishPivots = false; // selectSameBarFVGs = false; maxAllowedFVGLifetime = 0; validateFVGUsingPV = false; applyPVToFVGBoundary = false; selectRejectedFVGPivots = false; selectEngulfedFVGPivots = false; validateFVGUsingManalyser = false; applyLastBarToFVGBoundary = false; selectOnlyFVGWhichHasIndirectionalLastBar = false; // // OB ... maxAllowedOBLifetime = 0; // detectOBBullishPivots = false; detectOBBearishPivots = false; // // TREND ... maxAllowedTrendLifetime = 0; // detectTrendBullishPivots = false; detectTrendBearishPivots = false; // // Trigger Block ... triggerBlockSwingLength = 7; triggerBlockMaxAllowedRange = 0; filterTriggerBlocksBySar = true; triggerBlockBarHasProperSwing = true; detectTriggerBlockBullishPivots = false; detectTriggerBlockBearishPivots = false; triggerBlockBarPressureValidation = true; // } // void Detect( int barIndex = 0 // ) { // if (barIndex < 0) { barIndex = 0; } // int loopback = pivotDetectionLoopbac; loopback = NormalizeInt(loopback, 50); // int idx = -1; int count = 0; bool has = false; // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; int p3IDX = p2IDX + 1; // newSWHPivotDetected = false; newSWLPivotDetected = false; newPeakPivotDetected = false; newValePivotDetected = false; newOBBullishPivotDetected = false; newOBBearishPivotDetected = false; newFVGBullishPivotDetected = false; newFVGBearishPivotDetected = false; newTrendBullishPivotDetected = false; newTrendBearishPivotDetected = false; newTriggerBlockBullishPivotDetected = false; newTriggerBlockBearishPivotDetected = false; // int index = barIndex; int start = index; int end = index + loopback; while (start < end) { // // Retrieve Conditions ... XCAEAConditions conditions; has = helper.GetConditions( conditions, start, 10 // ); if (!has) { conditions.Clean(); continue; } // // Retrieve Bars ... XOHCL zBar; XOHCL cBar; XOHCL pBar; XOHCL p2Bar; has = zBar.Init( conditions.symbol, conditions.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(); conditions.Clean(); // continue; } // // Handle On Time Detection Pivots ... bool isFirstBar = start == index; if (isFirstBar) { // // TRIGGER Block ... // Since Trigger Block Pivots Only Used on Detection Time ... // we have to Detect only when zBar Index is Zero, means at Last Bar ... // in this Senario we Have to Ignore LoopBacks ... // // Bullish ... if (detectTriggerBlockBullishPivots) { // newTriggerBlockBullishPivotDetected = DetectTriggerBlockPivot( barIndex, X_DIRECTION_BULLISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // Bearish ... if (detectTriggerBlockBearishPivots) { // newTriggerBlockBearishPivotDetected = DetectTriggerBlockPivot( barIndex, X_DIRECTION_BEARISH, zBar, cBar, pBar, p2Bar, conditions // ); } } // // Checking Pivots ... // // SWING ... // // SWH ... if (detectSWHPivots) { // newSWHPivotDetected = DetectSwingPivot( barIndex, X_DIRECTION_BEARISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // SWL ... if (detectSWLPivots) { // newSWLPivotDetected = DetectSwingPivot( barIndex, X_DIRECTION_BULLISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // PV ... // // PEAK ... if (detectPeakPivots) { // newPeakPivotDetected = DetectPeakAndValePivot( barIndex, X_DIRECTION_BEARISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // VALE ... if (detectValePivots) { // newValePivotDetected = DetectPeakAndValePivot( barIndex, X_DIRECTION_BULLISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // FVG ... // // Bullish ... if (detectFVGBullishPivots) { // newFVGBullishPivotDetected = DetectFVGPivot( barIndex, X_DIRECTION_BULLISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // Bearish ... if (detectFVGBearishPivots) { // newFVGBearishPivotDetected = DetectFVGPivot( barIndex, X_DIRECTION_BEARISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // OB ... // // Bullish ... if (detectOBBullishPivots) { // newOBBullishPivotDetected = DetectOBPivot( barIndex, X_DIRECTION_BULLISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // Bearish ... if (detectOBBearishPivots) { // newOBBearishPivotDetected = DetectOBPivot( barIndex, X_DIRECTION_BEARISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // TREND ... // // Bullish ... if (detectTrendBullishPivots) { // newTrendBullishPivotDetected = DetectTrendPivot( barIndex, X_DIRECTION_BULLISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // Bearish ... if (detectTrendBearishPivots) { // newTrendBearishPivotDetected = DetectTrendPivot( barIndex, X_DIRECTION_BEARISH, zBar, cBar, pBar, p2Bar, conditions // ); } // // Others ... // start++; // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); conditions.Clean(); } // SortPivots(); } // void Validate( XBoxZone &unavailables[], int barIndex = 0 // ) { // // Implement Validation Senarios ... // // SWING ... ValidateSwingPivots( unavailables, barIndex // ); // // PV ... ValidatePeakValePivots( unavailables, barIndex // ); // // OB ... ValidateOBPivots( unavailables, barIndex // ); // // FVG ... ValidateFVGPivots( unavailables, barIndex // ); // // TREND ... ValidateTrendPivots( unavailables, barIndex // ); // // TRIGGER Block ... ValidateTriggerBlockPivots( unavailables, barIndex // ); // SortPivots(); } // int FillPivots( XBoxZone &pivots[], ENUM_X_DIRECTION forDir = X_DIRECTION_ALL // ) { // int result = 0; // Clean(pivots); // if (forDir == X_DIRECTION_NONE) { return result; } // int count = 0; bool has = false; // bool canFillBullish = forDir == X_DIRECTION_ALL || forDir == X_DIRECTION_BULLISH; // bool canFillBearish = forDir == X_DIRECTION_ALL || forDir == X_DIRECTION_BEARISH; // // Bullish ... if (canFillBullish) { // Copy( swlPivots, pivots, false // ); // Copy( valePivots, pivots, false // ); // Copy( obBullishPivots, pivots, false // ); // Copy( fvgBullishPivots, pivots, false // ); // Copy( trendBullishPivots, pivots, false // ); } // // Bearish ... if (canFillBearish) { // Copy( swhPivots, pivots, false // ); // Copy( peakPivots, pivots, false // ); // Copy( obBearishPivots, pivots, false // ); // Copy( fvgBearishPivots, pivots, false // ); // Copy( trendBearishPivots, pivots, false // ); } // result = ArraySize(pivots); // return result; } // int FillPivots( XBoxZone &pivots[], XBoxZone &unavailables[], ENUM_XCA_PIVOTS &allowedTypes[], datetime to = NULL // ) { // int result = 0; // Clean(pivots); // bool canUpdateTo = IsValid(to); // XBoxZone tmp[]; bool has = false; int tmpCount = FillPivots( tmp, X_DIRECTION_ALL // ); has = IsValidSize(tmpCount); if (!has) { return result; } // XBoxZone iBox; while (HasChild(tmp)) { // iBox = tmp[0]; ArrayRemove( tmp, 0, 1 // ); // if (canUpdateTo) { iBox.to = to; } // ENUM_XCA_PIVOTS iType = GetPivotType(iBox); bool isAllowed = !HasChild(allowedTypes) ? true : Contains( iType, allowedTypes // ); // int idx = -1; bool isUnAvailable = FindBoxIndex( idx, iBox, unavailables // ); // if (isAllowed && !isUnAvailable) { // AddRef( iBox, pivots // ); } // iBox.Clean(); } iBox.Clean(); // result = ArraySize(pivots); // return result; } // int FillPivots( XBoxZone &decision, XBoxZone &pivots[], XBoxZone &unavailables[], ENUM_XCA_PIVOTS &allowedTypes[], datetime to = NULL // ) { // int result = false; // bool has = false; has = decision.IsValid(); if (!has) { return result; } // XBoxZone tmp[]; int count = FillPivots( tmp, unavailables, allowedTypes, to // ); // for (int i = 0; i < count; i++) { // XBoxZone iBox = tmp[i]; // // Validate Box ... has = // // Validate Time .. iBox.from > decision.from // && // // Validate Price ... ( // (iBox.upper < decision.upper && iBox.upper > decision.lower) // || // (iBox.lower > decision.lower && iBox.lower < decision.upper) // ); if (has) { // AddRef( iBox, pivots // ); } // iBox.Clean(); } // Clean(tmp); // result = ArraySize(pivots); // return result; } // // Pivots ... // // INVALID Pivots ... // bool HasInvalidPivots() { return HasChild(invalidPivots); } // int CountInvalidPivots() { return ArraySize(invalidPivots); } // // SWING ... // int maxAllowedSwingLifetime; // Max Allowed Swing Life ... // bool DetectSwingPivot( int barIndex, ENUM_X_DIRECTION forDir, XOHCL &zBar, XOHCL &cBar, XOHCL &pBar, XOHCL &p2Bar, XCAEAConditions &conditions // ) { // bool result = false; // // Checking Direction ... result = HasDirection(forDir); if (!result) { return result; } // bool forBullish = IsBullish(forDir); bool forBearish = IsBearish(forDir); // // Check Allowed ... result = forBullish ? detectSWLPivots : detectSWHPivots; if (!result) { return result; } // // Validate Args ... result = // barIndex >= 0 && zBar.IsValid() && cBar.IsValid() && pBar.IsValid() && p2Bar.IsValid() // ; if (!result) { return result; } // // Define Requirements ... // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; // datetime cTime = zBar.time; string symbol = zBar.symbol; ENUM_TIMEFRAMES period = zBar.period; double points = GetPoints(symbol); // // Reading Conditional Values ... // // PEAK ... double zPeak = conditions.peakBuffer[zIDX]; double cPeak = conditions.peakBuffer[cIDX]; double pPeak = conditions.peakBuffer[pIDX]; double p2Peak = conditions.peakBuffer[p2IDX]; // // VALE ... double zVale = conditions.valeBuffer[zIDX]; double cVale = conditions.valeBuffer[cIDX]; double pVale = conditions.valeBuffer[pIDX]; double p2Vale = conditions.valeBuffer[p2IDX]; // // SWING High .. double zSwingHigh = conditions.swingHighBuffer[zIDX]; double cSwingHigh = conditions.swingHighBuffer[cIDX]; double pSwingHigh = conditions.swingHighBuffer[pIDX]; double p2SwingHigh = conditions.swingHighBuffer[p2IDX]; // // SWING Low ... double zSwingLow = conditions.swingLowBuffer[zIDX]; double cSwingLow = conditions.swingLowBuffer[cIDX]; double pSwingLow = conditions.swingLowBuffer[pIDX]; double p2SwingLow = conditions.swingLowBuffer[p2IDX]; // // Prepare Conditinal Conditions ... // // SWH ... // bool isSWHSameLast = cSwingHigh == pSwingHigh; bool isSWHSameLastPrev = pSwingHigh == p2SwingHigh; // bool isSWHSwitchedToSameLast = isSWHSameLast && !isSWHSameLastPrev; bool isSWHFinishedFromSameLast = !isSWHSameLast && isSWHSameLastPrev; // // SWL ... // bool isSWLSameLast = cSwingLow == pSwingLow; bool isSWLSameLastPrev = pSwingLow == p2SwingLow; // bool isSWLSwitchedToSameLast = isSWLSameLast && !isSWLSameLastPrev; bool isSWLFinishedFromSameLast = !isSWLSameLast && isSWLSameLastPrev; // // Summarizing Conditions ... // result = false; // bool hasStartCondition = // forBullish ? isSWLFinishedFromSameLast : isSWHFinishedFromSameLast // ; // bool hasContinuationCondition = // forBullish ? isSWLSameLast : isSWHSameLast // ; // bool hasEndCondition = // forBullish ? isSWLSwitchedToSameLast : isSWHSwitchedToSameLast // ; // // // // // ReInstance Pivot ... if (hasStartCondition) { // // SWL ... if (forBullish) { // swlPivot.Clean(); // swlPivot.type = XCA_SWL; swlPivot.symbol = symbol; swlPivot.period = period; // swlPivot.to = pBar.time; swlPivot.from = pBar.time; swlPivot.value = pSwingLow; swlPivot.reserve = pVale; } // // SWH ... if (forBearish) { // swhPivot.Clean(); // swhPivot.type = XCA_SWH; swhPivot.symbol = symbol; swhPivot.period = period; // swhPivot.to = pBar.time; swhPivot.from = pBar.time; swhPivot.value = pSwingHigh; swhPivot.reserve = pPeak; } } // // Calculate and Fill Pivot Requirements ... if (hasContinuationCondition) { // // SWL ... if (forBullish) { // swlPivot.from = pBar.time; // swlPivot.reserve = swlPivot.reserve == 0 ? pVale : MathMin(swlPivot.reserve, pVale); } // // SWH ... if (forBearish) { // swhPivot.from = pBar.time; // swhPivot.reserve = swhPivot.reserve == 0 ? pPeak : MathMin(swhPivot.reserve, pPeak); } } // // End up Pivot and Store it ... if (hasEndCondition) { // // SWL ... if (forBullish) { // result = swlPivot.IsValid() && swlPivot.GetAge() >= pivotVerifications; if (result) { // XBoxZone iBox; result = swlPivot.AsBox(iBox); if (result) { // newSWLPivotDetected = AddBox( iBox, swlPivots // ); } // iBox.Clean(); } // swlPivot.Clean(); } // // SWH ... if (forBearish) { // result = swhPivot.IsValid() && swhPivot.GetAge() >= pivotVerifications; if (result) { // XBoxZone iBox; result = swhPivot.AsBox(iBox); if (result) { // newSWHPivotDetected = AddBox( iBox, swhPivots // ); } // iBox.Clean(); } // swhPivot.Clean(); } } // return result; } // void ValidateSwingPivots( XBoxZone &unavailables[], int barIndex = 0 // ) { // bool has = false; // bool applyLifetimeValidating = maxAllowedSwingLifetime > 0; // // SWH ... has = HasSWHPivots(); if (has) { // ApplyValidationOnBoxes( swhPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( swhPivots, maxAllowedSwingLifetime, barIndex // ); } } // // SWL ... has = HasSWLPivots(); if (has) { // ApplyValidationOnBoxes( swlPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( swlPivots, maxAllowedSwingLifetime, barIndex // ); } } } // // SWL ... // XCAPivot swlPivot; bool detectSWLPivots; XBoxZone swlPivots[]; bool newSWLPivotDetected; // bool HasSWLPivots() { return HasChild(swlPivots); } // int CountSWLPivots() { return ArraySize(swlPivots); } // // SWH ... // XCAPivot swhPivot; bool detectSWHPivots; XBoxZone swhPivots[]; bool newSWHPivotDetected; // bool HasSWHPivots() { return HasChild(swhPivots); } // int CountSWHPivots() { return ArraySize(swhPivots); } // // PV ... // int maxAllowedPVLifetime; // Max Allowed PV Life ... bool applySwingsOnPVPivots; // Apply Swings on PV Pivots ... bool selectRejectedPVPivots; // Select Rejected PV Pivots ... bool selectEngulfedPVPivots; // Select Engulfed PV Pivots ... bool selectPVWhichStartByFVG; // Select PV Pivots Which Starts by FVG ... bool applySupportAndResistanceOnPVPivots; // Apply Support and Resistance on PV Pivots ... // bool DetectPeakAndValePivot( int barIndex, ENUM_X_DIRECTION forDir, XOHCL &zBar, XOHCL &cBar, XOHCL &pBar, XOHCL &p2Bar, XCAEAConditions &conditions // ) { // bool result = false; // // Checking Direction ... result = HasDirection(forDir); if (!result) { return result; } // bool forBullish = IsBullish(forDir); bool forBearish = IsBearish(forDir); // // Check Allowed ... result = forBullish ? detectValePivots : detectPeakPivots; if (!result) { return result; } // // Validate Args ... result = // barIndex >= 0 && zBar.IsValid() && cBar.IsValid() && pBar.IsValid() && p2Bar.IsValid() // ; if (!result) { return result; } // // Define Requirements ... // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; // datetime cTime = zBar.time; string symbol = zBar.symbol; ENUM_TIMEFRAMES period = zBar.period; double points = GetPoints(symbol); // // Reading Conditional Values ... // // PEAK ... double zPeak = conditions.peakBuffer[zIDX]; double cPeak = conditions.peakBuffer[cIDX]; double pPeak = conditions.peakBuffer[pIDX]; double p2Peak = conditions.peakBuffer[p2IDX]; // // PEAK Golden ... double zPeakGolden = conditions.peakGoldenBuffer[zIDX]; double cPeakGolden = conditions.peakGoldenBuffer[cIDX]; double pPeakGolden = conditions.peakGoldenBuffer[pIDX]; double p2PeakGolden = conditions.peakGoldenBuffer[p2IDX]; // // VALE ... double zVale = conditions.valeBuffer[zIDX]; double cVale = conditions.valeBuffer[cIDX]; double pVale = conditions.valeBuffer[pIDX]; double p2Vale = conditions.valeBuffer[p2IDX]; // // VALE Golden ... double zValeGolden = conditions.valeGoldenBuffer[zIDX]; double cValeGolden = conditions.valeGoldenBuffer[cIDX]; double pValeGolden = conditions.valeGoldenBuffer[pIDX]; double p2ValeGolden = conditions.valeGoldenBuffer[p2IDX]; // // SWING High .. double zSwingHigh = conditions.swingHighBuffer[zIDX]; double cSwingHigh = conditions.swingHighBuffer[cIDX]; double pSwingHigh = conditions.swingHighBuffer[pIDX]; double p2SwingHigh = conditions.swingHighBuffer[p2IDX]; // // SWING Low ... double zSwingLow = conditions.swingLowBuffer[zIDX]; double cSwingLow = conditions.swingLowBuffer[cIDX]; double pSwingLow = conditions.swingLowBuffer[pIDX]; double p2SwingLow = conditions.swingLowBuffer[p2IDX]; // // SUPPORT ... double zSupport = conditions.supportBuffer[zIDX]; double cSupport = conditions.supportBuffer[cIDX]; double pSupport = conditions.supportBuffer[pIDX]; double p2Support = conditions.supportBuffer[p2IDX]; // // RESISTANCE ... double zResistance = conditions.resistanceBuffer[zIDX]; double cResistance = conditions.resistanceBuffer[cIDX]; double pResistance = conditions.resistanceBuffer[pIDX]; double p2Resistance = conditions.resistanceBuffer[p2IDX]; // // Detecting Bar Conditions ... // ENUM_X_DIRECTION cBarDir; // // Rejected ... bool isCBarRejected = helper .barAnalyser .IsRejected( cBar, cBarDir, false, // Force Type ... false // Force Fibo Pressure ... ); // bool isCBarBullishRejected = forBullish && isCBarRejected && IsBullish(cBarDir); bool isCBarBearishRejected = forBearish && isCBarRejected && IsBearish(cBarDir); // bool isPBarRejected = helper .barAnalyser .IsRejected( pBar, cBarDir, false, // Force Type ... false // Force Fibo Pressure ... ); bool isPBarBullishRejected = forBullish && isPBarRejected && IsBullish(cBarDir); bool isPBarBearishRejected = forBearish && isPBarRejected && IsBearish(cBarDir); // bool isBarBullishRejected = forBullish && (isCBarBullishRejected || isPBarBullishRejected); // bool isBarBearishRejected = forBearish && (isCBarBearishRejected || isPBarBearishRejected); // // Engulfed ... bool isCBarEngulfed = helper .barAnalyser .IsEngulfed( cBar, cBarDir // ); bool isCBarBullishEngulfed = forBullish && isCBarEngulfed && IsBullish(cBarDir); bool isCBarBearishEngulfed = forBearish && isCBarEngulfed && IsBearish(cBarDir); // bool isPBarEngulfed = helper .barAnalyser .IsEngulfed( pBar, cBarDir // ); bool isPBarBullishEngulfed = forBullish && isPBarEngulfed && IsBullish(cBarDir); bool isPBarBearishEngulfed = forBearish && isPBarEngulfed && IsBearish(cBarDir); // bool isBarBullishEngulfed = forBullish && (isCBarBullishEngulfed || isPBarBullishEngulfed); // bool isBarBearishEngulfed = forBearish && (isCBarBearishEngulfed || isPBarBearishEngulfed); // // Prepare Conditinal Conditions ... // // PEAK ... // bool isPeakSameLast = cPeak == pPeak; bool isPeakSameLastPrev = pPeak == p2Peak; // if (applySwingsOnPVPivots) { // isPeakSameLast = isPeakSameLast && cSwingHigh == cPeak && cSwingHigh == pSwingHigh; // isPeakSameLastPrev = isPeakSameLastPrev && pSwingHigh == pPeak && pSwingHigh == p2SwingHigh; } // if (applySupportAndResistanceOnPVPivots) { // isPeakSameLast = isPeakSameLast && cResistance == cPeak && cResistance == pResistance; // isPeakSameLastPrev = isPeakSameLastPrev && pResistance == pPeak && pResistance == p2Resistance; } // bool isPeakSwitchedToSameLast = isPeakSameLast && !isPeakSameLastPrev; bool isPeakFinishedFromSameLast = !isPeakSameLast && isPeakSameLastPrev; // // VALE ... // bool isValeSameLast = cVale == pVale; bool isValeSameLastPrev = pVale == p2Vale; // if (applySwingsOnPVPivots) { // isValeSameLast = isValeSameLast && cSwingLow == cVale && cSwingLow == pSwingLow; // isValeSameLastPrev = isValeSameLastPrev && pSwingLow == pVale && pSwingLow == p2SwingLow; } // if (applySupportAndResistanceOnPVPivots) { // isValeSameLast = isValeSameLast && cSupport == cVale && cSupport == pSupport; // isValeSameLastPrev = isValeSameLastPrev && pSupport == pVale && pSupport == p2Support; } // bool isValeSwitchedToSameLast = isValeSameLast && !isValeSameLastPrev; bool isValeFinishedFromSameLast = !isValeSameLast && isValeSameLastPrev; // // Summarizing Conditions ... // result = false; // bool hasStartCondition = // forBullish ? isValeFinishedFromSameLast : isPeakFinishedFromSameLast // ; // bool hasContinuationCondition = // forBullish ? isValeSameLast : isPeakSameLast // ; // bool hasEndCondition = // forBullish ? isValeSwitchedToSameLast : isPeakSwitchedToSameLast // ; // // Apply Validations ... if (hasEndCondition) { // bool hasSelectionType = selectRejectedPVPivots || selectEngulfedPVPivots; // bool isPVRejected = forBullish ? (isBarBullishRejected && selectRejectedPVPivots) : (isBarBearishRejected && selectRejectedPVPivots); // bool isPVEngulfed = forBullish ? (isBarBullishEngulfed && selectEngulfedPVPivots) : (isBarBearishEngulfed && selectEngulfedPVPivots); // bool isBarPassed = !hasSelectionType ? true : isPVRejected || isPVEngulfed; // hasEndCondition = isBarPassed && hasEndCondition; if (!hasEndCondition) { // // VALE ... if (forBullish) { valePivot.Clean(); } // // PEAK ... if (forBearish) { peakPivot.Clean(); } } } // // // // // ReInstance Pivot ... if (hasStartCondition) { // // VALE ... if (forBullish) { // valePivot.Clean(); // valePivot.type = XCA_VALE; valePivot.symbol = symbol; valePivot.period = period; // valePivot.to = pBar.time; valePivot.from = pBar.time; valePivot.value = pVale; valePivot.reserve = pValeGolden; } // // PEAK ... if (forBearish) { // peakPivot.Clean(); // peakPivot.type = XCA_PEAK; peakPivot.symbol = symbol; peakPivot.period = period; // peakPivot.to = pBar.time; peakPivot.from = pBar.time; peakPivot.value = pPeak; peakPivot.reserve = pPeakGolden; } } // // Calculate and Fill Pivot Requirements ... if (hasContinuationCondition) { // // VALE ... if (forBullish) { // valePivot.from = pBar.time; // valePivot.reserve = valePivot.reserve == 0 ? pValeGolden : MathMin(valePivot.reserve, pValeGolden); } // // PEAK ... if (forBearish) { // peakPivot.from = pBar.time; // peakPivot.reserve = peakPivot.reserve == 0 ? pPeakGolden : MathMax(peakPivot.reserve, pPeakGolden); } } // // End up Pivot and Store it ... if (hasEndCondition) { // // VALE ... if (forBullish) { // result = valePivot.IsValid() && valePivot.GetAge() >= pivotVerifications; if (result) { // XBoxZone iBox; result = valePivot.AsBox(iBox); if (result) { // newValePivotDetected = AddBox( iBox, valePivots // ); } // iBox.Clean(); } // valePivot.Clean(); } // // PEAK ... if (forBearish) { // result = peakPivot.IsValid() && peakPivot.GetAge() >= pivotVerifications; if (result) { // XBoxZone iBox; result = peakPivot.AsBox(iBox); if (result) { // newPeakPivotDetected = AddBox( iBox, peakPivots // ); } // iBox.Clean(); } // peakPivot.Clean(); } } // return result; } // void ValidatePeakValePivots( XBoxZone &unavailables[], int barIndex = 0 // ) { // bool has = false; // bool applyLifetimeValidating = maxAllowedPVLifetime > 0; // // PEAK ... has = HasPeakPivots(); if (has) { // ApplyValidationOnBoxes( peakPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( peakPivots, maxAllowedPVLifetime, barIndex // ); } } // // VALE ... has = HasValePivots(); if (has) { // ApplyValidationOnBoxes( valePivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( valePivots, maxAllowedPVLifetime, barIndex // ); } } } // // PEAK ... // XCAPivot peakPivot; bool detectPeakPivots; XBoxZone peakPivots[]; bool newPeakPivotDetected; // bool HasPeakPivots() { return HasChild(peakPivots); } // int CountPeakPivots() { return ArraySize(peakPivots); } // // VALE ... // XCAPivot valePivot; bool detectValePivots; XBoxZone valePivots[]; bool newValePivotDetected; // bool HasValePivots() { return HasChild(valePivots); } // int CountValePivots() { return ArraySize(valePivots); } // // OB ... int maxAllowedOBLifetime; // Max Allowed OB Life ... // bool DetectOBPivot( int barIndex, ENUM_X_DIRECTION forDir, XOHCL &zBar, XOHCL &cBar, XOHCL &pBar, XOHCL &p2Bar, XCAEAConditions &conditions // ) { // bool result = false; // // Checking Direction ... result = HasDirection(forDir); if (!result) { return result; } // bool forBullish = IsBullish(forDir); bool forBearish = IsBearish(forDir); // // Check Allowed ... result = forBullish ? detectOBBullishPivots : detectOBBearishPivots; if (!result) { return result; } // // Validate Args ... result = // barIndex >= 0 && zBar.IsValid() && cBar.IsValid() && pBar.IsValid() && p2Bar.IsValid() // ; if (!result) { return result; } // // Prepare Conditinal Conditions ... // // Default OB Detection ... XBoxZone obBox; bool isOB = barAnalyser.IsOB( cBar, obBox, true, // OB FVG Bar Type ... true // TWO Bar Verification ... ); bool isBullishOB = isOB && forBullish && obBox.IsBullish(); bool isBearishOB = isOB && forBearish && obBox.IsBearish(); // // Summarizing Conditions ... // result = false; // bool hasStartCondition = false; bool hasContinuationCondition = false; bool hasEndCondition = isBullishOB || isBearishOB; // // ReInstance Pivot ... if (hasStartCondition) { // } // // Calculate and Fill Pivot Requirements ... if (hasContinuationCondition) { // } // // End up Pivot and Store it ... if (hasEndCondition) { // XBoxZone iBox; XCAPivot iPivot; // iPivot.to = obBox.to; iPivot.from = obBox.from; iPivot.symbol = obBox.symbol; iPivot.period = obBox.period; iPivot.type = forBullish ? XCA_OB_BULL : XCA_OB_BEAR; iPivot.value = forBullish ? obBox.lower : obBox.upper; iPivot.reserve = forBullish ? obBox.upper : obBox.lower; // result = iPivot.IsValid(); if (result) { // result = iPivot.AsBox(iBox); if (result) { // if (forBullish) { // result = AddBox( iBox, obBullishPivots // ); } else { // result = AddBox( iBox, obBearishPivots // ); } } } // iBox.Clean(); iPivot.Clean(); } // return result; } // void ValidateOBPivots( XBoxZone &unavailables[], int barIndex = 0 // ) { // bool has = false; // bool applyLifetimeValidating = maxAllowedOBLifetime > 0; // // Bullish ... has = HasOBBullishPivots(); if (has) { // ApplyValidationOnBoxes( obBullishPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( obBullishPivots, maxAllowedOBLifetime, barIndex // ); } } // // Bearish ... has = HasOBBearishPivots(); if (has) { // ApplyValidationOnBoxes( obBearishPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( obBearishPivots, maxAllowedOBLifetime, barIndex // ); } } } // // OB Bullish Pivots ... // bool detectOBBullishPivots; XBoxZone obBullishPivots[]; bool newOBBullishPivotDetected; // bool HasOBBullishPivots() { return HasChild(obBullishPivots); } // int CountOBBullishPivots() { return ArraySize(obBullishPivots); } // // OB Bearish Pivots ... // bool detectOBBearishPivots; XBoxZone obBearishPivots[]; bool newOBBearishPivotDetected; // bool HasOBBearishPivots() { return HasChild(obBearishPivots); } // int CountOBBearishPivots() { return ArraySize(obBearishPivots); } // // FVG ... // bool selectSameBarFVGs; // Select FVGs which has Same Type Bars ... bool validateFVGUsingPV; // Detect FVG Type Two ( Validating Using PV ) ... int maxAllowedFVGLifetime; // Max Allowed FVG Life ... bool applyPVToFVGBoundary; // Apply PV to FVG Boundary ... bool selectRejectedFVGPivots; // Select Rejected FVG Pivots ... bool selectEngulfedFVGPivots; // Select Engulfed FVG Pivots ... bool validateFVGUsingManalyser; // Detect FVG Type One ( Validating Using MAnalyser ) ... bool applyLastBarToFVGBoundary; // Apply Last Bar to FVG Boundary ... bool selectOnlyFVGWhichHasIndirectionalLastBar; // Select Only FVGs which has Indirectionsl Last Bar, uses to Order Block ... // bool DetectFVGPivot( int barIndex, ENUM_X_DIRECTION forDir, XOHCL &zBar, XOHCL &cBar, XOHCL &pBar, XOHCL &p2Bar, XCAEAConditions &conditions // ) { // bool result = false; // // Checking Direction ... result = HasDirection(forDir); if (!result) { return result; } // bool forBullish = IsBullish(forDir); bool forBearish = IsBearish(forDir); // // Check Allowed ... result = forBullish ? detectFVGBullishPivots : detectFVGBearishPivots; if (!result) { return result; } // // Validate Args ... result = // barIndex >= 0 && zBar.IsValid() && cBar.IsValid() && pBar.IsValid() && p2Bar.IsValid() // ; if (!result) { return result; } // // Define Requirements ... // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; // datetime cTime = zBar.time; string symbol = zBar.symbol; ENUM_TIMEFRAMES period = zBar.period; double points = GetPoints(symbol); // // Reading Conditional Values ... // // PEAK ... double zPeak = conditions.peakBuffer[zIDX]; double cPeak = conditions.peakBuffer[cIDX]; double pPeak = conditions.peakBuffer[pIDX]; double p2Peak = conditions.peakBuffer[p2IDX]; // // VALE ... double zVale = conditions.valeBuffer[zIDX]; double cVale = conditions.valeBuffer[cIDX]; double pVale = conditions.valeBuffer[pIDX]; double p2Vale = conditions.valeBuffer[p2IDX]; // // MANALYSER ... // // MAH ... double zMAH = conditions.mahBuffer[zIDX]; double cMAH = conditions.mahBuffer[cIDX]; double pMAH = conditions.mahBuffer[pIDX]; double p2MAH = conditions.mahBuffer[p2IDX]; // // MAL ... double zMAL = conditions.malBuffer[zIDX]; double cMAL = conditions.malBuffer[cIDX]; double pMAL = conditions.malBuffer[pIDX]; double p2MAL = conditions.malBuffer[p2IDX]; // // MAC ... double zMAC = conditions.macBuffer[zIDX]; double cMAC = conditions.macBuffer[cIDX]; double pMAC = conditions.macBuffer[pIDX]; double p2MAC = conditions.macBuffer[p2IDX]; // // Detecting Bar Conditions ... // ENUM_X_DIRECTION p2BarDir; // // Rejected ... bool isP2BarRejected = helper .barAnalyser .IsRejected( p2Bar, p2BarDir, false, // Force Type ... true // Force Fibo Pressure ... ); bool isP2BarBullishRejected = isP2BarRejected && IsBullish(p2BarDir); bool isP2BarBearishRejected = isP2BarRejected && IsBearish(p2BarDir); // // Engulfed ... bool isP2BarEngulfed = helper .barAnalyser .IsEngulfed( p2Bar, p2BarDir // ); bool isP2BarBullishEngulfed = isP2BarEngulfed && IsBullish(p2BarDir); bool isP2BarBearishEngulfed = isP2BarEngulfed && IsBearish(p2BarDir); // // Prepare Conditinal Conditions ... // // Default FVG Detection ... XBoxZone fvgBox; bool isFVG = barAnalyser.IsFVG( cBar, fvgBox // ); bool isBullishFVG = isFVG && forBullish && fvgBox.IsBullish(); bool isBearishFVG = isFVG && forBearish && fvgBox.IsBearish(); // // Summarizing Conditions ... // result = false; // bool hasStartCondition = false; bool hasContinuationCondition = false; bool hasEndCondition = isBullishFVG || isBearishFVG; // // Apply all Filtering ... if (hasEndCondition) { // XOHCL p3Bar; p2Bar.GetPreviousBar(p3Bar); // bool isFVGValid = true; // // Validate FVG Using Manalyser ... bool isManalyserValid = false; if (validateFVGUsingManalyser) { // isManalyserValid = hasEndCondition && (forBullish ? fvgBox.upper <= cMAL : fvgBox.lower >= cMAH); } // // Validate FVG Using PV ... bool isPVValid = false; if (validateFVGUsingPV) { // isPVValid = hasEndCondition && (forBullish ? (p2Peak < pPeak || pPeak < cPeak) : (p2Vale > pVale || pVale > cVale)); } // // Select Pure FVG ... bool isPureFVGValid = !validateFVGUsingPV && !validateFVGUsingManalyser; // // Summarise Validation ... isFVGValid = isPVValid || isPureFVGValid || isManalyserValid; // bool isFVGBarPassed = false; // // Select Same Bars FVGs ... bool isFVGHasSameBar = true; if (selectSameBarFVGs) { // isFVGHasSameBar = forBullish ? (cBar.IsBullish() && pBar.IsBullish() && p2Bar.IsBullish()) : (cBar.IsBearish() && pBar.IsBearish() && p2Bar.IsBearish()); isFVGBarPassed = isFVGBarPassed || isFVGHasSameBar; } // // Select Rejected FVG ... bool isFVGRejected = true; if (selectRejectedFVGPivots) { // isFVGRejected = (forBullish ? isP2BarBullishRejected : isP2BarBearishRejected); isFVGBarPassed = isFVGBarPassed || isFVGRejected; } // // Select Engulfed FVG ... bool isFVGEngulfed = true; if (selectEngulfedFVGPivots) { // isFVGEngulfed = (forBullish ? isP2BarBullishEngulfed : isP2BarBearishEngulfed); isFVGBarPassed = isFVGBarPassed || isFVGEngulfed; } // // Select Only FVGs Which Has Indirectional Last Bar ... bool isFVGHasIndirectionalStart = true; if (selectOnlyFVGWhichHasIndirectionalLastBar) { // isFVGHasIndirectionalStart = p3Bar.IsValid() && (forBullish ? p3Bar.IsBearish() : p3Bar.IsBullish()); isFVGBarPassed = isFVGBarPassed || isFVGHasIndirectionalStart; } // // Summarise Bar Pass ... isFVGBarPassed = (selectSameBarFVGs || selectRejectedFVGPivots || selectEngulfedFVGPivots || selectOnlyFVGWhichHasIndirectionalLastBar) ? isFVGBarPassed : true; // hasEndCondition = isFVGValid && isFVGBarPassed; // // Apply Boundary ... if (hasEndCondition) { // double iValue = forBullish ? fvgBox.upper : fvgBox.lower; // if (applyPVToFVGBoundary) { // fvgBox.upper = forBullish ? fvgBox.upper : cPeak; // fvgBox.lower = forBullish ? cVale : fvgBox.lower; } // if (applyLastBarToFVGBoundary) { // fvgBox.lower = MathMin(p3Bar.low, fvgBox.lower); fvgBox.upper = MathMax(p3Bar.high, fvgBox.upper); } } // p3Bar.Clean(); } // // ReInstance Pivot ... if (hasStartCondition) { // } // // Calculate and Fill Pivot Requirements ... if (hasContinuationCondition) { // } // // End up Pivot and Store it ... if (hasEndCondition) { // XBoxZone iBox; XCAPivot iPivot; // iPivot.to = fvgBox.to; iPivot.from = fvgBox.from; iPivot.symbol = fvgBox.symbol; iPivot.period = fvgBox.period; iPivot.type = forBullish ? XCA_FVG_BULL : XCA_FVG_BEAR; iPivot.value = forBullish ? fvgBox.lower : fvgBox.upper; iPivot.reserve = forBullish ? fvgBox.upper : fvgBox.lower; // result = iPivot.IsValid(); if (result) { // result = iPivot.AsBox(iBox); if (result) { // if (forBullish) { // result = AddBox( iBox, fvgBullishPivots // ); } else { // result = AddBox( iBox, fvgBearishPivots // ); } } } // iBox.Clean(); iPivot.Clean(); } // return result; } // void ValidateFVGPivots( XBoxZone &unavailables[], int barIndex = 0 // ) { // bool has = false; // bool applyLifetimeValidating = maxAllowedFVGLifetime > 0; // // Bullish ... has = HasFVGBullishPivots(); if (has) { // ApplyValidationOnBoxes( fvgBullishPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( fvgBullishPivots, maxAllowedFVGLifetime, barIndex // ); } } // // Bearish ... has = HasFVGBearishPivots(); if (has) { // ApplyValidationOnBoxes( fvgBearishPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( fvgBearishPivots, maxAllowedFVGLifetime, barIndex // ); } } } // // FVG Bullish Pivots ... // bool detectFVGBullishPivots; XBoxZone fvgBullishPivots[]; bool newFVGBullishPivotDetected; // bool HasFVGBullishPivots() { return HasChild(fvgBullishPivots); } // int CountFVGBullishPivots() { return ArraySize(fvgBullishPivots); } // // FVG Bearish Pivots ... // bool detectFVGBearishPivots; XBoxZone fvgBearishPivots[]; bool newFVGBearishPivotDetected; // bool HasFVGBearishPivots() { return HasChild(fvgBearishPivots); } // int CountFVGBearishPivots() { return ArraySize(fvgBearishPivots); } // // TREND ... // int maxAllowedTrendLifetime; // Max Allowed Trend Life ... // bool DetectTrendPivot( int barIndex, ENUM_X_DIRECTION forDir, XOHCL &zBar, XOHCL &cBar, XOHCL &pBar, XOHCL &p2Bar, XCAEAConditions &conditions // ) { // bool result = false; // // Checking Direction ... result = HasDirection(forDir); if (!result) { return result; } // bool forBullish = IsBullish(forDir); bool forBearish = IsBearish(forDir); // // Check Allowed ... result = forBullish ? detectTrendBullishPivots : detectTrendBearishPivots; if (!result) { return result; } // // Validate Args ... result = // barIndex >= 0 && zBar.IsValid() && cBar.IsValid() && pBar.IsValid() && p2Bar.IsValid() // ; if (!result) { return result; } // // Define Requirements ... // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; // datetime cTime = zBar.time; string symbol = zBar.symbol; ENUM_TIMEFRAMES period = zBar.period; double points = GetPoints(symbol); // // Reading Conditional Values ... // // TREND ... double zTrend = conditions.trendBuffer[zIDX]; double cTrend = conditions.trendBuffer[cIDX]; double pTrend = conditions.trendBuffer[pIDX]; double p2Trend = conditions.trendBuffer[p2IDX]; // // TREND State ... double zTrendState = conditions.trendStateBuffer[zIDX]; double cTrendState = conditions.trendStateBuffer[cIDX]; double pTrendState = conditions.trendStateBuffer[pIDX]; double p2TrendState = conditions.trendStateBuffer[p2IDX]; // // Prepare Conditinal Conditions ... // // Bullish ... // bool isTrendBullish = cTrendState > 0; bool isTrendBullishPrev = pTrendState > 0; // bool isTrendSwitchedToBullish = isTrendBullish && !isTrendBullishPrev; bool isTrendFinishedFromBullish = !isTrendBullish && isTrendBullishPrev; // // Bearish ... // bool isTrendBearish = cTrendState < 0; bool isTrendBearishPrev = pTrendState < 0; // bool isTrendSwitchedToBearish = isTrendBearish && !isTrendBearishPrev; bool isTrendFinishedFromBearish = !isTrendBearish && isTrendBearishPrev; // // Summarizing Conditions ... // result = false; // bool hasStartCondition = forBullish ? isTrendFinishedFromBullish : isTrendFinishedFromBearish; bool hasContinuationCondition = forBullish ? isTrendBullish : isTrendBearish; bool hasEndCondition = forBullish ? isTrendSwitchedToBullish : isTrendSwitchedToBearish; // // ReInstance Pivot ... if (hasStartCondition) { // // Bullish ... if (forBullish) { // trendBullishPivot.Clean(); // trendBullishPivot.symbol = symbol; trendBullishPivot.period = period; trendBullishPivot.type = XCA_TREND_BULL; // trendBullishPivot.to = pBar.time; trendBullishPivot.from = pBar.time; trendBullishPivot.value = pTrend; trendBullishPivot.reserve = pTrend; } // // Bearish ... if (forBearish) { // trendBearishPivot.Clean(); // trendBearishPivot.symbol = symbol; trendBearishPivot.period = period; trendBearishPivot.type = XCA_TREND_BEAR; // trendBearishPivot.to = pBar.time; trendBearishPivot.from = pBar.time; trendBearishPivot.value = pTrend; trendBearishPivot.reserve = pTrend; } } // // Calculate and Fill Pivot Requirements ... if (hasContinuationCondition) { // // Bullish ... if (forBullish) { // trendBullishPivot.from = pBar.time; // Add( pTrend, trendBullishPivot.values // ); Add( pTrend, trendBullishPivot.values // ); } // // Bearish ... if (forBearish) { // trendBearishPivot.from = pBar.time; // Add( pTrend, trendBearishPivot.values // ); Add( pTrend, trendBearishPivot.values // ); } } // // End up Pivot and Store it ... if (hasEndCondition) { // // Bullish ... if (forBullish) { // // Update Values ... trendBullishPivot.value = GetMin(trendBullishPivot.values); trendBullishPivot.reserve = GetMax(trendBullishPivot.values); // result = trendBullishPivot.IsValid() && trendBullishPivot.GetAge() >= pivotVerifications; if (result) { // XBoxZone iBox; result = trendBullishPivot.AsBox(iBox); if (result) { // newTrendBullishPivotDetected = AddBox( iBox, trendBullishPivots // ); } // iBox.Clean(); } // trendBullishPivot.Clean(); } // // Bearish ... if (forBearish) { // // Update Values ... trendBearishPivot.value = GetMax(trendBearishPivot.values); trendBearishPivot.reserve = GetMin(trendBearishPivot.values); // result = trendBearishPivot.IsValid() && trendBearishPivot.GetAge() >= pivotVerifications; if (result) { // XBoxZone iBox; result = trendBearishPivot.AsBox(iBox); if (result) { // newTrendBearishPivotDetected = AddBox( iBox, trendBearishPivots // ); } // iBox.Clean(); } // trendBearishPivot.Clean(); } } // return result; } // void ValidateTrendPivots( XBoxZone &unavailables[], int barIndex = 0 // ) { // bool has = false; // bool applyLifetimeValidating = maxAllowedTrendLifetime > 0; // // Bullish ... has = HasTrendBullishPivots(); if (has) { // ApplyValidationOnBoxes( trendBullishPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( trendBullishPivots, maxAllowedTrendLifetime, barIndex // ); } } // // Bearish ... has = HasTrendBearishPivots(); if (has) { // ApplyValidationOnBoxes( trendBearishPivots, unavailables, barIndex // ); // if (applyLifetimeValidating) { // ApplyLifeTimeValidationOnBoxes( trendBearishPivots, maxAllowedTrendLifetime, barIndex // ); } } } // // Bullish ... // XCAPivot trendBullishPivot; XBoxZone trendBullishPivots[]; bool detectTrendBullishPivots; bool newTrendBullishPivotDetected; // bool HasTrendBullishPivots() { return HasChild(trendBullishPivots); } // int CountTrendBullishPivots() { return ArraySize(trendBullishPivots); } // // Bearish ... // XCAPivot trendBearishPivot; XBoxZone trendBearishPivots[]; bool detectTrendBearishPivots; bool newTrendBearishPivotDetected; // bool HasTrendBearishPivots() { return HasChild(trendBearishPivots); } // int CountTrendBearishPivots() { return ArraySize(trendBearishPivots); } // // TRIGGER Blocks ... // int triggerBlockSwingLength; int filterTriggerBlocksBySar; double triggerBlockMaxAllowedRange; bool triggerBlockBarHasProperSwing; bool triggerBlockBarPressureValidation; // bool DetectTriggerBlockPivot( int barIndex, ENUM_X_DIRECTION forDir, XOHCL &zBar, XOHCL &cBar, XOHCL &pBar, XOHCL &p2Bar, XCAEAConditions &conditions // ) { // bool result = false; // // Checking Direction ... result = HasDirection(forDir); if (!result) { return result; } // bool forBullish = IsBullish(forDir); bool forBearish = IsBearish(forDir); // // Check Allowed ... result = forBullish ? detectTriggerBlockBullishPivots : detectTriggerBlockBearishPivots; if (!result) { return result; } // // Validate Args ... result = // barIndex >= 0 && zBar.IsValid() && cBar.IsValid() && pBar.IsValid() && p2Bar.IsValid() // ; if (!result) { return result; } // // Define Requirements ... // int zIDX = 0; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; int p3IDX = p2IDX + 1; // datetime cTime = zBar.time; string symbol = zBar.symbol; ENUM_TIMEFRAMES period = zBar.period; double points = GetPoints(symbol); // // Reading Conditional Values ... // // Prepare Conditinal Conditions ... // // Checking Base Block Exists ... XBoxZone iBlock; result = helper.barAnalyser.IsOB( cBar, iBlock, true, // Force FVG Bar Type ... true // Force Two Bar ... ); if (!result) { // iBlock.Clean(); // return result; } // // Bullish ... bool isBullish = result && forBullish && iBlock.IsBullish(); // // Bearish ... bool isBearish = result && forBearish && iBlock.IsBearish(); // // Summarizing Conditions ... // result = isBullish || isBearish; if (!result) { // iBlock.Clean(); // return result; } // // Adding Pivot to Box Type ... string iType = isBullish ? GetBoxType(XCA_TRIGGER_BULL) : GetBoxType(XCA_TRIGGER_BEAR); iBlock.type = iType; // // Validate TriggerBlock ... XOHCL p3Bar; XOHCL p4Bar; result = p2Bar.GetPreviousBar(p3Bar); result = result && p3Bar.GetPreviousBar(p4Bar); if (!result) { // p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); // return result; } ENUM_X_DIRECTION iDir; // // Validating Range ... if (triggerBlockMaxAllowedRange > 0) { // double blockRange = iBlock.GetRange(); result = blockRange <= triggerBlockMaxAllowedRange * points; if (!result) { // p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); // return result; } } // // Validate Using Swing Bars ... if (triggerBlockBarHasProperSwing) { // // Check Has Proper Swing ... // // CBar ... bool isCBarSimpleSwing = barAnalyser.IsSimpleSwing( cBar, iDir // ); bool isCBarBullishSimpleSwing = isCBarSimpleSwing && IsBullish(iDir); bool isCBarBearishSimpleSwing = isCBarSimpleSwing && IsBearish(iDir); // // PBar ... bool isPBarSimpleSwing = barAnalyser.IsSimpleSwing( pBar, iDir // ); bool isPBarBullishSimpleSwing = isPBarSimpleSwing && IsBullish(iDir); bool isPBarBearishSimpleSwing = isPBarSimpleSwing && IsBearish(iDir); // // P2Bar ... bool isP2BarSimpleSwing = barAnalyser.IsSimpleSwing( p2Bar, iDir // ); bool isP2BarBullishSimpleSwing = isP2BarSimpleSwing && IsBullish(iDir); bool isP2BarBearishSimpleSwing = isP2BarSimpleSwing && IsBearish(iDir); // // P3Bar ... bool isP3BarSimpleSwing = barAnalyser.IsSimpleSwing( p3Bar, iDir // ); bool isP3BarBullishSimpleSwing = isP3BarSimpleSwing && IsBullish(iDir); bool isP3BarBearishSimpleSwing = isP3BarSimpleSwing && IsBearish(iDir); // // P4Bar ... bool isP4BarSimpleSwing = barAnalyser.IsSimpleSwing( p4Bar, iDir // ); bool isP4BarBullishSimpleSwing = isP4BarSimpleSwing && IsBullish(iDir); bool isP4BarBearishSimpleSwing = isP4BarSimpleSwing && IsBearish(iDir); // // Summarise Validation ... // bool isBullishSwimpleSwing = isBullish && (isCBarBullishSimpleSwing || isPBarBullishSimpleSwing || isP2BarBullishSimpleSwing || isP3BarBullishSimpleSwing || isP4BarBullishSimpleSwing); // bool isBearishSwimpleSwing = isBearish && (isCBarBearishSimpleSwing || isPBarBearishSimpleSwing || isP2BarBearishSimpleSwing || isP3BarBearishSimpleSwing || isP4BarBearishSimpleSwing); // result = isBullishSwimpleSwing || isBearishSwimpleSwing; if (!result) { // p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); // return result; } } // // Validating Using Bar Pressure ... if (triggerBlockBarPressureValidation) { // // Check pBar is Momentum Bar ... // and Breakd Block Side ... // bool isCBarMomentum = barAnalyser.IsMomentum( pBar, iDir // ); bool isCBarBullishMomentum = isCBarMomentum && IsBullish(iDir); bool isCBarBearishMomentum = isCBarMomentum && IsBearish(iDir); // bool isPBarMomentum = barAnalyser.IsMomentum( pBar, iDir // ); bool isPBarBullishMomentum = isPBarMomentum && IsBullish(iDir); bool isPBarBearishMomentum = isPBarMomentum && IsBearish(iDir); // bool isBullishBreakedOut = isBullish && forBullish && pBar.IsBullish() && (isCBarBullishMomentum || isPBarBullishMomentum) && pBar.GetUp() > iBlock.upper && pBar.GetDown() < iBlock.upper; // bool isBearishBreakedOut = isBearish && forBearish && pBar.IsBearish() && (isCBarBearishMomentum || isPBarBearishMomentum) && pBar.GetUp() > iBlock.lower && pBar.GetDown() < iBlock.lower; // result = isBullishBreakedOut || isBearishBreakedOut; if (!result) { // p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); // return result; } } // // Extract to and from Info ... // int toIDX = iBlock.ToIndex(); int fromIDX = iBlock.FromIndex(); // XOHCL toBar; XOHCL fromBar; // result = iBlock.ToBar(toBar); result = result && iBlock.FromBar(fromBar); if (!result) { // toBar.Clean(); p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); fromBar.Clean(); // return result; } // // Validating Using HH and LL ... if (triggerBlockSwingLength > 0) { // double toLL = toBar.FindLowest(triggerBlockSwingLength, MODE_LOW); double toHH = toBar.FindHighest(triggerBlockSwingLength, MODE_HIGH); // double fromLL = fromBar.FindLowest(triggerBlockSwingLength, MODE_LOW); double fromHH = fromBar.FindHighest(triggerBlockSwingLength, MODE_HIGH); // double selectedLL = fromLL; // MathMin(toLL, fromLL); double selectedHH = fromHH; // MathMax(toHH, fromHH); // bool isBullishSwingPassed = isBullish && forBullish && selectedLL >= iBlock.lower; // bool isBearishSwingPassed = isBearish && forBearish && selectedHH <= iBlock.upper; // result = isBullishSwingPassed || isBearishSwingPassed; if (!result) { // toBar.Clean(); p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); fromBar.Clean(); // return result; } } // // Apply Filters ... bool hasFilter = filterTriggerBlocksBySar; if (hasFilter) { // // Sar Filtering ... if (filterTriggerBlocksBySar) { // // Reading Conditions ... // double zSar = conditions.sarBuffer[zIDX]; double cSar = conditions.sarBuffer[cIDX]; double pSar = conditions.sarBuffer[pIDX]; double p2Sar = conditions.sarBuffer[p2IDX]; double p3Sar = conditions.sarBuffer[p3IDX]; // // Preparing Constom Conditions ... // bool isZSarBullish = zSar < zBar.low; bool isCSarBullish = cSar < cBar.low; bool isPSarBullish = pSar < pBar.low; bool isP2SarBullish = p2Sar < p2Bar.low; bool isP3SarBullish = p3Sar < p3Bar.low; // bool isZSarBearish = zSar > zBar.high; bool isCSarBearish = cSar > cBar.high; bool isPSarBearish = pSar > pBar.high; bool isP2SarBearish = p2Sar > p2Bar.high; bool isP3SarBearish = p3Sar > p3Bar.high; // bool isCSarSwitchedToBullish = isCSarBullish && !isPSarBullish; bool isPSarSwitchedToBullish = isPSarBullish && !isP2SarBullish; bool isP2SarSwitchedToBullish = isP2SarBullish && !isP3SarBullish; // bool isCSarSwitchedToBearish = isCSarBearish && !isPSarBearish; bool isPSarSwitchedToBearish = isPSarBearish && !isP2SarBearish; bool isP2SarSwitchedToBearish = isP2SarBearish && !isP3SarBearish; // // Summarize Custom Conditions ... // // Bullish ... // bool isCSarBullishPassed = isZSarBullish && isCSarSwitchedToBullish; // bool isPSarBullishPassed = isZSarBullish && isCSarBullish && isPSarSwitchedToBullish; // bool isP2SarBullishPassed = isZSarBullish && isCSarBullish && isPSarBullish && isP2SarSwitchedToBullish; // // Bearish ... // bool isCSarBearishPassed = isZSarBearish && isCSarSwitchedToBearish; // bool isPSarBearishPassed = isZSarBearish && isCSarBearish && isPSarSwitchedToBearish; // bool isP2SarBearishPassed = isZSarBearish && isCSarBearish && isPSarBearish && isP2SarSwitchedToBearish; // // Summarize Conditions ... // bool isBullishFiltered = isBullish && forBullish && (isCSarBullishPassed || isPSarBullishPassed || isP2SarBullishPassed); // bool isBearishFiltered = isBearish && forBearish && (isCSarBearishPassed || isPSarBearishPassed || isP2SarBearishPassed); // result = isBullishFiltered || isBearishFiltered; if (!result) { // toBar.Clean(); p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); fromBar.Clean(); // return result; } } } // // Summarize ... // isBullish = isBullish && forBullish && iBlock.IsValid(); // isBearish = isBearish && forBearish && iBlock.IsValid(); // result = isBullish || isBearish; if (!result) { iBlock.Clean(); } // // Storing Pivot ... // if (isBullish) { // result = AddBox( iBlock, triggerBlockBullishPivots // ); } // if (isBearish) { // result = AddBox( iBlock, triggerBlockBearishPivots // ); } // // Cleanup Resource ... // toBar.Clean(); p3Bar.Clean(); p4Bar.Clean(); iBlock.Clean(); fromBar.Clean(); // return result; } // void ValidateTriggerBlockPivots( XBoxZone &unavailables[], int barIndex = 0 // ) { // // Since Trigger Blocks Doesnt Use Multiple Times, // there is not any Validation Required for them ... bool has = false; // // bool applyLifetimeValidating = maxAllowedTriggerBlockLifetime > 0; // // Bullish ... has = HasTriggerBlockBullishPivots(); if (has) { } // // Bearish ... has = HasTriggerBlockBearishPivots(); if (has) { } } // // Bullish ... // XBoxZone triggerBlockBullishPivots[]; bool detectTriggerBlockBullishPivots; bool newTriggerBlockBullishPivotDetected; // bool HasTriggerBlockBullishPivots() { return HasChild(triggerBlockBullishPivots); } // int CountTriggerBlockBullishPivots() { return ArraySize(triggerBlockBullishPivots); } // // Bearish ... // bool detectTriggerBlockBearishPivots; XBoxZone triggerBlockBearishPivots[]; bool newTriggerBlockBearishPivotDetected; // bool HasTriggerBlockBearishPivots() { return HasChild(triggerBlockBearishPivots); } // int CountTriggerBlockBearishPivots() { return ArraySize(triggerBlockBearishPivots); } // // Protected ... protected: // // Props ... // // Prrivate ... private: // // Props ... // XCPOIDrawer *drawer; XCXCAEAHelper *helper; XCBarAnalyser *barAnalyser; // bool AddBox( XBoxZone &box, XBoxZone &boxes[] // ) { // bool result = false; // result = box.IsValid(); if (!result) { return result; } // int idx = -1; bool isExists = FindBoxIndex( idx, box, boxes // ); result = !isExists; if (!result) { return result; } // int before = ArraySize(boxes); // AddRef( box, boxes // ); // int after = ArraySize(boxes); // result = after > before; // return result; } // bool ValidateBox( XBoxZone &box, XBoxZone &unavailables[], int barIndex = 0 // ) { // bool result = false; // // Normalize Bar Index ... barIndex = NormalizeInt(barIndex, 0); // // Ceck Input Box is Valid ... result = box.IsValid(); if (!result) { return result; } // // Check Input Box is Available ... bool canCheckUnAvailableBoxes = HasChild(unavailables); if (canCheckUnAvailableBoxes) { // int idx = -1; bool isUnAvailable = FindBoxIndex( idx, box, unavailables // ); result = !isUnAvailable; if (!result) { return result; } } // // Check Input Box is Breaked or not ... // // Check Bar Index must after Box To Index ... int toIDX = box.ToIndex(); int fromIDX = box.FromIndex(); result = toIDX > barIndex && fromIDX > barIndex && fromIDX > toIDX; if (!result) { return result; } // // Detect Box Applied Boundary Price ... // For Checking Break of Box ... bool isBullish = box.IsBullish(); double boundary = isBullish ? box.lower : box.upper; // // for validating Box Break we have to wait At Least 3 Bars Close // out of Box Boundary ... int barsLength = 3; // // Calculate Start Checking Bar Index ... int startCheckBreaktionBarIndex = toIDX - barsLength; bool isBarIndexValid = startCheckBreaktionBarIndex > 0 && barIndex < startCheckBreaktionBarIndex; result = isBarIndexValid; if (!result) { // // Assume Box is Valid if Bar Index not Valid for Checking ... result = true; return result; } // // Try to Check Box Validation if Everything is OK ... XOHCL cBar; XOHCL pBar; XOHCL p2Bar; bool isValid = false; bool isBreaked = false; for (int i = barIndex; i < startCheckBreaktionBarIndex; i++) { // // Initialize Bars ... isValid = cBar.Init( box.symbol, box.period, i + 1 // ); isValid = result && cBar.GetPreviousBar(pBar); isValid = result && pBar.GetPreviousBar(p2Bar); if (!isValid) { // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); // result = false; // break; } // // Preparing Conditions ... // bool isBullishBreaked = isBullish && cBar.close < boundary && pBar.close < boundary && p2Bar.close < boundary; // bool isBearishBreaked = !isBullish && cBar.close > boundary && pBar.close > boundary && p2Bar.close > boundary; // // Calculate Result ... isBreaked = isBullishBreaked || isBearishBreaked; if (isBreaked) { // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); // result = false; // break; } // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); } // result = isValid && !isBreaked; if (!result) { // int idx = -1; bool isExists = FindBoxIndex( idx, box, invalidPivots // ); if (!isExists) { // AddRef( box, invalidPivots // ); } } // // Cleanup Resource ... // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); // return result; } // void CleanPivots() { // Clean(invalidPivots); // swlPivot.Clean(); swhPivot.Clean(); peakPivot.Clean(); valePivot.Clean(); trendBullishPivot.Clean(); trendBearishPivot.Clean(); // Clean(swlPivots); Clean(swhPivots); // Clean(peakPivots); Clean(valePivots); // Clean(obBullishPivots); Clean(obBearishPivots); // Clean(fvgBullishPivots); Clean(fvgBearishPivots); // Clean(trendBullishPivots); Clean(trendBearishPivots); // Clean(triggerBlockBullishPivots); Clean(triggerBlockBearishPivots); } // void SortPivots() { // bool has = false; // // Invalid Pivots ... has = HasInvalidPivots(); if (has) { ApplySortOnBoxes(invalidPivots); } // // SWING ... // // SWH ... has = HasSWHPivots(); if (has) { ApplySortOnBoxes(swhPivots); } // // SWL ... has = HasSWLPivots(); if (has) { ApplySortOnBoxes(swlPivots); } // // PV ... // // PEAK ... has = HasPeakPivots(); if (has) { ApplySortOnBoxes(peakPivots); } // // VALE ... has = HasValePivots(); if (has) { ApplySortOnBoxes(valePivots); } // // OB ... // // Bullish ... has = HasOBBullishPivots(); if (has) { ApplySortOnBoxes(obBullishPivots); } // // Bearish ... has = HasOBBearishPivots(); if (has) { ApplySortOnBoxes(obBearishPivots); } // // FVG ... // // Bullish ... has = HasFVGBullishPivots(); if (has) { ApplySortOnBoxes(fvgBullishPivots); } // // Bearish ... has = HasFVGBearishPivots(); if (has) { ApplySortOnBoxes(fvgBearishPivots); } // // TREND ... // // Bullish ... has = HasTrendBullishPivots(); if (has) { ApplySortOnBoxes(trendBullishPivots); } // // Bearish ... has = HasTrendBearishPivots(); if (has) { ApplySortOnBoxes(trendBearishPivots); } // // TRIGGER Block ... // // Bullish ... has = HasTriggerBlockBullishPivots(); if (has) { ApplySortOnBoxes(triggerBlockBullishPivots); } // // Bearish ... has = HasTriggerBlockBearishPivots(); if (has) { ApplySortOnBoxes(triggerBlockBearishPivots); } } // void ApplySortOnBoxes( XBoxZone &items[] // ) { // int idx = -1; bool has = false; // has = HasChild(items); if (!has) { return; } // XBoxZone tmp[]; Copy( items, tmp // ); Clean(items); // while (HasChild(tmp)) { // idx = GetOldest(tmp); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox = tmp[idx]; ArrayRemove( tmp, idx, 1 // ); // AddRef( iBox, items // ); } // CleanupArray( items, maxAllowedPivots // ); // Clean(tmp); } // void ApplyValidationOnBoxes( XBoxZone &items[], XBoxZone &unavailables[], int barIndex = 0 // ) { // bool has = false; // has = HasChild(items); if (!has) { return; } // XBoxZone tmp[]; Copy( items, tmp // ); Clean(items); while (HasChild(tmp)) { // XBoxZone iBox = tmp[0]; ArrayRemove( tmp, 0, 1 // ); // has = ValidateBox( iBox, unavailables, barIndex // ); if (has) { // AddRef( iBox, items // ); } // iBox.Clean(); // } // Clean(tmp); } // void ApplyLifeTimeValidationOnBoxes( XBoxZone &items[], int maxAllowedAge = 0, int barIndex = 0 // ) { // bool has = false; // barIndex = NormalizeInt(barIndex, 0); // has = maxAllowedAge > 0 && HasChild(items); if (!has) { return; } // datetime cTime = GetBarTime( helper.GetSymbol(), helper.GetPeriod(), barIndex // ); // XBoxZone tmp[]; Copy( items, tmp // ); Clean(items); // while (HasChild(tmp)) { // XBoxZone iBox = tmp[0]; ArrayRemove( tmp, 0, 1 // ); // datetime defTo = iBox.to; iBox.to = cTime; // int iAge = iBox.GetAge(); has = iAge <= maxAllowedAge; iBox.to = defTo; if (has) { // AddRef( iBox, items // ); } else { // int idx = -1; bool isExists = FindBoxIndex( idx, iBox, invalidPivots // ); if (!isExists) { // AddRef( iBox, invalidPivots // ); } } // iBox.Clean(); } // Clean(tmp); } // }; //