From 04d11702feeaab8af76019331d7cb00db102c3dd Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 29 May 2025 01:13:31 +0330 Subject: [PATCH] apply new mechanism for validating anf filtering ... --- Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 | 259 ++++++++ Experts/xcatb.test.ea.mq5 | 222 ++++--- Helpers/x-saherelm.x121.xcatb.helper.mq5 | 125 ---- Indicators/x-saherelm.x121.xcatb.mq5 | 85 --- XCATBEA/Libraries/xcatbea.signaller.lib.mq5 | 682 ++++++++++++++++++-- 5 files changed, 1019 insertions(+), 354 deletions(-) diff --git a/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 b/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 index 9f1645d6..07d149d7 100644 --- a/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 +++ b/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 @@ -953,3 +953,262 @@ bool DetectTriggerBlock( // return result; } + +// +// Signal ... +// int signalR2R; // Risk Reward Ratio +// bool drawSignals; // Draw Signal +// bool drawTriggerBlock; // Draw Trigger Block +// double slAtrMultiplier; // ATR Multiplier for SL + +// +// Validating ... +bool forceHasSwing; // Force Blocks to Have Swing +bool forceOBBarType; // Force Block Has Reversal Bar +bool forceOBFVGBarType; // Force FVG Has Same Bars +bool forceHasFLiquidity; // Force Blocks to Have Following Liquidity +bool forceHasRLiquidity; // Force Blocks to Have Reversal Liquidity +bool validateGapSequence; // Validate Block's Gap Sequence +bool validateBlockEdgeBreakout; // Validate Block's Edge Breakout + +// +// Filtering ... +bool filterBasedOnPV; // Filter Based on Peak and Vale +bool filterBasedOnSar; // Filter Based on Sar +bool filterBasedOnRSI; // Filter Based on RSI +bool filterBasedOnADX; // Filter Based on ADX +bool filterBasedOnATR; // Filter Based on ATR +bool filterBasedOnTrend; // Filter Based on Trend +bool filterBasedOnDelta; // Filter Based on Delta +bool filterBasedOnVolume; // Filter Based on Volume +bool filterBasedOnSignalBar; // Filter Based on Signal Bar +bool filterBasedOnHKSignalBar; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +string alertPrefix; // Alert Prefix +bool logAlerts; // Log Alerts +bool pushAlerts; // Push Alerts +bool mailAlerts; // Mail Alerts +bool terminalAlerts; // Terminal Alerts + + // + // Initialize and Configure Alert ... + mAlert = new XCAlert(); + mEnableAlerts = + _logAlerts || + _pushAlerts || + _mailAlerts || + _terminalAlerts; + string mPrefix = ShortName + + (!IsValid(mAlertPrefix) + ? "" + : "[" + mAlertPrefix + "]"); + mAlert.SetPrefix(mPrefix); + mAlert.SetLogAlerts(_logAlerts); + mAlert.SetMailAlerts(_mailAlerts); + mAlert.SetPushAlerts(_pushAlerts); + mAlert.SetEnableAlerts(mEnableAlerts); + mAlert.SetTerminalAlerts(_terminalAlerts); + +// +// Validating ... +forceHasSwing = false; // Force Blocks to Have Swing +forceOBBarType = false; // Force Block Has Reversal Bar +forceOBFVGBarType = false; // Force FVG Has Same Bars +forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +validateGapSequence = false; // Validate Block's Gap Sequence +validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +filterBasedOnPV = false; // Filter Based on Peak and Vale +filterBasedOnSar = false; // Filter Based on Sar +filterBasedOnRSI = false; // Filter Based on RSI +filterBasedOnADX = false; // Filter Based on ADX +filterBasedOnATR = false; // Filter Based on ATR +filterBasedOnTrend = false; // Filter Based on Trend +filterBasedOnDelta = false; // Filter Based on Delta +filterBasedOnVolume = false; // Filter Based on Volume +filterBasedOnSignalBar = false; // Filter Based on Signal Bar +filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +alertPrefix = ""; // Alert Prefix +logAlerts = false; // Log Alerts +pushAlerts = false; // Push Alerts +mailAlerts = false; // Mail Alerts +terminalAlerts = false; // Terminal Alerts + +// +// Validating ... +forceHasSwing = false; // Force Blocks to Have Swing +forceOBBarType = false; // Force Block Has Reversal Bar +forceOBFVGBarType = false; // Force FVG Has Same Bars +forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +validateGapSequence = false; // Validate Block's Gap Sequence +validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +filterBasedOnPV = false; // Filter Based on Peak and Vale +filterBasedOnSar = false; // Filter Based on Sar +filterBasedOnRSI = false; // Filter Based on RSI +filterBasedOnADX = false; // Filter Based on ADX +filterBasedOnATR = false; // Filter Based on ATR +filterBasedOnTrend = false; // Filter Based on Trend +filterBasedOnDelta = false; // Filter Based on Delta +filterBasedOnVolume = false; // Filter Based on Volume +filterBasedOnSignalBar = false; // Filter Based on Signal Bar +filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +alertPrefix = ""; // Alert Prefix +logAlerts = false; // Log Alerts +pushAlerts = false; // Push Alerts +mailAlerts = false; // Mail Alerts +terminalAlerts = false; // Terminal Alerts + +"", // Validating ... + mInputs.forceHasSwing, + mInputs.forceOBBarType, + mInputs.forceOBFVGBarType, + mInputs.forceHasFLiquidity, + mInputs.forceHasRLiquidity, + mInputs.validateGapSequence, + mInputs.validateBlockEdgeBreakout, + "", // Filtering ... + mInputs.filterBasedOnPV, + mInputs.filterBasedOnSar, + mInputs.filterBasedOnRSI, + mInputs.filterBasedOnADX, + mInputs.filterBasedOnATR, + mInputs.filterBasedOnTrend, + mInputs.filterBasedOnDelta, + mInputs.filterBasedOnVolume, + mInputs.filterBasedOnSignalBar, + mInputs.filterBasedOnHKSignalBar, + "", // Alerts ... + mInputs.alertPrefix, + mInputs.logAlerts, + mInputs.pushAlerts, + mInputs.mailAlerts, + mInputs.terminalAlerts, + + // + // Validating ... + input group "Validating"; +input bool forceHasSwing = false; // Force Blocks to Have Swing +input bool forceObBarType = false; // Force Block Has Reversal Bar +input bool forceOBFVGBarType = false; // Force FVG Has Same Bars +input bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +input bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +input bool validateGapSequence = false; // Validate Block's Gap Sequence +input bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +input group "Filtering"; +input bool filterBasedOnPV = false; // Filter Based on Peak and Vale +input bool filterBasedOnSar = false; // Filter Based on Sar +input bool filterBasedOnRSI = false; // Filter Based on RSI +input bool filterBasedOnADX = false; // Filter Based on ADX +input bool filterBasedOnATR = false; // Filter Based on ATR +input bool filterBasedOnTrend = false; // Filter Based on Trend +input bool filterBasedOnDelta = false; // Filter Based on Delta +input bool filterBasedOnVolume = false; // Filter Based on Volume +input bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar +input bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +input group "Alerts"; +input string mAlertPrefix = ""; // Alert Prefix +input bool _logAlerts = false; // Log Alerts +input bool _pushAlerts = false; // Push Alerts +input bool _mailAlerts = false; // Mail Alerts +input bool _terminalAlerts = false; // Terminal Alerts + + + // + // Set Validators ... + eaInputs.forceHasSwing = eaForceHasSwing; + eaInputs.forceOBBarType = eaForceOBBarType; + eaInputs.forceOBFVGBarType = eaForceOBFVGBarType; + eaInputs.forceHasFLiquidity = eaForceHasFLiquidity; + eaInputs.forceHasRLiquidity = eaForceHasRLiquidity; + eaInputs.validateGapSequence = eaValidateGapSequence; + eaInputs.validateBlockEdgeBreakout = eaValidateBlockEdgeBreakout; + + // + // Set Filters ... + eaInputs.filterBasedOnPV = eaFilterBasedOnPV; + eaInputs.filterBasedOnSar = eaFilterBasedOnSar; + eaInputs.filterBasedOnRSI = eaFilterBasedOnRSI; + eaInputs.filterBasedOnADX = eaFilterBasedOnADX; + eaInputs.filterBasedOnATR = eaFilterBasedOnATR; + eaInputs.filterBasedOnTrend = eaFilterBasedOnTrend; + eaInputs.filterBasedOnDelta = eaFilterBasedOnDelta; + eaInputs.filterBasedOnVolume = eaFilterBasedOnVolume; + eaInputs.filterBasedOnSignalBar = eaFilterBasedOnSignalBar; + eaInputs.filterBasedOnHKSignalBar = eaFilterBasedOnHKSignalBar; + + // + // Alerts ... + eaInputs.alertPrefix = eaTag; + eaInputs.logAlerts = false; // eaLogAlerts; + eaInputs.pushAlerts = false; // eaMailAlerts; + eaInputs.mailAlerts = false; // eaPushAlerts; + eaInputs.terminalAlerts = false; // eaTerminalAlerts; + + + + // + // TODO: Remove this ... + // Temparory Testing Configs ... + // validations.maxAllowedRange = 200; + // validations.forceHasSwing = true; + // validations.forceFVGBarType = true; + // validations.forceOBBarType = true; + // validations.validateGapSequence = true; + // validations.validateBlockEdgeBreakout = true; + // validations.liquidityLoopback = 144; + // validations.forceHasFLiquidity = true; + // validations.forceHasRLiquidity = true; + // validations.minAllowedBlockLength = 7; + + // + // TODO: Remove this ... + // filters.bosLoopback = 0; + // filters.filterBasedOnPV = true; + // filters.filterBasedOnSar = true; + // filters.forceSarSwitched = false; + // filters.forceSarOnBothSide = true; + // filters.forceSarHasBreakout = true; + // filters.forceSarHasReversalSide = false; + // filters.filterBasedOnRSI = false; + // filters.forceHasRSITrending = false; + // filters.forceHasRSIVPattern = false; + // filters.forceHasRSICrossing = false; + // filters.filterBasedOnADX = true; + // filters.forceHasADXTrending = false; + // filters.forceHasADXCrossing = true; + // filters.filterBasedOnATR = true; + // filters.forceHasATRTrending = true; + // filters.forceHasATRBreakout = true; + // filters.filterBasedOnTrend = false; + // filters.forceHasTrendDir = false; + // filters.forceHasTrendPlace = false; + // filters.forceHasTrendChange = false; + // filters.forceHasTrendTrending = false; + // filters.forceHasTrendRejection = false; + // filters.forceHasTrendLineInside = false; + // filters.forceHasTrendDirOnBothSide = false; + // filters.filterBasedOnDelta = false; + // filters.filterBasedOnVolume = false; + // filters.filterBasedOnSignalBar = true; + // filters.filterBasedOnHKSignalBar = true; diff --git a/Experts/xcatb.test.ea.mq5 b/Experts/xcatb.test.ea.mq5 index 2620d9f1..4339af74 100644 --- a/Experts/xcatb.test.ea.mq5 +++ b/Experts/xcatb.test.ea.mq5 @@ -38,9 +38,9 @@ // // Common ... input group "Common"; -input long eaMagicNumber = 78692110; // Magic Number -input int eaSlippage = 10; // Slippgae -input string eaLogSuffix = ""; // Log Suffix +input long eaMagicNumber = 1694056; // Magic Number +input int eaSlippage = 10; // Slippgae +input string eaLogSuffix = ""; // Log Suffix // // Detector ... @@ -49,27 +49,51 @@ input group "Detector"; // // Validating ... input group "Validations"; -input bool eaForceHasSwing = false; // Force Blocks to Have Swing -input bool eaForceOBBarType = false; // Force Block Has Reversal Bar -input bool eaForceOBFVGBarType = false; // Force FVG Has Same Bars -input bool eaForceHasFLiquidity = false; // Force Blocks to Have Following Liquidity -input bool eaForceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity -input bool eaValidateGapSequence = false; // Validate Block's Gap Sequence -input bool eaValidateBlockEdgeBreakout = false; // Validate Block's Edge Breakout +input bool eaForceHasSwing = false; // Force Block to Has Propper Swing +input bool eaForceOBBarType = false; // Force Order Block to Has InDirectional Bars +input int eaMinRequiredOBBar = 0; // Min Required OB Bar +input bool eaForceFVGBarType = false; // Force Fair Value Gaps Bars Type +input int eaLiquidityLoopback = 0; // Liquidity Detection Loopback +input double eaMaxAllowedRange = 0.0; // Max Allowed Order Block Range +input double eaMinAllowedRange = 0.0; // Min Allowed Order Block Range +input bool eaForceHasFLiquidity = false; // Force Order Block To Has Reversal Liquidity +input bool eaForceHasRLiquidity = false; // Force Order Block to Has Following Liquidity +input bool eaValidateGapSequence = false; // Validate Fair Value Gaps Bar Sequences +input int eaMinAllowedBlockLength = 5; // Min Allowed Block Length +input bool eaValidateBlockEdgeBreakout = false; // Validate Order Block Edge Breakeout // // Filtering ... input group "Filters"; -input bool eaFilterBasedOnPV = false; // Filter Based on Peak and Vale -input bool eaFilterBasedOnSar = false; // Filter Based on Sar -input bool eaFilterBasedOnRSI = false; // Filter Based on RSI -input bool eaFilterBasedOnADX = false; // Filter Based on ADX -input bool eaFilterBasedOnATR = false; // Filter Based on ATR -input bool eaFilterBasedOnTrend = false; // Filter Based on Trend -input bool eaFilterBasedOnDelta = false; // Filter Based on Delta -input bool eaFilterBasedOnVolume = false; // Filter Based on Volume -input bool eaFilterBasedOnSignalBar = false; // Filter Based on Signal Bar -input bool eaFilterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar +input bool eaFilterBasedOnPV = false; // Filter Based On PV +input int eaBosLoopback = 0; // PV Based Filtering BOS Lookup +input bool eaFilterBasedOnSar = false; // Filter Based On SAR +input bool eaForceSarSwitched = false; // SAR Switched on Sides for Filtering +input bool eaForceSarOnBothSide = false; // SAR Check on Both Sides for Filtering +input bool eaForceSarHasBreakout = false; // SAR Must Has Reversal Direction in Trigger Block +input bool eaForceSarHasReversalSide = false; // SAR Must Has Reversal Direction in Trigger Block +input bool eaFilterBasedOnRSI = false; // Filter Based On RSI +input bool eaForceHasRSITrending = false; // RSI Must Has Trending +input bool eaForceHasRSIVPattern = false; // RSI Must Has Pattern +input bool eaForceHasRSICrossing = false; // RSI Must Has Crossing Levels +input bool eaFilterBasedOnADX = false; // Filter Based On ADX +input bool eaForceHasADXTrending = false; // ADX Must Has Trending +input bool eaForceHasADXCrossing = false; // ADX Must Has Crossing +DI/-DI +input bool eaFilterBasedOnATR = false; // Filter Based On ATR +input bool eaForceHasATRTrending = false; // ATR Must Has Trending +input bool eaForceHasATRBreakout = false; // ATR Must Has Breakout +input bool eaFilterBasedOnTrend = false; // Filter Based On Trend +input bool eaForceHasTrendDir = false; // TREND Must Has Following Direction +input bool eaForceHasTrendPlace = false; // TREND Place Based Filtering +input bool eaForceHasTrendChange = false; // TREND Change Filtering +input bool eaForceHasTrendTrending = false; // TREND Must Has Trending +input bool eaForceHasTrendRejection = false; // TREND Line Must Rejected +input bool eaForceHasTrendLineInside = false; // TREND Line has Inside +input bool eaForceHasTrendDirOnBothSide = false; // TREND Must Has Following Direction in Both Side +input bool eaFilterBasedOnDelta = false; // Filter Based On Delta +input bool eaFilterBasedOnVolume = false; // Filter Based On Volume +input bool eaFilterBasedOnSignalBar = false; // Filter Based on Signal Bar +input bool eaFilterBasedOnHKSignalBar = false; // Filter Based On HK Signal Bar // // Signal ... @@ -137,6 +161,7 @@ XCTrade *eaTrade; XSignal eaSignal; string eaTag = ""; XCVolume *eaVolume; +XTriggerBlock eaTB; CArrayObj *eaObjects; XCPOIDrawer *eaDrawer; XBarTracker eaBarTraker; @@ -144,8 +169,11 @@ X121XCatbInputs eaInputs; XTimeTracker eaTimeTracker; XCX121XCatbHelper *eaHelper; XCBarAnalyser *eaBarAnalyser; +XTriggerBlockFilters eaFilters; +X121XCatbConditions eaCatbConditions; XCXCATBEATradeManager *eaTradeManager; XCATBEAStrategyConditions eaConditions; +XTriggerBlockValidationRules eaValidations; // // Event Handlers ... @@ -221,10 +249,16 @@ void OnDeinit(const int reason) ZeroMemory(eaBarAnalyser); // + eaTB.Clean(); eaSignal.Clean(); + eaSignal.Clean(); + eaFilters.Clean(); eaBarTraker.Clean(); eaConditions.Clean(); + eaConditions.Clean(); eaTimeTracker.Clean(); + eaValidations.Clean(); + eaCatbConditions.Clean(); // DestroyTimer(); @@ -247,8 +281,10 @@ void OnTick() eaTradeManager.Manage(); // + eaTB.Clean(); eaSignal.Clean(); eaConditions.Clean(); + eaCatbConditions.Clean(); // bool has = false; @@ -298,45 +334,15 @@ void OnTick() // Check Trigger Block Detected or Not ... if (tradeUsingTriggerBlock) { - // - // Define Requirements ... - XTriggerBlock iTB; - XTriggerBlockFilters iFilters; - X121XCatbConditions iConditions; - XTriggerBlockValidationRules iValidations; - - // - // Fill Validations ... - iValidations.forceHasSwing = eaInputs.forceHasSwing; - iValidations.forceOBBarType = eaInputs.forceOBBarType; - iValidations.forceFVGBarType = eaInputs.forceOBFVGBarType; - iValidations.forceHasFLiquidity = eaInputs.forceHasFLiquidity; - iValidations.forceHasRLiquidity = eaInputs.forceHasRLiquidity; - iValidations.validateGapSequence = eaInputs.validateGapSequence; - iValidations.validateBlockEdgeBreakout = eaInputs.validateBlockEdgeBreakout; - - // - // Fill Filters ... - iFilters.filterBasedOnPV = eaInputs.filterBasedOnPV; - iFilters.filterBasedOnSar = eaInputs.filterBasedOnSar; - iFilters.filterBasedOnRSI = eaInputs.filterBasedOnRSI; - iFilters.filterBasedOnADX = eaInputs.filterBasedOnADX; - iFilters.filterBasedOnATR = eaInputs.filterBasedOnATR; - iFilters.filterBasedOnTrend = eaInputs.filterBasedOnTrend; - iFilters.filterBasedOnDelta = eaInputs.filterBasedOnDelta; - iFilters.filterBasedOnVolume = eaInputs.filterBasedOnVolume; - iFilters.filterBasedOnSignalBar = eaInputs.filterBasedOnSignalBar; - iFilters.filterBasedOnHKSignalBar = eaInputs.filterBasedOnHKSignalBar; - // // Trigger Block Detection ... has = DetectTriggerBlock1( eaHelper, eaBarAnalyser, - iTB, - iConditions, - iValidations, - iFilters, + eaTB, + eaCatbConditions, + eaValidations, + eaFilters, barIndex, 10 // Loopback ... ); @@ -373,8 +379,8 @@ void OnTick() // // Preparing Signal ... has = ToSignal( - iTB.trigger, - iTB.signal, + eaTB.trigger, + eaTB.signal, targets, slAdditional // ); @@ -382,7 +388,7 @@ void OnTick() // // Draw Trigger Block ... DrawTriggerBlock( - iTB, + eaTB, eaDrawer, eaObjects, NULL // @@ -390,7 +396,7 @@ void OnTick() // // Attach Signal ... - eaSignal = iTB.signal; + eaSignal = eaTB.signal; // // Here we Can Fill eaConditions ... @@ -428,7 +434,7 @@ void OnTick() } // - iTB.Clean(); + eaTB.Clean(); } // @@ -459,6 +465,10 @@ void OnTick() // zBar.Clean(); cBar.Clean(); + eaTB.Clean(); + eaSignal.Clean(); + eaConditions.Clean(); + eaCatbConditions.Clean(); } // @@ -729,40 +739,9 @@ void InitRequirements() eaInputs.showPV = true; eaInputs.showSar = true; eaInputs.showTrend = true; - eaInputs.showATRBand = false; + eaInputs.showATRBand = true; eaInputs.showPVGolden = true; - // - // Set Validators ... - eaInputs.forceHasSwing = eaForceHasSwing; - eaInputs.forceOBBarType = eaForceOBBarType; - eaInputs.forceOBFVGBarType = eaForceOBFVGBarType; - eaInputs.forceHasFLiquidity = eaForceHasFLiquidity; - eaInputs.forceHasRLiquidity = eaForceHasRLiquidity; - eaInputs.validateGapSequence = eaValidateGapSequence; - eaInputs.validateBlockEdgeBreakout = eaValidateBlockEdgeBreakout; - - // - // Set Filters ... - eaInputs.filterBasedOnPV = eaFilterBasedOnPV; - eaInputs.filterBasedOnSar = eaFilterBasedOnSar; - eaInputs.filterBasedOnRSI = eaFilterBasedOnRSI; - eaInputs.filterBasedOnADX = eaFilterBasedOnADX; - eaInputs.filterBasedOnATR = eaFilterBasedOnATR; - eaInputs.filterBasedOnTrend = eaFilterBasedOnTrend; - eaInputs.filterBasedOnDelta = eaFilterBasedOnDelta; - eaInputs.filterBasedOnVolume = eaFilterBasedOnVolume; - eaInputs.filterBasedOnSignalBar = eaFilterBasedOnSignalBar; - eaInputs.filterBasedOnHKSignalBar = eaFilterBasedOnHKSignalBar; - - // - // Alerts ... - eaInputs.alertPrefix = eaTag; - eaInputs.logAlerts = false; // eaLogAlerts; - eaInputs.pushAlerts = false; // eaMailAlerts; - eaInputs.mailAlerts = false; // eaPushAlerts; - eaInputs.terminalAlerts = false; // eaTerminalAlerts; - // eaHelper = new XCX121XCatbHelper(); bool isInited = eaHelper.Init( @@ -897,6 +876,67 @@ void InitRequirements() } } + // + // Fill Validations ... + eaValidations.forceHasSwing = eaForceHasSwing; + eaValidations.forceOBBarType = eaForceOBBarType; + eaValidations.minRequiredOBBar = eaMinRequiredOBBar; + eaValidations.forceFVGBarType = eaForceFVGBarType; + eaValidations.liquidityLoopback = eaLiquidityLoopback; + eaValidations.maxAllowedRange = eaMaxAllowedRange; + eaValidations.minAllowedRange = eaMinAllowedRange; + eaValidations.forceHasFLiquidity = eaForceHasFLiquidity; + eaValidations.forceHasRLiquidity = eaForceHasRLiquidity; + eaValidations.validateGapSequence = eaValidateGapSequence; + eaValidations.minAllowedBlockLength = eaMinAllowedBlockLength; + eaValidations.validateBlockEdgeBreakout = eaValidateBlockEdgeBreakout; + + // + // Fill Filters ... + + // + eaFilters.filterBasedOnPV = eaFilterBasedOnPV; + eaFilters.bosLoopback = eaBosLoopback; + + // + eaFilters.filterBasedOnSar = eaFilterBasedOnSar; + eaFilters.forceSarSwitched = eaForceSarSwitched; + eaFilters.forceSarOnBothSide = eaForceSarOnBothSide; + eaFilters.forceSarHasBreakout = eaForceSarHasBreakout; + eaFilters.forceSarHasReversalSide = eaForceSarHasReversalSide; + + // + eaFilters.filterBasedOnRSI = eaFilterBasedOnRSI; + eaFilters.forceHasRSITrending = eaForceHasRSITrending; + eaFilters.forceHasRSIVPattern = eaForceHasRSIVPattern; + eaFilters.forceHasRSICrossing = eaForceHasRSICrossing; + + // + eaFilters.filterBasedOnADX = eaFilterBasedOnADX; + eaFilters.forceHasADXTrending = eaForceHasADXTrending; + eaFilters.forceHasADXCrossing = eaForceHasADXCrossing; + + // + eaFilters.filterBasedOnATR = eaFilterBasedOnATR; + eaFilters.forceHasATRTrending = eaForceHasATRTrending; + eaFilters.forceHasATRBreakout = eaForceHasATRBreakout; + + // + eaFilters.filterBasedOnTrend = eaFilterBasedOnTrend; + eaFilters.forceHasTrendDir = eaForceHasTrendDir; + eaFilters.forceHasTrendPlace = eaForceHasTrendPlace; + eaFilters.forceHasTrendChange = eaForceHasTrendChange; + eaFilters.forceHasTrendTrending = eaForceHasTrendTrending; + eaFilters.forceHasTrendRejection = eaForceHasTrendRejection; + eaFilters.forceHasTrendLineInside = eaForceHasTrendLineInside; + eaFilters.forceHasTrendDirOnBothSide = eaForceHasTrendDirOnBothSide; + + // + eaFilters.filterBasedOnDelta = eaFilterBasedOnDelta; + eaFilters.filterBasedOnVolume = eaFilterBasedOnVolume; + eaFilters.filterBasedOnSignalBar = eaFilterBasedOnSignalBar; + eaFilters.filterBasedOnHKSignalBar = eaFilterBasedOnHKSignalBar; + // } diff --git a/Helpers/x-saherelm.x121.xcatb.helper.mq5 b/Helpers/x-saherelm.x121.xcatb.helper.mq5 index 7b186198..a0ba5a2a 100644 --- a/Helpers/x-saherelm.x121.xcatb.helper.mq5 +++ b/Helpers/x-saherelm.x121.xcatb.helper.mq5 @@ -96,44 +96,6 @@ struct X121XCatbInputs ENUM_TIMEFRAMES hcPeriod; // Hind Period ENUM_X_MARKET_CYCLES appliedCycle; // Applied Cycle - // - // Signal ... - // int signalR2R; // Risk Reward Ratio - // bool drawSignals; // Draw Signal - // bool drawTriggerBlock; // Draw Trigger Block - // double slAtrMultiplier; // ATR Multiplier for SL - - // - // Validating ... - bool forceHasSwing; // Force Blocks to Have Swing - bool forceOBBarType; // Force Block Has Reversal Bar - bool forceOBFVGBarType; // Force FVG Has Same Bars - bool forceHasFLiquidity; // Force Blocks to Have Following Liquidity - bool forceHasRLiquidity; // Force Blocks to Have Reversal Liquidity - bool validateGapSequence; // Validate Block's Gap Sequence - bool validateBlockEdgeBreakout; // Validate Block's Edge Breakout - - // - // Filtering ... - bool filterBasedOnPV; // Filter Based on Peak and Vale - bool filterBasedOnSar; // Filter Based on Sar - bool filterBasedOnRSI; // Filter Based on RSI - bool filterBasedOnADX; // Filter Based on ADX - bool filterBasedOnATR; // Filter Based on ATR - bool filterBasedOnTrend; // Filter Based on Trend - bool filterBasedOnDelta; // Filter Based on Delta - bool filterBasedOnVolume; // Filter Based on Volume - bool filterBasedOnSignalBar; // Filter Based on Signal Bar - bool filterBasedOnHKSignalBar; // Filter Based on Hiken Ashi Signal Bar - - // - // Alert ... - string alertPrefix; // Alert Prefix - bool logAlerts; // Log Alerts - bool pushAlerts; // Push Alerts - bool mailAlerts; // Mail Alerts - bool terminalAlerts; // Terminal Alerts - // // Presentation ... bool showBars; // Show Bars @@ -179,37 +141,6 @@ struct X121XCatbInputs hcPeriod = NULL; // Hind Period appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle - // - // Validating ... - forceHasSwing = false; // Force Blocks to Have Swing - forceOBBarType = false; // Force Block Has Reversal Bar - forceOBFVGBarType = false; // Force FVG Has Same Bars - forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity - forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity - validateGapSequence = false; // Validate Block's Gap Sequence - validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout - - // - // Filtering ... - filterBasedOnPV = false; // Filter Based on Peak and Vale - filterBasedOnSar = false; // Filter Based on Sar - filterBasedOnRSI = false; // Filter Based on RSI - filterBasedOnADX = false; // Filter Based on ADX - filterBasedOnATR = false; // Filter Based on ATR - filterBasedOnTrend = false; // Filter Based on Trend - filterBasedOnDelta = false; // Filter Based on Delta - filterBasedOnVolume = false; // Filter Based on Volume - filterBasedOnSignalBar = false; // Filter Based on Signal Bar - filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar - - // - // Alert ... - alertPrefix = ""; // Alert Prefix - logAlerts = false; // Log Alerts - pushAlerts = false; // Push Alerts - mailAlerts = false; // Mail Alerts - terminalAlerts = false; // Terminal Alerts - // // Presentation ... showBars = false; // Show Bars @@ -249,37 +180,6 @@ struct X121XCatbInputs hcPeriod = NULL; // Hind Period appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle - // - // Validating ... - forceHasSwing = false; // Force Blocks to Have Swing - forceOBBarType = false; // Force Block Has Reversal Bar - forceOBFVGBarType = false; // Force FVG Has Same Bars - forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity - forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity - validateGapSequence = false; // Validate Block's Gap Sequence - validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout - - // - // Filtering ... - filterBasedOnPV = false; // Filter Based on Peak and Vale - filterBasedOnSar = false; // Filter Based on Sar - filterBasedOnRSI = false; // Filter Based on RSI - filterBasedOnADX = false; // Filter Based on ADX - filterBasedOnATR = false; // Filter Based on ATR - filterBasedOnTrend = false; // Filter Based on Trend - filterBasedOnDelta = false; // Filter Based on Delta - filterBasedOnVolume = false; // Filter Based on Volume - filterBasedOnSignalBar = false; // Filter Based on Signal Bar - filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar - - // - // Alert ... - alertPrefix = ""; // Alert Prefix - logAlerts = false; // Log Alerts - pushAlerts = false; // Push Alerts - mailAlerts = false; // Mail Alerts - terminalAlerts = false; // Terminal Alerts - // // Presentation ... showBars = true; // Show Bars @@ -1568,31 +1468,6 @@ class XCX121XCatbHelper : public XCBaseHelper mInputs.hcMethod, mInputs.hcPeriod, mInputs.appliedCycle, - "", // Validating ... - mInputs.forceHasSwing, - mInputs.forceOBBarType, - mInputs.forceOBFVGBarType, - mInputs.forceHasFLiquidity, - mInputs.forceHasRLiquidity, - mInputs.validateGapSequence, - mInputs.validateBlockEdgeBreakout, - "", // Filtering ... - mInputs.filterBasedOnPV, - mInputs.filterBasedOnSar, - mInputs.filterBasedOnRSI, - mInputs.filterBasedOnADX, - mInputs.filterBasedOnATR, - mInputs.filterBasedOnTrend, - mInputs.filterBasedOnDelta, - mInputs.filterBasedOnVolume, - mInputs.filterBasedOnSignalBar, - mInputs.filterBasedOnHKSignalBar, - "", // Alerts ... - mInputs.alertPrefix, - mInputs.logAlerts, - mInputs.pushAlerts, - mInputs.mailAlerts, - mInputs.terminalAlerts, "", // Presentation ... mInputs.showBars, mInputs.showPV, diff --git a/Indicators/x-saherelm.x121.xcatb.mq5 b/Indicators/x-saherelm.x121.xcatb.mq5 index b47d658a..39459a71 100644 --- a/Indicators/x-saherelm.x121.xcatb.mq5 +++ b/Indicators/x-saherelm.x121.xcatb.mq5 @@ -43,9 +43,6 @@ // // Imports ... -#include "../Classes/x-saherelm.x-alert.class.mq5" -#include "../Classes/x-saherelm.x-bar.analyser.class.mq5" -#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // @@ -79,40 +76,6 @@ input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period // this Cycle Used for All Calculations ... input ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle -// -// Validating ... -input group "Validating"; -input bool forceHasSwing = false; // Force Blocks to Have Swing -input bool forceObBarType = false; // Force Block Has Reversal Bar -input bool forceOBFVGBarType = false; // Force FVG Has Same Bars -input bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity -input bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity -input bool validateGapSequence = false; // Validate Block's Gap Sequence -input bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout - -// -// Filtering ... -input group "Filtering"; -input bool filterBasedOnPV = false; // Filter Based on Peak and Vale -input bool filterBasedOnSar = false; // Filter Based on Sar -input bool filterBasedOnRSI = false; // Filter Based on RSI -input bool filterBasedOnADX = false; // Filter Based on ADX -input bool filterBasedOnATR = false; // Filter Based on ATR -input bool filterBasedOnTrend = false; // Filter Based on Trend -input bool filterBasedOnDelta = false; // Filter Based on Delta -input bool filterBasedOnVolume = false; // Filter Based on Volume -input bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar -input bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar - -// -// Alert ... -input group "Alerts"; -input string mAlertPrefix = ""; // Alert Prefix -input bool _logAlerts = false; // Log Alerts -input bool _pushAlerts = false; // Push Alerts -input bool _mailAlerts = false; // Mail Alerts -input bool _terminalAlerts = false; // Terminal Alerts - // // Presentation ... input group "Presentation"; @@ -643,13 +606,6 @@ int rsiHandler = INVALID_HANDLE; int adxHandler = INVALID_HANDLE; int trendHandler = INVALID_HANDLE; -// -XCAlert *mAlert; -CArrayObj mObjects; -XCPOIDrawer *mDrawer; -bool mEnableAlerts = false; -XCBarAnalyser *mBarAnalyser; - // // Event Handlers ... @@ -743,21 +699,6 @@ void OnDeinit(const int reason) // ShowBars(); - // - mObjects.Clear(); - - // - delete mAlert; - ZeroMemory(mAlert); - - // - delete mDrawer; - ZeroMemory(mDrawer); - - // - delete mBarAnalyser; - ZeroMemory(mBarAnalyser); - // // De Initialize all Handlers and etc ... IndicatorRelease(atrHandler); @@ -1668,32 +1609,6 @@ bool InitRequirements() return result; } - // - // Initial Class Instances ... - - // - mDrawer = new XCPOIDrawer(); - mBarAnalyser = new XCBarAnalyser(); - - // - // Initialize and Configure Alert ... - mAlert = new XCAlert(); - mEnableAlerts = - _logAlerts || - _pushAlerts || - _mailAlerts || - _terminalAlerts; - string mPrefix = ShortName + - (!IsValid(mAlertPrefix) - ? "" - : "[" + mAlertPrefix + "]"); - mAlert.SetPrefix(mPrefix); - mAlert.SetLogAlerts(_logAlerts); - mAlert.SetMailAlerts(_mailAlerts); - mAlert.SetPushAlerts(_pushAlerts); - mAlert.SetEnableAlerts(mEnableAlerts); - mAlert.SetTerminalAlerts(_terminalAlerts); - // return result; } diff --git a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 index cf55b0ca..0da71911 100644 --- a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 +++ b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 @@ -219,9 +219,22 @@ struct XTriggerBlockFilters bool forceHasRSICrossing; // RSI Must Has Crossing Levels ... // - bool forceHasADXTrending; // ADX Must Trending ... + bool forceHasADXTrending; // ADX Must Has Trending ... bool forceHasADXCrossing; // ADX Must Has Crossing +DI/-DI ... + // + bool forceHasATRTrending; // ATR Must Has Trending ... + bool forceHasATRBreakout; // ATR Must Has Breakout ... + + // + bool forceHasTrendDir; // TREND Must Has Following Direction ... + bool forceHasTrendPlace; // TREND Place Based Filtering ... + bool forceHasTrendChange; // TREND Change Filtering ... + bool forceHasTrendTrending; // TREND Must Has Trending ... + bool forceHasTrendRejection; // TREND Line Must Rejected ... + bool forceHasTrendLineInside; // TREND Line has Inside ... + bool forceHasTrendDirOnBothSide; // TREND Must Has Following Direction in Both Side ... + // // Constructor(s) ... XTriggerBlockFilters() @@ -266,6 +279,19 @@ struct XTriggerBlockFilters forceHasADXTrending = false; forceHasADXCrossing = false; + // + forceHasATRTrending = false; + forceHasATRBreakout = false; + + // + forceHasTrendDir = false; + forceHasTrendPlace = false; + forceHasTrendChange = false; + forceHasTrendTrending = false; + forceHasTrendRejection = false; + forceHasTrendLineInside = false; + forceHasTrendDirOnBothSide = false; + // ZeroMemory(this); } @@ -429,20 +455,6 @@ bool DetectTriggerBlock1( iBar.Clean(); } - // - // TODO: Remove this ... - // Temparory Testing Configs ... - // validations.maxAllowedRange = 200; - // validations.forceHasSwing = true; - // validations.forceFVGBarType = true; - // validations.forceOBBarType = true; - // validations.validateGapSequence = true; - // validations.validateBlockEdgeBreakout = true; - // validations.liquidityLoopback = 144; - // validations.forceHasFLiquidity = true; - // validations.forceHasRLiquidity = true; - // validations.minAllowedBlockLength = 7; - // // Apply Validations ... if (result) @@ -465,23 +477,6 @@ bool DetectTriggerBlock1( } } - // - // TODO: Remove this ... - // filters.bosLoopback = 0; - // filters.filterBasedOnPV = true; - // filters.filterBasedOnSar = true; - // filters.forceSarSwitched = false; - // filters.forceSarOnBothSide = true; - // filters.forceSarHasBreakout = true; - // filters.forceSarHasReversalSide = false; - // filters.filterBasedOnRSI = false; - // filters.forceHasRSITrending = false; - // filters.forceHasRSIVPattern = false; - // filters.forceHasRSICrossing = false; - filters.filterBasedOnADX = true; - filters.forceHasADXTrending = false; - filters.forceHasADXCrossing = true; - // // Apply Filtering ... if (result) @@ -1648,11 +1643,589 @@ bool FilterTriggerBlock( // result = has; } + } + + // + // Filter Based On ATR Band ... + if (result && + filters.filterBasedOnATR) + { + // + // Here We Can Apply ATR Filters ... + // Since ATR Filters must be Check on OB Bars ... + // we Have to Loop back Based on OB Bars to Detect Conditions ... // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + + // + // Filter Using ATR Trending ... + if (result && + filters.forceHasATRTrending) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iATRUpper = helper.GetATRUpper(i); + double iPATRUpper = helper.GetATRUpper(i + 1); + + // + double iATRLower = helper.GetATRLower(i); + double iPATRLower = helper.GetATRLower(i + 1); + + // + bool isATRUp = + iATRLower > iPATRLower; + + // + bool isATRDown = + iATRUpper < iPATRUpper; + + // + has = isBullish + ? isATRUp + : isATRDown; + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using ATR Breakout ... + if (result && + filters.forceHasATRBreakout) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iATRUpper = helper.GetATRUpper(i); + double iATRLower = helper.GetATRLower(i); + + // + has = isBullish + ? triggerBlock.ob.lower < iATRLower + : triggerBlock.ob.upper > iATRUpper; + if (has) + { + break; + } + } + + // + result = has; + } + } + + // + // Filter Based On Trend ... + if (result && + filters.filterBasedOnTrend) + { + // + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex(); + + // + // Filter Using Trend Direction ... + if (result && + filters.forceHasTrendDir) + { + // + result = + result && + isBullish + ? conditions.isTrendBullish + : conditions.isTrendBearish; + } + + // + // Filter Using Trend Direction On Both Side ... + if (result && + filters.forceHasTrendDirOnBothSide) + { + // + // Side To ... + result = + result && + isBullish + ? conditions.isTrendBullish + : conditions.isTrendBearish; + + // + // Side From ... + int sFIDX = triggerBlock.ob.FromIndex(); + double sFTrendState = helper.GetTrendState(sFIDX); + result = + result && + isBullish + ? sFTrendState > 0 + : sFTrendState < 0; + } + + // + // Filter Using Trend Change ... + if (result && + filters.forceHasTrendChange) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iTrendState = helper.GetTrendState(i); + double iPTrendState = helper.GetTrendState(i + 1); + + // + bool isTrendSwitchedToBullish = + iTrendState > 0 && + iPTrendState <= 0; + + // + bool isTrendSwitchedToBearish = + iTrendState < 0 && + iPTrendState >= 0; + + // + has = + isBullish + ? isTrendSwitchedToBullish + : isTrendSwitchedToBearish; + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using Trend Trending ... + if (result && + filters.forceHasTrendTrending) + { + // + result = + result && + (isBullish + ? conditions.trendBuffer[cIDX] > conditions.trendBuffer[pIDX] + : conditions.trendBuffer[cIDX] < conditions.trendBuffer[pIDX]); + } + + // + // Filter Using Trend Rejection ... + if (result && + filters.forceHasTrendRejection) + { + // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + for (int i = toIDX; i < fromIDX; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + + // + // Read Trend Value ... + double iTrend = helper.GetTrend(i); + + // + bool isTrendBullishRejected = + has && + iBar.low < iTrend && + iBar.GetDown() > iTrend; + + // + bool isTrendBearishRejected = + has && + iBar.high > iTrend && + iBar.GetUp() < iTrend; + + // + has = + has && + (isBullish + ? isTrendBullishRejected + : isTrendBearishRejected); + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using Trend Inside ... + if (result && + filters.forceHasTrendLineInside) + { + // + result = + result && + conditions.trendBuffer[cIDX] > triggerBlock.ob.lower && + conditions.trendBuffer[cIDX] < triggerBlock.ob.upper; + } + + // + // Filter Using Trend Place ... + if (result && + filters.forceHasTrendPlace) + { + // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + double mult = + isBullish + ? 1 + : -1; + double edge = isBullish + ? triggerBlock.ob.lower + : triggerBlock.ob.upper; + double factor = edge + (mult * (triggerBlock.ob.GetRange() / 4)); + for (int i = toIDX; i < fromIDX; i++) + { + // + double iTrend = helper.GetTrend(i); + + // + has = + isBullish + ? factor >= iTrend + : factor <= iTrend; + if (has) + { + break; + } + } + + // + result = has; + } + } + + // + // Filter Using Delta ... + if (result && + filters.filterBasedOnDelta) + { + // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iDelta = helper.GetDelta(i); + double iPDelta = helper.GetDelta(i + 1); + + // + double iDeltaSignal = helper.GetDeltaSignal(i); + double iPDeltaSignal = helper.GetDeltaSignal(i + 1); + + // + bool isDeltaUp = + iDelta > iPDelta; + + // + bool isDeltaDown = + iDelta < iPDelta; + + // + bool isDeltaSignalUp = + iDeltaSignal > iPDeltaSignal; + + // + bool isDeltaSignalDown = + iDeltaSignal < iPDeltaSignal; + + // + bool isDeltaCrossedOverSignal = + iDelta > iDeltaSignal && + iPDelta <= iPDeltaSignal; + + // + bool isDeltaCrossedUnderSignal = + iDelta < iDeltaSignal && + iPDelta >= iPDeltaSignal; + + // + has = + isBullish + ? (isDeltaUp && + isDeltaSignalUp && + isDeltaCrossedOverSignal) + : (isDeltaDown && + isDeltaSignalDown && + isDeltaCrossedUnderSignal); + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using Volume ... + if (result && + filters.filterBasedOnVolume) + { + // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iBullVolume = helper.GetBullishVolume(i); + double iPBullVolume = helper.GetBullishVolume(i + 1); + + // + double iBullVolumeSignal = helper.GetBullishVolumeSignal(i); + double iPBullVolumeSignal = helper.GetBullishVolumeSignal(i + 1); + + // + double iBearVolume = helper.GetBearishVolume(i); + double iPBearVolume = helper.GetBearishVolume(i + 1); + + // + double iBearVolumeSignal = helper.GetBearishVolumeSignal(i); + double iPBearVolumeSignal = helper.GetBearishVolumeSignal(i + 1); + + // + bool isBullVolumeUp = + iBullVolume > iPBullVolume; + + // + bool isBullVolumeSignalUp = + iBullVolumeSignal > iPBullVolumeSignal; + + // + bool isBearVolumeUp = + iBearVolume > iPBearVolume; + + // + bool isBearVolumeSignalUp = + iBearVolumeSignal > iPBearVolumeSignal; + + // + bool isVolumeSwitchedToBullish = + iBullVolumeSignal > iBearVolumeSignal && + iPBullVolumeSignal <= iPBearVolumeSignal; + + // + bool isVolumeSwitchedToBearish = + iBearVolumeSignal > iBullVolumeSignal && + iPBearVolumeSignal <= iPBullVolumeSignal; + + // + has = + isBullish + ? (isBullVolumeUp && + isBullVolumeSignalUp && + isVolumeSwitchedToBullish) + : (isBearVolumeUp && + isBearVolumeSignalUp && + isVolumeSwitchedToBearish); + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using Signal Bar ... + if (result && + filters.filterBasedOnSignalBar) + { + // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + + // + double iSOpen = helper.GetSBarOpen(toIDX); + double iPSOpen = helper.GetSBarOpen(toIDX + 1); + + // + double iSClose = helper.GetSBarClose(toIDX); + double iPSClose = helper.GetSBarClose(toIDX + 1); + + // + double iSPow = MathAbs(iSOpen - iSClose); + double iPSPow = MathAbs(iPSOpen - iPSClose); + + // + result = + result && + iSPow > iPSPow && + (isBullish + ? iSClose > iSOpen + : iSClose < iSOpen); + + // + // Now Looking for Dir Change ... if (result) { - Print("Filter Passed ..."); + // + for (int i = toIDX; i < fromIDX; i++) + { + // + iSOpen = helper.GetSBarOpen(toIDX); + iPSOpen = helper.GetSBarOpen(toIDX + 1); + + // + iSClose = helper.GetSBarClose(toIDX); + iPSClose = helper.GetSBarClose(toIDX + 1); + + // + bool isSBullish = + iSClose > iSOpen; + + // + bool isPSBullish = + iPSClose > iPSOpen; + + // + bool isSBearish = + iSClose < iSOpen; + + // + bool isPSBearish = + iPSClose < iPSOpen; + + // + bool isSSwitchedToBullish = + isSBullish && + !isPSBullish; + + // + bool isSSwitchedToBearish = + isSBearish && + !isPSBearish; + + // + has = + isBullish + ? isSSwitchedToBullish + : isSSwitchedToBearish; + if (has) + { + break; + } + } + + // + result = has; + } + } + + // + // Filter Using Signal Bar ... + if (result && + filters.filterBasedOnHKSignalBar) + { + // + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + + // + double iSOpen = helper.GetHKSBarOpen(toIDX); + double iPSOpen = helper.GetHKSBarOpen(toIDX + 1); + + // + double iSClose = helper.GetHKSBarClose(toIDX); + double iPSClose = helper.GetHKSBarClose(toIDX + 1); + + // + double iSPow = MathAbs(iSOpen - iSClose); + double iPSPow = MathAbs(iPSOpen - iPSClose); + + // + result = + result && + iSPow > iPSPow && + (isBullish + ? iSClose > iSOpen + : iSClose < iSOpen); + + // + // Now Looking for Dir Change ... + if (result) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + iSOpen = helper.GetHKSBarOpen(toIDX); + iPSOpen = helper.GetHKSBarOpen(toIDX + 1); + + // + iSClose = helper.GetHKSBarClose(toIDX); + iPSClose = helper.GetHKSBarClose(toIDX + 1); + + // + bool isSBullish = + iSClose > iSOpen; + + // + bool isPSBullish = + iPSClose > iPSOpen; + + // + bool isSBearish = + iSClose < iSOpen; + + // + bool isPSBearish = + iPSClose < iPSOpen; + + // + bool isSSwitchedToBullish = + isSBullish && + !isPSBullish; + + // + bool isSSwitchedToBearish = + isSBearish && + !isPSBearish; + + // + has = + isBullish + ? isSSwitchedToBullish + : isSSwitchedToBearish; + if (has) + { + break; + } + } + + // + result = has; } } @@ -2370,28 +2943,31 @@ bool DrawTriggerBlock( return result; } + // + XTriggerBlock _trigger = trigger; + // // Update To ... bool canUpdateTo = IsValid(to); if (canUpdateTo) { // - trigger.trigger.to = to; - trigger.rLiquidity.to = to; - trigger.fLiquidity.to = to; + _trigger.trigger.to = to; + _trigger.rLiquidity.to = to; + _trigger.fLiquidity.to = to; } // - bool isBullish = trigger.IsBullish(); + bool isBullish = _trigger.IsBullish(); // // Draw OB ... - if (trigger.ob.IsValid()) + if (_trigger.ob.IsValid()) { // XCBoxObject *iOBObj; result = drawer.DrawBox( - trigger.ob, + _trigger.ob, iOBObj // ); if (result) @@ -2425,12 +3001,12 @@ bool DrawTriggerBlock( // // Draw FVG ... - if (trigger.fvg.IsValid()) + if (_trigger.fvg.IsValid()) { // XCBoxObject *iFVGObj; result = drawer.DrawBox( - trigger.fvg, + _trigger.fvg, iFVGObj // ); if (result) @@ -2464,12 +3040,12 @@ bool DrawTriggerBlock( // // Draw Trigger ... - if (trigger.trigger.IsValid()) + if (_trigger.trigger.IsValid()) { // XCBoxObject *iTriggerObj; result = drawer.DrawBox( - trigger.trigger, + _trigger.trigger, iTriggerObj // ); if (result) @@ -2506,12 +3082,12 @@ bool DrawTriggerBlock( // // Reversla Liquidity ... - if (trigger.rLiquidity.IsValid()) + if (_trigger.rLiquidity.IsValid()) { // XCBoxObject *iLiqObj; result = drawer.DrawBox( - trigger.rLiquidity, + _trigger.rLiquidity, iLiqObj // ); if (result) @@ -2529,12 +3105,12 @@ bool DrawTriggerBlock( // // Following Liquidity ... - if (trigger.fLiquidity.IsValid()) + if (_trigger.fLiquidity.IsValid()) { // XCBoxObject *iLiqObj; result = drawer.DrawBox( - trigger.fLiquidity, + _trigger.fLiquidity, iLiqObj // ); if (result) @@ -2552,22 +3128,22 @@ bool DrawTriggerBlock( // // Draw Swing Bar ... - if (trigger.swingBar.IsValid()) + if (_trigger.swingBar.IsValid()) { // color swingColor = - trigger.fvg.IsBullish() + _trigger.fvg.IsBullish() ? clrAqua : clrMagenta; ENUM_X_PRICE swingPType = - trigger.fvg.IsBullish() + _trigger.fvg.IsBullish() ? X_PRICE_LOW : X_PRICE_HIGH; // XCBarArrowObject *swingObj; result = drawer.CreateBarArrow( - trigger.swingBar, + _trigger.swingBar, swingObj, swingPType, 159, @@ -2589,7 +3165,7 @@ bool DrawTriggerBlock( // // Draw RR of Signal ... if (_drawSignals && - trigger.signal.IsValid() && + _trigger.signal.IsValid() && rrZoneLength > 0) { // @@ -2598,7 +3174,7 @@ bool DrawTriggerBlock( result = iRRObj.Create( drawer.ChartIdentification(), drawer.SubWindowIdentification(), - trigger.signal, + _trigger.signal, rrZoneLength // ); if (result)