From 2f865670c57bc3297ed4c756b9eabb19cfe504bb Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 23 May 2025 20:29:37 +0330 Subject: [PATCH] last preparation of XCATB indicator, helper and tester EA ... --- Documents/BKP/xcaea.trigger.block.lib.mq5 | 2847 +----------- Documents/BKP/xcaea.trigger.block.lib.old.mq5 | 4122 +++++++++++++++++ Documents/BKP/xcatb.tm.inputs.mq5 | 316 ++ {Experts => Documents/BKP}/xczone.test.ea.mq5 | 0 Experts/xcatb.test.ea.mq5 | 836 ++++ Helpers/x-saherelm.x121.xcatb.helper.mq5 | 3789 +++++++++++++++ Helpers/x-saherelm.x121.xtb.helper.mq5 | 65 - Libraries/x-saherelm.x121.xcatb.lib.mq5 | 182 +- XCAEA/Classes/xcaea.x-poi.detector.class.mq5 | 1 - XCAEA/Libraries/xcaea.trigger.block.lib.mq5 | 1487 ------ 10 files changed, 9267 insertions(+), 4378 deletions(-) create mode 100644 Documents/BKP/xcaea.trigger.block.lib.old.mq5 create mode 100644 Documents/BKP/xcatb.tm.inputs.mq5 rename {Experts => Documents/BKP}/xczone.test.ea.mq5 (100%) create mode 100644 Experts/xcatb.test.ea.mq5 create mode 100644 Helpers/x-saherelm.x121.xcatb.helper.mq5 delete mode 100644 Helpers/x-saherelm.x121.xtb.helper.mq5 delete mode 100644 XCAEA/Libraries/xcaea.trigger.block.lib.mq5 diff --git a/Documents/BKP/xcaea.trigger.block.lib.mq5 b/Documents/BKP/xcaea.trigger.block.lib.mq5 index c3b7877f..82abbc74 100644 --- a/Documents/BKP/xcaea.trigger.block.lib.mq5 +++ b/Documents/BKP/xcaea.trigger.block.lib.mq5 @@ -94,6 +94,7 @@ struct XCAEATriggerBlockConfiguration int minAllowedBlockEdgeLength; // Minimum Required Block Edge Length // + // Validation ... bool forceOBOppositBar; // Force OB to Start by Opposit Bars bool forceFVGBarType; // Force FVG to Has Same Type of Bars bool forceGapBarBreakout; // Force FVG's Gap Bar to Breakeout OB Edge Side @@ -101,15 +102,6 @@ struct XCAEATriggerBlockConfiguration bool forceHasLiquidity; // Force Has Following Liquidity Zone bool forceHasReversalLiquidity; // Force Has Reversal Liquidity Zone - // - // Validating ... - int minZoneLength; // Minimum Length of Consolidation Zone - bool forceHasSwing; // Force Zone's Has Propper Swing - bool forceHasPinBarEntry; // Force Zone's Ends with a Pin Bar - bool forceGapBarsBreakout; // Force Zone's Gap Bar's Breakes Out - double maxZoneRangeInPoints; // Max Zone Range in Point - double maxAllowedEntryDistance; // Max Allowed Entry Distance - // // Filtering ... bool filterBasedOnSar; // Filter Trigger Block Based on Sar @@ -119,6 +111,9 @@ struct XCAEATriggerBlockConfiguration bool filterBasedOnScores; // Filter Trigger Block Based on Scores bool filterBasedOnVolumes; // Filter Trigger Block Based on Volumes + // + double targets[]; // Targets Collection for R:R on Signal Preparation + // // Constructor ... XCAEATriggerBlockConfiguration() @@ -134,15 +129,17 @@ struct XCAEATriggerBlockConfiguration void Clean() { // + // Validating ... + maxAllowedRange = false; + minAllowedBlockEdgeLength = false; // - // Validating ... - minZoneLength = 0; - forceHasSwing = false; - maxZoneRangeInPoints = 0.0; - forceHasPinBarEntry = false; - forceGapBarsBreakout = false; - maxAllowedEntryDistance = 0.0; + forceOBOppositBar = false; + forceFVGBarType = false; + forceGapBarBreakout = false; + forceHasSwingBar = false; + forceHasLiquidity = false; + forceHasReversalLiquidity = false; // // Filtering ... @@ -150,6 +147,11 @@ struct XCAEATriggerBlockConfiguration filterBasedOnRSI = false; filterBasedOnADX = false; filterBasedOnTrend = false; + filterBasedOnScores = false; + filterBasedOnVolumes = false; + + // + Clean(targets); // ZeroMemory(this); @@ -158,169 +160,6 @@ struct XCAEATriggerBlockConfiguration // // Preset Configurations ... - // - // Commons Verifications which used in all - // Preset Configurations ... - void ConfigureCommons() - { - // - minZoneLength = 7; - forceHasSwing = true; - maxZoneRangeInPoints = 70; - forceHasPinBarEntry = true; - forceGapBarsBreakout = true; - maxAllowedEntryDistance = 30; - } - - // - // Cleanup Range Verifications ... - void CleanRanges() - { - // - maxZoneRangeInPoints = 0; - maxAllowedEntryDistance = 0; - } - - // - void ConfigureFullFilter() - { - // - // Apply Common Configurations ... - ConfigureCommons(); - - // - // Apply Full Filters ... - filterBasedOnSar = true; - filterBasedOnRSI = true; - filterBasedOnADX = true; - filterBasedOnTrend = true; - } - - // - void ConfigureFullFilterNoRange() - { - // - // Apply Common Configurations ... - ConfigureCommons(); - - // - // Clean Ranges ... - CleanRanges(); - - // - // Apply Full Filters ... - filterBasedOnSar = true; - filterBasedOnRSI = true; - filterBasedOnADX = true; - filterBasedOnTrend = true; - } - - // - void ConfigureSarRsiAdxFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnTrend = false; - } - - // - void ConfigureSarRsiTrendFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnADX = false; - } - - // - void ConfigureSarAdxTrendFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnRSI = false; - } - - // - void ConfigureRsiAdxTrendFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnSar = false; - } - - // - void ConfigureSarRsiFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnADX = false; - filterBasedOnTrend = false; - } - - // - void ConfigureSarAdxFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnRSI = false; - filterBasedOnTrend = false; - } - - // - void ConfigureSarTrendFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnRSI = false; - filterBasedOnADX = false; - } - - // - void ConfigureRsiAdxFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnSar = false; - filterBasedOnTrend = false; - } - - // - void ConfigureRsiTrendFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnSar = false; - filterBasedOnADX = false; - } - - // - void ConfigureAdxTrendFilter() - { - // - ConfigureFullFilter(); - - // - filterBasedOnSar = false; - filterBasedOnRSI = false; - } - // }; @@ -338,6 +177,9 @@ struct XTriggerBlock XCAEAConditions conditions; // Market Conditions XCAEATriggerBlockConfiguration configuration; // Detection Configuration + // + XSignal signal; // Pepared Signal + // // Constructor ... XTriggerBlock() @@ -355,6 +197,7 @@ struct XTriggerBlock // ob.Clean(); fvg.Clean(); + signal.Clean(); trigger.Clean(); swingBar.Clean(); rLiquidity.Clean(); @@ -387,2565 +230,6 @@ struct XTriggerBlock // // Extensions ... -/** - * Detect a Trigger Block ... - * - * @param triggerBlock: XBoxZone instance reference, The Detected Trigger Block ... - * @param conditions: XCAEAConditions instance reference, The Block Verification Conditions ... - * @param helper: XCXCAEAHelper instance pointer, Specified The Helper Class Instance which used to Detect Conditions ... - * @param config: XCAEATriggerBlockConfiguration instance reference, Specified The Trigger Block Detection Configuration ... - * @param bar_index: int, Specified The Bar Index to Start Detection ... - * @param loopback: int, Specified The Loopback Length to Detect Helper Conditions ... - * - * @return ( bool ) - */ -bool DetectTriggerBlock( - XBoxZone &triggerBlock, - XCAEAConditions &conditions, - XCXCAEAHelper *helper, - XCAEATriggerBlockConfiguration &config, - int bar_index = 0, - int loopback = 6 // -) -{ - // - bool result = false; - - // - conditions.Clean(); - triggerBlock.Clean(); - - // - // Normalize Args ... - loopback = NormalizeInt(loopback, 6); - bar_index = NormalizeInt(bar_index, 0); - - // - // Validate Args ... - result = helper != NULL; - if (!result) - { - return result; - } - - // - // Provide base Requirements ... - - // - string symbol = helper.GetSymbol(); - double points = GetPoints(symbol); - ENUM_TIMEFRAMES period = helper.GetPeriod(); - - // - // Conditions Reading Indexes ... - int zIDX = 0; - int cIDX = zIDX + 1; - int pIDX = cIDX + 1; - int p2IDX = pIDX + 1; - int p3IDX = p2IDX + 1; - int p4IDX = p3IDX + 1; - - // - double ll = 0; - double hh = 0; - bool has = false; - ENUM_X_DIRECTION iDir; - - // - // Retrieve Current Conditions ... - result = helper.GetConditions( - conditions, - bar_index, - loopback // - ); - - // - // Retrieve Required Bars ... - - // - XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... - XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ... - XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ... - XOHCL p2Bar; // Determines FVG's Start Bar in a Block ... - XOHCL p3Bar; // First Verification of Block ... - XOHCL p4Bar; // Seccond Verification of Block ... - - // - result = zBar.Init( - symbol, - period, - bar_index // - ); - result = - result && - zBar.GetPreviousBar(cBar); - result = - result && - cBar.GetPreviousBar(pBar); - result = - result && - pBar.GetPreviousBar(p2Bar); - result = - result && - p2Bar.GetPreviousBar(p3Bar); - result = - result && - p3Bar.GetPreviousBar(p4Bar); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - - // - // Detect Based Order Block using CBar ... - result = - helper - .barAnalyser - .IsOB( - cBar, - triggerBlock, - true, // Force FVG Bar Type ... - true // Force Block Two Bar Checking ... - ); - - // - // Ensure a Block is Detected ... - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - - // - // Reading Some Block Based Requirements ... - - // - bool isBullish = - result && - triggerBlock.IsBullish(); - - // - bool isBearish = - result && - triggerBlock.IsBearish(); - - // - int toIDX = triggerBlock.ToIndex(); - int fromIDX = triggerBlock.FromIndex(); - - // - // Start Validating ... - - // - // Validating p2Bar and p3Bar Direction ... - if (result) - { - // - iDir = Opposit(triggerBlock.dir); - - // - result = - iDir == p3Bar.GetDirection() || - iDir == p4Bar.GetDirection(); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validating Using Max Range ... - result = config.maxZoneRangeInPoints > 0; - if (result) - { - // - double range = triggerBlock.GetRange(); - result = range <= config.maxZoneRangeInPoints * points; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validate Gap Endup with PinBar ... - result = config.forceHasPinBarEntry; - if (result) - { - // - bool isBullishRejected = - isBullish && - cBar.IsBullish() && - cBar.GetLowShadow() > cBar.GetHighShadow(); - - // - bool isBearishRejected = - isBearish && - cBar.IsBearish() && - cBar.GetLowShadow() < cBar.GetHighShadow(); - - // - result = isBullishRejected || - isBearishRejected; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validating Gap Bar must a Momentum Bar and - // Breakes out Zone's Directional Edge ... - // for Bullish: Upper - // for Bearish: Lower - result = config.forceGapBarsBreakout; - if (result) - { - // - // Gap Bar is PBar ... - - // - // Check Gap Bar is Momentum Bar ... - result = - helper - .barAnalyser - .IsMomentum( - pBar, - iDir // - ); - bool isBullishMomentum = - result && - IsBullish(iDir); - bool isBearishMomentum = - result && - IsBearish(iDir); - - // - // Check Gap Bar's Breakout ... - - // - bool isBullishBreakedout = - isBullish && - pBar.IsBullish() && - isBullishMomentum && - pBar.GetUp() > triggerBlock.upper && - pBar.GetDown() < triggerBlock.upper; - - // - bool isBearishBreakedout = - isBearish && - pBar.IsBearish() && - isBearishMomentum && - pBar.GetUp() > triggerBlock.lower && - pBar.GetDown() < triggerBlock.lower; - - // - result = isBullishBreakedout || - isBearishBreakedout; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validate Zone Has Propper Swing ... - // for Bullish: p2Bar or p3Bar must be a Swing Low ... - // for Bearish: p2Bar or p3Bar must be a Swing High ... - result = config.forceHasSwing; - if (result) - { - // - // p2Bar ... - bool isP2BarSwing = - helper - .barAnalyser - .IsSimpleSwing( - p2Bar, - iDir // - ); - bool isP2BarSwingLow = - isP2BarSwing && - IsBullish(iDir); - bool isP2BarSwingHigh = - isP2BarSwing && - IsBearish(iDir); - - // - // p3Bar ... - bool isP3BarSwing = - helper - .barAnalyser - .IsSimpleSwing( - p3Bar, - iDir // - ); - bool isP3BarSwingLow = - isP3BarSwing && - IsBullish(iDir); - bool isP3BarSwingHigh = - isP3BarSwing && - IsBearish(iDir); - - // - bool hasSwingLow = - isBullish && - (isP2BarSwingLow || - isP3BarSwingLow); - - // - bool hasSwingHigh = - isBearish && - (isP2BarSwingHigh || - isP3BarSwingHigh); - - // - result = - hasSwingLow || - hasSwingHigh; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validating Using Swing Length ... - result = config.minZoneLength > 0; - if (result) - { - // - XOHCL fromBar; - has = triggerBlock.FromBar(fromBar); - if (result) - { - // - // Retrieve HH and LL ... - ll = fromBar.FindLowest(config.minZoneLength, MODE_LOW); - hh = fromBar.FindHighest(config.minZoneLength, MODE_HIGH); - - // - // Validate Using HH and LL ... - - // - bool isBullishValid = - isBullish && - ll >= triggerBlock.lower; - - // - bool isBearishValid = - isBearish && - hh <= triggerBlock.upper; - - // - result = isBullishValid || - isBearishValid; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - - // - // Update Zone's From Time ... - triggerBlock.from = GetBarTime( - triggerBlock.symbol, - triggerBlock.period, - fromBar.Index() + config.minZoneLength // - ); - } - - // - fromBar.Clean(); - } - - // - // Validate Max Allowed Entry Distance ... - result = config.maxAllowedEntryDistance > 0; - if (result) - { - // - double base = - isBullish - ? triggerBlock.upper - : triggerBlock.lower; - double entryDistance = MathAbs(zBar.open - base); - result = entryDistance <= config.maxAllowedEntryDistance * points; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Here we Ensure which have a Valid Zone using Different Applied Validations ... - // from now we are Going to Filterd Validate Zones ... - - // - // Check Exists Filters or not ... - result = config.filterBasedOnSar || - config.filterBasedOnRSI || - config.filterBasedOnADX || - config.filterBasedOnTrend; - if (result) - { - // - // Do Apply Several Exists Filters ... - - // - // SAR Filter ... - if (config.filterBasedOnSar) - { - // - // Reading Conditions Values ... - - // - 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]; - double p4Sar = conditions.sarBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - bool isZSarBullish = zSar < zBar.low; - bool isZSarBearish = zSar > zBar.high; - - // - bool isCSarBullish = cSar < cBar.low; - bool isCSarBearish = cSar > cBar.high; - - // - bool isPSarBullish = pSar < pBar.low; - bool isPSarBearish = pSar > pBar.high; - - // - bool isP2SarBullish = p2Sar < p2Bar.low; - bool isP2SarBearish = p2Sar > p2Bar.high; - - // - bool isCSarSwitchedToBullish = - isZSarBullish && - isCSarBullish && - !isPSarBullish && - cBar.IsBullish() && - cBar.GetUp() > pSar; - - // - bool isCSarSwitchedToBearish = - isZSarBearish && - isCSarBearish && - !isPSarBearish && - cBar.IsBearish() && - cBar.GetDown() < pSar; - - // - bool isPSarSwitchedToBullish = - isZSarBullish && - isCSarBullish && - isPSarBullish && - !isP2SarBullish && - pBar.IsBullish() && - pBar.GetUp() > p2Sar; - - // - bool isPSarSwitchedToBearish = - isZSarBearish && - isCSarBearish && - isPSarBearish && - !isP2SarBearish && - pBar.IsBearish() && - pBar.GetDown() < p2Sar; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - (isCSarSwitchedToBullish || - isPSarSwitchedToBullish); - - // - bool isBearishFilterd = - isBearish && - (isCSarSwitchedToBearish || - isPSarSwitchedToBearish); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // RSI Filter ... - if (config.filterBasedOnRSI) - { - // - // Reading Conditions Values ... - - // - double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2; - - // - double zRSI = conditions.rsiBuffer[zIDX]; - double cRSI = conditions.rsiBuffer[cIDX]; - double pRSI = conditions.rsiBuffer[pIDX]; - double p2RSI = conditions.rsiBuffer[p2IDX]; - double p3RSI = conditions.rsiBuffer[p3IDX]; - double p4RSI = conditions.rsiBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - bool isZRSIBullish = zRSI > rsiTrend; - bool isZRSIBearish = zRSI < rsiTrend; - - // - bool isCRSIBullish = cRSI > rsiTrend; - bool isCRSIBearish = cRSI < rsiTrend; - - // - bool isPRSIBullish = pRSI > rsiTrend; - bool isPRSIBearish = pRSI < rsiTrend; - - // - bool isP2RSIBullish = p2RSI > rsiTrend; - bool isP2RSIBearish = p2RSI < rsiTrend; - - // - bool isP3RSIBullish = p3RSI > rsiTrend; - bool isP3RSIBearish = p3RSI < rsiTrend; - - // - // Trending Conditions ... - - // - bool isCRSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - !isPRSIBullish; - - // - bool isCRSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - !isPRSIBearish; - - // - bool isPRSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - isPRSIBullish && - !isP2RSIBullish; - - // - bool isPRSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - isPRSIBearish && - !isP2RSIBearish; - - // - bool isP2RSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - isPRSIBullish && - isP2RSIBullish && - !isP3RSIBullish; - - // - bool isP2RSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - isPRSIBearish && - isP2RSIBearish && - !isP3RSIBearish; - - // - // Crosses Conditions ... - - // - bool isCBarCrossedOverOS = - zRSI > conditions.rsiOSLevel && - cRSI > conditions.rsiOSLevel && - pRSI <= conditions.rsiOSLevel; - - // - bool isCBarCrossedUnderOB = - zRSI < conditions.rsiOBLevel && - cRSI < conditions.rsiOBLevel && - pRSI >= conditions.rsiOBLevel; - - // - bool isPBarCrossedOverOS = - zRSI > conditions.rsiOSLevel && - cRSI > conditions.rsiOSLevel && - pRSI > conditions.rsiOSLevel && - p2RSI <= conditions.rsiOSLevel; - - // - bool isPBarCrossedUnderOB = - zRSI < conditions.rsiOBLevel && - cRSI < conditions.rsiOBLevel && - pRSI < conditions.rsiOBLevel && - p2RSI >= conditions.rsiOBLevel; - - // - // V Pattern Conditions ... - - // - bool isCRSIHasVBullishPattern = - zRSI >= cRSI && - cRSI > pRSI && - p2RSI > pRSI && - cRSI >= p2RSI; - - // - bool isCRSIHasVBearishPattern = - zRSI <= cRSI && - cRSI < pRSI && - p2RSI < pRSI && - cRSI <= p2RSI; - - // - // Continuation Conditions ... - - // - bool isRSIUp = - zRSI >= cRSI && - (cRSI >= pRSI || - pRSI >= p2RSI || - p2RSI >= p3RSI); - - // - bool isRSIDown = - zRSI <= cRSI && - (cRSI <= pRSI || - pRSI <= p2RSI || - p2RSI <= p3RSI); - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isRSIUp - // - || - // - // Crosses ... - (isCBarCrossedOverOS || - isPBarCrossedOverOS) - // - || - // - // V Pattern ... - isCRSIHasVBullishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBullish || - isPRSISwitchedToBullish || - isP2RSISwitchedToBullish) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isRSIDown - // - || - // - // Crosses ... - (isCBarCrossedUnderOB || - isPBarCrossedUnderOB) - // - || - // - // V Pattern ... - isCRSIHasVBearishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBearish || - isPRSISwitchedToBearish || - isP2RSISwitchedToBearish) - // - ); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // ADX Filter ... - if (config.filterBasedOnADX) - { - // - // Reading Conditions Values ... - - // - // ADX ... - double zADX = conditions.adxBuffer[zIDX]; - double cADX = conditions.adxBuffer[cIDX]; - double pADX = conditions.adxBuffer[pIDX]; - double p2ADX = conditions.adxBuffer[p2IDX]; - double p3ADX = conditions.adxBuffer[p3IDX]; - double p4ADX = conditions.adxBuffer[p4IDX]; - - // - // ADX +DI ... - double zADXP = conditions.adxpBuffer[zIDX]; - double cADXP = conditions.adxpBuffer[cIDX]; - double pADXP = conditions.adxpBuffer[pIDX]; - double p2ADXP = conditions.adxpBuffer[p2IDX]; - double p3ADXP = conditions.adxpBuffer[p3IDX]; - double p4ADXP = conditions.adxpBuffer[p4IDX]; - - // - // ADX -DI ... - double zADXN = conditions.adxnBuffer[zIDX]; - double cADXN = conditions.adxnBuffer[cIDX]; - double pADXN = conditions.adxnBuffer[pIDX]; - double p2ADXN = conditions.adxnBuffer[p2IDX]; - double p3ADXN = conditions.adxnBuffer[p3IDX]; - double p4ADXN = conditions.adxnBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - // Grows ... - - // - bool isADXUp = - zADX >= cADX && - (cADX >= pADX || - pADX >= p2ADX); - - // - bool isADXDown = - zADX <= cADX && - (cADX <= pADX || - pADX <= p2ADX); - - // - // Trending ... - - // - bool isZADXBullish = zADX > conditions.adxThreshold; - bool isZADXBearish = zADX < conditions.adxThreshold; - - // - bool isCADXBullish = cADX > conditions.adxThreshold; - bool isCADXBearish = cADX < conditions.adxThreshold; - - // - bool isPADXBullish = pADX > conditions.adxThreshold; - bool isPADXBearish = pADX < conditions.adxThreshold; - - // - bool isP2ADXBullish = p2ADX > conditions.adxThreshold; - bool isP2ADXBearish = p2ADX < conditions.adxThreshold; - - // - bool isP3ADXBullish = p3ADX > conditions.adxThreshold; - bool isP3ADXBearish = p3ADX < conditions.adxThreshold; - - // - bool isP4ADXBullish = p4ADX > conditions.adxThreshold; - bool isP4ADXBearish = p4ADX < conditions.adxThreshold; - - // - bool isCADXSwitchedToBullish = - isZADXBullish && - isCADXBullish && - !isPADXBullish; - - // - bool isCADXSwitchedToBearish = - isZADXBearish && - isCADXBearish && - !isPADXBearish; - - // - bool isPADXSwitchedToBullish = - isZADXBullish && - isCADXBullish && - isPADXBullish && - !isP2ADXBullish; - - // - bool isPADXSwitchedToBearish = - isZADXBearish && - isCADXBearish && - isPADXBearish && - !isP2ADXBearish; - - // - // Powering ... - - // - bool isZADXHasBullishPower = zADXP > zADXN; - bool isZADXHasBearishPower = zADXN > zADXP; - - // - bool isCADXHasBullishPower = cADXP > cADXN; - bool isCADXHasBearishPower = cADXN > cADXP; - - // - bool isPADXHasBullishPower = pADXP > pADXN; - bool isPADXHasBearishPower = pADXN > pADXP; - - // - bool isP2ADXHasBullishPower = p2ADXP > p2ADXN; - bool isP2ADXHasBearishPower = p2ADXN > p2ADXP; - - // - bool isP3ADXHasBullishPower = p3ADXP > p3ADXN; - bool isP3ADXHasBearishPower = p3ADXN > p3ADXP; - - // - bool isP4ADXHasBullishPower = p4ADXP > p4ADXN; - bool isP4ADXHasBearishPower = p4ADXN > p4ADXP; - - // - bool isCADXSwitchedToBullishPower = - isZADXHasBullishPower && - isCADXHasBullishPower && - !isPADXHasBullishPower; - - // - bool isCADXSwitchedToBearishPower = - isZADXHasBearishPower && - isCADXHasBearishPower && - !isPADXHasBearishPower; - - // - bool isPADXSwitchedToBullishPower = - isZADXHasBullishPower && - isCADXHasBullishPower && - isPADXHasBullishPower && - !isP2ADXHasBullishPower; - - // - bool isPADXSwitchedToBearishPower = - isZADXHasBearishPower && - isCADXHasBearishPower && - isPADXHasBearishPower && - !isP2ADXHasBearishPower; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isADXUp - // - || - // - // Trending ... - (isCADXSwitchedToBullish || - isPADXSwitchedToBullish) - // - || - // - // Powering ... - (isCADXSwitchedToBullishPower || - isPADXSwitchedToBullishPower) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isADXDown - // - || - // - // Trending ... - (isCADXSwitchedToBearish || - isPADXSwitchedToBearish) - // - || - // - // Powering ... - (isCADXSwitchedToBearishPower || - isPADXSwitchedToBearishPower) - // - ); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // TREND Filter ... - if (config.filterBasedOnTrend) - { - // - // Reading Conditions Values ... - - // - double zTrend = conditions.trendBuffer[zIDX]; - double cTrend = conditions.trendBuffer[cIDX]; - double pTrend = conditions.trendBuffer[pIDX]; - double p2Trend = conditions.trendBuffer[p2IDX]; - double p3Trend = conditions.trendBuffer[p3IDX]; - double p4Trend = conditions.trendBuffer[p4IDX]; - - // - double trends[] = { - zTrend, - cTrend, - pTrend, - p2Trend, - p3Trend, - p4Trend // - }; - double trendsMin = GetMin(trends); - double trendsMax = GetMax(trends); - double trendsAVG = GetAverage(trends); - - // - double zTrendState = conditions.trendStateBuffer[zIDX]; - double cTrendState = conditions.trendStateBuffer[cIDX]; - double pTrendState = conditions.trendStateBuffer[pIDX]; - double p2TrendState = conditions.trendStateBuffer[p2IDX]; - double p3TrendState = conditions.trendStateBuffer[p3IDX]; - double p4TrendState = conditions.trendStateBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - // Grows ... - - // - bool isTrendUp = - zTrend >= cTrend && - cTrend >= trendsAVG && - cTrend > trendsMin; - - // - bool isTrendDown = - zTrend <= cTrend && - cTrend <= trendsAVG && - cTrend < trendsMax; - - // - // Stating ... - - // - bool isCTrendBullish = - zTrendState > 0 && - cTrendState > 0; - - // - bool isCTrendBearish = - zTrendState < 0 && - cTrendState < 0; - - // - bool isPTrendBullish = - zTrendState > 0 && - cTrendState > 0 && - pTrendState > 0; - - // - bool isPTrendBearish = - zTrendState < 0 && - cTrendState < 0 && - pTrendState < 0; - - // - bool isP2TrendBullish = - zTrendState > 0 && - cTrendState > 0 && - pTrendState > 0 && - p2TrendState > 0; - - // - bool isP2TrendBearish = - zTrendState < 0 && - cTrendState < 0 && - pTrendState < 0 && - p2TrendState < 0; - - // - bool isCTrendSwitchedToBullish = - isCTrendBullish && - !isPTrendBullish; - - // - bool isCTrendSwitchedToBearish = - isCTrendBearish && - !isPTrendBearish; - - // - bool isPTrendSwitchedToBullish = - isCTrendBullish && - isPTrendBullish && - !isP2TrendBullish; - - // - bool isPTrendSwitchedToBearish = - isCTrendBearish && - isPTrendBearish && - !isP2TrendBearish; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isTrendUp - // - || - // - // Trend Stating ... - (isCTrendBullish && - isPTrendBullish) - // - || - // - // Switching ... - (isCTrendSwitchedToBullish || - isPTrendSwitchedToBullish) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isTrendDown - // - || - // - // Trend Stating ... - (isCTrendBearish && - isPTrendBearish) - // - || - // - // Switching ... - (isCTrendSwitchedToBearish || - isPTrendSwitchedToBearish) - // - ); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // SCORE Filter ... - - // - // VOLUME Filter ... - } - - // - result = triggerBlock.IsValid(); - if (result) - { - // - triggerBlock.type = - isBullish - ? ToString(XCA_TRIGGER_BULL) - : ToString(XCA_TRIGGER_BEAR); - } - - // - // Cleanup Resources ... - - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - if (!result) - { - // - conditions.Clean(); - triggerBlock.Clean(); - } - - // - return result; -}; - -bool DetectTriggerBlock1( - XBoxZone &triggerBlock, - XCAEAConditions &conditions, - XCXCAEAHelper *helper, - XCAEATriggerBlockConfiguration &config, - int bar_index = 0, - int loopback = 6 // -) -{ - // - bool result = false; - - // - conditions.Clean(); - triggerBlock.Clean(); - - // - // Normalize Args ... - loopback = NormalizeInt(loopback, 6); - bar_index = NormalizeInt(bar_index, 0); - - // - // Validate Args ... - result = helper != NULL; - if (!result) - { - return result; - } - - // - // Provide base Requirements ... - - // - string symbol = helper.GetSymbol(); - double points = GetPoints(symbol); - ENUM_TIMEFRAMES period = helper.GetPeriod(); - - // - // Conditions Reading Indexes ... - int zIDX = 0; - int cIDX = zIDX + 1; - int pIDX = cIDX + 1; - int p2IDX = pIDX + 1; - int p3IDX = p2IDX + 1; - int p4IDX = p3IDX + 1; - - // - double ll = 0; - double hh = 0; - bool has = false; - ENUM_X_DIRECTION iDir; - - // - // Retrieve Current Conditions ... - result = helper.GetConditions( - conditions, - bar_index, - loopback // - ); - - // - // Retrieve Required Bars ... - - // - XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... - XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ... - XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ... - XOHCL p2Bar; // Determines FVG's Start Bar in a Block ... - XOHCL p3Bar; // First Verification of Block ... - XOHCL p4Bar; // Seccond Verification of Block ... - - // - result = zBar.Init( - symbol, - period, - bar_index // - ); - result = - result && - zBar.GetPreviousBar(cBar); - result = - result && - cBar.GetPreviousBar(pBar); - result = - result && - pBar.GetPreviousBar(p2Bar); - result = - result && - p2Bar.GetPreviousBar(p3Bar); - result = - result && - p3Bar.GetPreviousBar(p4Bar); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - - // - // Detect Based Order Block using CBar ... - result = - helper - .barAnalyser - .IsOB( - cBar, - triggerBlock, - true, // Force FVG Bar Type ... - true // Force Block Two Bar Checking ... - ); - - // - // Ensure a Block is Detected ... - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - return result; - - // - // Reading Some Block Based Requirements ... - - // - bool isBullish = - result && - triggerBlock.IsBullish(); - - // - bool isBearish = - result && - triggerBlock.IsBearish(); - - // - int toIDX = triggerBlock.ToIndex(); - int fromIDX = triggerBlock.FromIndex(); - - // - // Start Validating ... - - // - // Validating p2Bar and p3Bar Direction ... - if (result) - { - // - iDir = Opposit(triggerBlock.dir); - - // - result = - iDir == p3Bar.GetDirection() || - iDir == p4Bar.GetDirection(); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validating Using Max Range ... - result = config.maxZoneRangeInPoints > 0; - if (result) - { - // - double range = triggerBlock.GetRange(); - result = range <= config.maxZoneRangeInPoints * points; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validate Gap Endup with PinBar ... - result = config.forceHasPinBarEntry; - if (result) - { - // - bool isBullishRejected = - isBullish && - cBar.IsBullish() && - cBar.GetLowShadow() > cBar.GetHighShadow(); - - // - bool isBearishRejected = - isBearish && - cBar.IsBearish() && - cBar.GetLowShadow() < cBar.GetHighShadow(); - - // - result = isBullishRejected || - isBearishRejected; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validating Gap Bar must a Momentum Bar and - // Breakes out Zone's Directional Edge ... - // for Bullish: Upper - // for Bearish: Lower - result = config.forceGapBarsBreakout; - if (result) - { - // - // Gap Bar is PBar ... - - // - // Check Gap Bar is Momentum Bar ... - result = - helper - .barAnalyser - .IsMomentum( - pBar, - iDir // - ); - bool isBullishMomentum = - result && - IsBullish(iDir); - bool isBearishMomentum = - result && - IsBearish(iDir); - - // - // Check Gap Bar's Breakout ... - - // - bool isBullishBreakedout = - isBullish && - pBar.IsBullish() && - isBullishMomentum && - pBar.GetUp() > triggerBlock.upper && - pBar.GetDown() < triggerBlock.upper; - - // - bool isBearishBreakedout = - isBearish && - pBar.IsBearish() && - isBearishMomentum && - pBar.GetUp() > triggerBlock.lower && - pBar.GetDown() < triggerBlock.lower; - - // - result = isBullishBreakedout || - isBearishBreakedout; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validate Zone Has Propper Swing ... - // for Bullish: p2Bar or p3Bar must be a Swing Low ... - // for Bearish: p2Bar or p3Bar must be a Swing High ... - result = config.forceHasSwing; - if (result) - { - // - // p2Bar ... - bool isP2BarSwing = - helper - .barAnalyser - .IsSimpleSwing( - p2Bar, - iDir // - ); - bool isP2BarSwingLow = - isP2BarSwing && - IsBullish(iDir); - bool isP2BarSwingHigh = - isP2BarSwing && - IsBearish(iDir); - - // - // p3Bar ... - bool isP3BarSwing = - helper - .barAnalyser - .IsSimpleSwing( - p3Bar, - iDir // - ); - bool isP3BarSwingLow = - isP3BarSwing && - IsBullish(iDir); - bool isP3BarSwingHigh = - isP3BarSwing && - IsBearish(iDir); - - // - bool hasSwingLow = - isBullish && - (isP2BarSwingLow || - isP3BarSwingLow); - - // - bool hasSwingHigh = - isBearish && - (isP2BarSwingHigh || - isP3BarSwingHigh); - - // - result = - hasSwingLow || - hasSwingHigh; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Validating Using Swing Length ... - result = config.minZoneLength > 0; - if (result) - { - // - XOHCL fromBar; - has = triggerBlock.FromBar(fromBar); - if (result) - { - // - // Retrieve HH and LL ... - ll = fromBar.FindLowest(config.minZoneLength, MODE_LOW); - hh = fromBar.FindHighest(config.minZoneLength, MODE_HIGH); - - // - // Validate Using HH and LL ... - - // - bool isBullishValid = - isBullish && - ll >= triggerBlock.lower; - - // - bool isBearishValid = - isBearish && - hh <= triggerBlock.upper; - - // - result = isBullishValid || - isBearishValid; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - - // - // Update Zone's From Time ... - triggerBlock.from = GetBarTime( - triggerBlock.symbol, - triggerBlock.period, - fromBar.Index() + config.minZoneLength // - ); - } - - // - fromBar.Clean(); - } - - // - // Validate Max Allowed Entry Distance ... - result = config.maxAllowedEntryDistance > 0; - if (result) - { - // - double base = - isBullish - ? triggerBlock.upper - : triggerBlock.lower; - double entryDistance = MathAbs(zBar.open - base); - result = entryDistance <= config.maxAllowedEntryDistance * points; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // Here we Ensure which have a Valid Zone using Different Applied Validations ... - // from now we are Going to Filterd Validate Zones ... - - // - // Check Exists Filters or not ... - result = config.filterBasedOnSar || - config.filterBasedOnRSI || - config.filterBasedOnADX || - config.filterBasedOnTrend; - if (result) - { - // - // Do Apply Several Exists Filters ... - - // - // SAR Filter ... - if (config.filterBasedOnSar) - { - // - // Reading Conditions Values ... - - // - 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]; - double p4Sar = conditions.sarBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - bool isZSarBullish = zSar < zBar.low; - bool isZSarBearish = zSar > zBar.high; - - // - bool isCSarBullish = cSar < cBar.low; - bool isCSarBearish = cSar > cBar.high; - - // - bool isPSarBullish = pSar < pBar.low; - bool isPSarBearish = pSar > pBar.high; - - // - bool isP2SarBullish = p2Sar < p2Bar.low; - bool isP2SarBearish = p2Sar > p2Bar.high; - - // - bool isCSarSwitchedToBullish = - isZSarBullish && - isCSarBullish && - !isPSarBullish && - cBar.IsBullish() && - cBar.GetUp() > pSar; - - // - bool isCSarSwitchedToBearish = - isZSarBearish && - isCSarBearish && - !isPSarBearish && - cBar.IsBearish() && - cBar.GetDown() < pSar; - - // - bool isPSarSwitchedToBullish = - isZSarBullish && - isCSarBullish && - isPSarBullish && - !isP2SarBullish && - pBar.IsBullish() && - pBar.GetUp() > p2Sar; - - // - bool isPSarSwitchedToBearish = - isZSarBearish && - isCSarBearish && - isPSarBearish && - !isP2SarBearish && - pBar.IsBearish() && - pBar.GetDown() < p2Sar; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - (isCSarSwitchedToBullish || - isPSarSwitchedToBullish); - - // - bool isBearishFilterd = - isBearish && - (isCSarSwitchedToBearish || - isPSarSwitchedToBearish); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // RSI Filter ... - if (config.filterBasedOnRSI) - { - // - // Reading Conditions Values ... - - // - double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2; - - // - double zRSI = conditions.rsiBuffer[zIDX]; - double cRSI = conditions.rsiBuffer[cIDX]; - double pRSI = conditions.rsiBuffer[pIDX]; - double p2RSI = conditions.rsiBuffer[p2IDX]; - double p3RSI = conditions.rsiBuffer[p3IDX]; - double p4RSI = conditions.rsiBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - bool isZRSIBullish = zRSI > rsiTrend; - bool isZRSIBearish = zRSI < rsiTrend; - - // - bool isCRSIBullish = cRSI > rsiTrend; - bool isCRSIBearish = cRSI < rsiTrend; - - // - bool isPRSIBullish = pRSI > rsiTrend; - bool isPRSIBearish = pRSI < rsiTrend; - - // - bool isP2RSIBullish = p2RSI > rsiTrend; - bool isP2RSIBearish = p2RSI < rsiTrend; - - // - bool isP3RSIBullish = p3RSI > rsiTrend; - bool isP3RSIBearish = p3RSI < rsiTrend; - - // - // Trending Conditions ... - - // - bool isCRSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - !isPRSIBullish; - - // - bool isCRSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - !isPRSIBearish; - - // - bool isPRSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - isPRSIBullish && - !isP2RSIBullish; - - // - bool isPRSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - isPRSIBearish && - !isP2RSIBearish; - - // - bool isP2RSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - isPRSIBullish && - isP2RSIBullish && - !isP3RSIBullish; - - // - bool isP2RSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - isPRSIBearish && - isP2RSIBearish && - !isP3RSIBearish; - - // - // Crosses Conditions ... - - // - bool isCBarCrossedOverOS = - zRSI > conditions.rsiOSLevel && - cRSI > conditions.rsiOSLevel && - pRSI <= conditions.rsiOSLevel; - - // - bool isCBarCrossedUnderOB = - zRSI < conditions.rsiOBLevel && - cRSI < conditions.rsiOBLevel && - pRSI >= conditions.rsiOBLevel; - - // - bool isPBarCrossedOverOS = - zRSI > conditions.rsiOSLevel && - cRSI > conditions.rsiOSLevel && - pRSI > conditions.rsiOSLevel && - p2RSI <= conditions.rsiOSLevel; - - // - bool isPBarCrossedUnderOB = - zRSI < conditions.rsiOBLevel && - cRSI < conditions.rsiOBLevel && - pRSI < conditions.rsiOBLevel && - p2RSI >= conditions.rsiOBLevel; - - // - // V Pattern Conditions ... - - // - bool isCRSIHasVBullishPattern = - zRSI >= cRSI && - cRSI > pRSI && - p2RSI > pRSI && - cRSI >= p2RSI; - - // - bool isCRSIHasVBearishPattern = - zRSI <= cRSI && - cRSI < pRSI && - p2RSI < pRSI && - cRSI <= p2RSI; - - // - // Continuation Conditions ... - - // - bool isRSIUp = - zRSI >= cRSI && - (cRSI >= pRSI || - pRSI >= p2RSI || - p2RSI >= p3RSI); - - // - bool isRSIDown = - zRSI <= cRSI && - (cRSI <= pRSI || - pRSI <= p2RSI || - p2RSI <= p3RSI); - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isRSIUp - // - || - // - // Crosses ... - (isCBarCrossedOverOS || - isPBarCrossedOverOS) - // - || - // - // V Pattern ... - isCRSIHasVBullishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBullish || - isPRSISwitchedToBullish || - isP2RSISwitchedToBullish) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isRSIDown - // - || - // - // Crosses ... - (isCBarCrossedUnderOB || - isPBarCrossedUnderOB) - // - || - // - // V Pattern ... - isCRSIHasVBearishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBearish || - isPRSISwitchedToBearish || - isP2RSISwitchedToBearish) - // - ); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // ADX Filter ... - if (config.filterBasedOnADX) - { - // - // Reading Conditions Values ... - - // - // ADX ... - double zADX = conditions.adxBuffer[zIDX]; - double cADX = conditions.adxBuffer[cIDX]; - double pADX = conditions.adxBuffer[pIDX]; - double p2ADX = conditions.adxBuffer[p2IDX]; - double p3ADX = conditions.adxBuffer[p3IDX]; - double p4ADX = conditions.adxBuffer[p4IDX]; - - // - // ADX +DI ... - double zADXP = conditions.adxpBuffer[zIDX]; - double cADXP = conditions.adxpBuffer[cIDX]; - double pADXP = conditions.adxpBuffer[pIDX]; - double p2ADXP = conditions.adxpBuffer[p2IDX]; - double p3ADXP = conditions.adxpBuffer[p3IDX]; - double p4ADXP = conditions.adxpBuffer[p4IDX]; - - // - // ADX -DI ... - double zADXN = conditions.adxnBuffer[zIDX]; - double cADXN = conditions.adxnBuffer[cIDX]; - double pADXN = conditions.adxnBuffer[pIDX]; - double p2ADXN = conditions.adxnBuffer[p2IDX]; - double p3ADXN = conditions.adxnBuffer[p3IDX]; - double p4ADXN = conditions.adxnBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - // Grows ... - - // - bool isADXUp = - zADX >= cADX && - (cADX >= pADX || - pADX >= p2ADX); - - // - bool isADXDown = - zADX <= cADX && - (cADX <= pADX || - pADX <= p2ADX); - - // - // Trending ... - - // - bool isZADXBullish = zADX > conditions.adxThreshold; - bool isZADXBearish = zADX < conditions.adxThreshold; - - // - bool isCADXBullish = cADX > conditions.adxThreshold; - bool isCADXBearish = cADX < conditions.adxThreshold; - - // - bool isPADXBullish = pADX > conditions.adxThreshold; - bool isPADXBearish = pADX < conditions.adxThreshold; - - // - bool isP2ADXBullish = p2ADX > conditions.adxThreshold; - bool isP2ADXBearish = p2ADX < conditions.adxThreshold; - - // - bool isP3ADXBullish = p3ADX > conditions.adxThreshold; - bool isP3ADXBearish = p3ADX < conditions.adxThreshold; - - // - bool isP4ADXBullish = p4ADX > conditions.adxThreshold; - bool isP4ADXBearish = p4ADX < conditions.adxThreshold; - - // - bool isCADXSwitchedToBullish = - isZADXBullish && - isCADXBullish && - !isPADXBullish; - - // - bool isCADXSwitchedToBearish = - isZADXBearish && - isCADXBearish && - !isPADXBearish; - - // - bool isPADXSwitchedToBullish = - isZADXBullish && - isCADXBullish && - isPADXBullish && - !isP2ADXBullish; - - // - bool isPADXSwitchedToBearish = - isZADXBearish && - isCADXBearish && - isPADXBearish && - !isP2ADXBearish; - - // - // Powering ... - - // - bool isZADXHasBullishPower = zADXP > zADXN; - bool isZADXHasBearishPower = zADXN > zADXP; - - // - bool isCADXHasBullishPower = cADXP > cADXN; - bool isCADXHasBearishPower = cADXN > cADXP; - - // - bool isPADXHasBullishPower = pADXP > pADXN; - bool isPADXHasBearishPower = pADXN > pADXP; - - // - bool isP2ADXHasBullishPower = p2ADXP > p2ADXN; - bool isP2ADXHasBearishPower = p2ADXN > p2ADXP; - - // - bool isP3ADXHasBullishPower = p3ADXP > p3ADXN; - bool isP3ADXHasBearishPower = p3ADXN > p3ADXP; - - // - bool isP4ADXHasBullishPower = p4ADXP > p4ADXN; - bool isP4ADXHasBearishPower = p4ADXN > p4ADXP; - - // - bool isCADXSwitchedToBullishPower = - isZADXHasBullishPower && - isCADXHasBullishPower && - !isPADXHasBullishPower; - - // - bool isCADXSwitchedToBearishPower = - isZADXHasBearishPower && - isCADXHasBearishPower && - !isPADXHasBearishPower; - - // - bool isPADXSwitchedToBullishPower = - isZADXHasBullishPower && - isCADXHasBullishPower && - isPADXHasBullishPower && - !isP2ADXHasBullishPower; - - // - bool isPADXSwitchedToBearishPower = - isZADXHasBearishPower && - isCADXHasBearishPower && - isPADXHasBearishPower && - !isP2ADXHasBearishPower; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isADXUp - // - || - // - // Trending ... - (isCADXSwitchedToBullish || - isPADXSwitchedToBullish) - // - || - // - // Powering ... - (isCADXSwitchedToBullishPower || - isPADXSwitchedToBullishPower) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isADXDown - // - || - // - // Trending ... - (isCADXSwitchedToBearish || - isPADXSwitchedToBearish) - // - || - // - // Powering ... - (isCADXSwitchedToBearishPower || - isPADXSwitchedToBearishPower) - // - ); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // TREND Filter ... - if (config.filterBasedOnTrend) - { - // - // Reading Conditions Values ... - - // - double zTrend = conditions.trendBuffer[zIDX]; - double cTrend = conditions.trendBuffer[cIDX]; - double pTrend = conditions.trendBuffer[pIDX]; - double p2Trend = conditions.trendBuffer[p2IDX]; - double p3Trend = conditions.trendBuffer[p3IDX]; - double p4Trend = conditions.trendBuffer[p4IDX]; - - // - double trends[] = { - zTrend, - cTrend, - pTrend, - p2Trend, - p3Trend, - p4Trend // - }; - double trendsMin = GetMin(trends); - double trendsMax = GetMax(trends); - double trendsAVG = GetAverage(trends); - - // - double zTrendState = conditions.trendStateBuffer[zIDX]; - double cTrendState = conditions.trendStateBuffer[cIDX]; - double pTrendState = conditions.trendStateBuffer[pIDX]; - double p2TrendState = conditions.trendStateBuffer[p2IDX]; - double p3TrendState = conditions.trendStateBuffer[p3IDX]; - double p4TrendState = conditions.trendStateBuffer[p4IDX]; - - // - // Create Required Conditions ... - - // - // Grows ... - - // - bool isTrendUp = - zTrend >= cTrend && - cTrend >= trendsAVG && - cTrend > trendsMin; - - // - bool isTrendDown = - zTrend <= cTrend && - cTrend <= trendsAVG && - cTrend < trendsMax; - - // - // Stating ... - - // - bool isCTrendBullish = - zTrendState > 0 && - cTrendState > 0; - - // - bool isCTrendBearish = - zTrendState < 0 && - cTrendState < 0; - - // - bool isPTrendBullish = - zTrendState > 0 && - cTrendState > 0 && - pTrendState > 0; - - // - bool isPTrendBearish = - zTrendState < 0 && - cTrendState < 0 && - pTrendState < 0; - - // - bool isP2TrendBullish = - zTrendState > 0 && - cTrendState > 0 && - pTrendState > 0 && - p2TrendState > 0; - - // - bool isP2TrendBearish = - zTrendState < 0 && - cTrendState < 0 && - pTrendState < 0 && - p2TrendState < 0; - - // - bool isCTrendSwitchedToBullish = - isCTrendBullish && - !isPTrendBullish; - - // - bool isCTrendSwitchedToBearish = - isCTrendBearish && - !isPTrendBearish; - - // - bool isPTrendSwitchedToBullish = - isCTrendBullish && - isPTrendBullish && - !isP2TrendBullish; - - // - bool isPTrendSwitchedToBearish = - isCTrendBearish && - isPTrendBearish && - !isP2TrendBearish; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isTrendUp - // - || - // - // Trend Stating ... - (isCTrendBullish && - isPTrendBullish) - // - || - // - // Switching ... - (isCTrendSwitchedToBullish || - isPTrendSwitchedToBullish) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isTrendDown - // - || - // - // Trend Stating ... - (isCTrendBearish && - isPTrendBearish) - // - || - // - // Switching ... - (isCTrendSwitchedToBearish || - isPTrendSwitchedToBearish) - // - ); - - // - result = - isBullishFilterd || - isBearishFilterd; - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - conditions.Clean(); - triggerBlock.Clean(); - - // - return result; - } - } - - // - // SCORE Filter ... - - // - // VOLUME Filter ... - } - - // - result = triggerBlock.IsValid(); - if (result) - { - // - triggerBlock.type = - isBullish - ? ToString(XCA_TRIGGER_BULL) - : ToString(XCA_TRIGGER_BEAR); - } - - // - // Cleanup Resources ... - - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - if (!result) - { - // - conditions.Clean(); - triggerBlock.Clean(); - } - - // - return result; -} - /** * Detect Trigger Block ... * @@ -2962,7 +246,9 @@ bool DetectTriggerBlock( XCXCAEAHelper *helper, XCAEATriggerBlockConfiguration &config, int bar_index = 0, - int loopback = 10 // + int loopback = 10, + double slAdditionalPoint = 0, + double slATRMultiplier = 0 // ) { // @@ -3025,7 +311,7 @@ bool DetectTriggerBlock( helper .barAnalyser .IsTrigger( - cBar, + zBar, trigger.trigger, trigger.ob, trigger.fvg, @@ -3902,7 +1188,35 @@ bool DetectTriggerBlock( // Attach Configuration if Trigger Block Founded ... if (result) { + // trigger.configuration = config; + + // + // Prepare Trigger Signal ... + if (HasChild(config.targets)) + { + // + // Calculating Additional SL Value for Signals ... + double additionalSL = 0; + if (slATRMultiplier > 0) + { + // + double cATR = trigger.conditions.atrBuffer[cIDX]; + additionalSL += (cATR * slATRMultiplier); + } + if (slAdditionalPoint > 0) + { + additionalSL += (slAdditionalPoint * points); + } + + // + ToSignal( + trigger.trigger, + trigger.signal, + config.targets, + additionalSL // + ); + } } // @@ -3923,7 +1237,8 @@ bool DrawTriggerBlock( XTriggerBlock &trigger, CArrayObj *&objects, XCXCAEAHelper *helper, - datetime to = NULL // + datetime to = NULL, + int rrZoneLength = 10 // ) { // @@ -4115,6 +1430,56 @@ bool DrawTriggerBlock( } } + // + // Draw RR of Signal ... + if (trigger.signal.IsValid() && + rrZoneLength > 0) + { + // + XCRRObject *iRRObj; + iRRObj = new XCRRObject(); + result = iRRObj.Create( + helper.poiDrawer.ChartIdentification(), + helper.poiDrawer.SubWindowIdentification(), + trigger.signal, + rrZoneLength // + ); + if (result) + { + // + int iWidth = 2; + ENUM_LINE_STYLE iStyle = STYLE_SOLID; + + // + iRRObj.TPWidth(iWidth); + iRRObj.SLWidth(iWidth); + iRRObj.EntryWidth(iWidth); + iRRObj.TargetWidth(iWidth); + + // + iRRObj.TPStyle(iStyle); + iRRObj.SLStyle(iStyle); + iRRObj.EntryStyle(iStyle); + iRRObj.TargetStyle(iStyle); + + // + iRRObj.TPColor(clrLime); + iRRObj.SLColor(clrRed); + iRRObj.EntryColor(clrYellow); + iRRObj.TargetColor(clrLightBlue); + + // + objects.Add(iRRObj); + } + ZeroMemory(iRRObj); + + // + if (result) + { + return result; + } + } + // return result; } diff --git a/Documents/BKP/xcaea.trigger.block.lib.old.mq5 b/Documents/BKP/xcaea.trigger.block.lib.old.mq5 new file mode 100644 index 00000000..c3b7877f --- /dev/null +++ b/Documents/BKP/xcaea.trigger.block.lib.old.mq5 @@ -0,0 +1,4122 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XCAEAHelper Lib +// Description: Library for XCAEA Signaller ... +// +// +// 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 Library for XCAEA Helper" +#property strict + +// +// Imports ... +#include "../../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/xcaea.x-poi.detector.class.mq5" +#include "../Helpers/xcaea.helper.mq5" + +// +// Definitions ... +enum ENUM_XCAEA_TIGGER_TYPE +{ + XCA_TRIGGER_NONE, // None + XCA_TRIGGER_BULL, // TriggerBull + XCA_TRIGGER_BEAR, // TriggerBear +}; + +// +bool IsValid(ENUM_XCAEA_TIGGER_TYPE value) +{ + return value != XCA_TRIGGER_NONE; +} + +// +string ToString(ENUM_XCAEA_TIGGER_TYPE value) +{ + return EnumToString(value); +} + +// +ENUM_XCAEA_TIGGER_TYPE GetType(string type) +{ + // + ENUM_XCAEA_TIGGER_TYPE result = XCA_TRIGGER_NONE; + + // + bool isTriggerBull = type == ToString(XCA_TRIGGER_BULL); + bool isTriggerBear = type == ToString(XCA_TRIGGER_BEAR); + + // + if (isTriggerBull) + { + result = XCA_TRIGGER_BULL; + } + else if (isTriggerBear) + { + result = XCA_TRIGGER_BEAR; + } + + // + return result; +} + +// +ENUM_X_DIRECTION GetDirection(ENUM_XCAEA_TIGGER_TYPE value) +{ + return value == XCA_TRIGGER_BULL + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; +} + +// +// Structues ... +struct XCAEATriggerBlockConfiguration +{ + // + // Props ... + + // + // Trigger Detection ... + + // + double maxAllowedRange; // Maximum Allowed Range + int minAllowedBlockEdgeLength; // Minimum Required Block Edge Length + + // + bool forceOBOppositBar; // Force OB to Start by Opposit Bars + bool forceFVGBarType; // Force FVG to Has Same Type of Bars + bool forceGapBarBreakout; // Force FVG's Gap Bar to Breakeout OB Edge Side + bool forceHasSwingBar; // Force Has Propper Swing + bool forceHasLiquidity; // Force Has Following Liquidity Zone + bool forceHasReversalLiquidity; // Force Has Reversal Liquidity Zone + + // + // Validating ... + int minZoneLength; // Minimum Length of Consolidation Zone + bool forceHasSwing; // Force Zone's Has Propper Swing + bool forceHasPinBarEntry; // Force Zone's Ends with a Pin Bar + bool forceGapBarsBreakout; // Force Zone's Gap Bar's Breakes Out + double maxZoneRangeInPoints; // Max Zone Range in Point + double maxAllowedEntryDistance; // Max Allowed Entry Distance + + // + // Filtering ... + bool filterBasedOnSar; // Filter Trigger Block Based on Sar + bool filterBasedOnRSI; // Filter Trigger Block Based on RSI + bool filterBasedOnADX; // Filter Trigger Block Based on ADX + bool filterBasedOnTrend; // Filter Trigger Block Based on Trend + bool filterBasedOnScores; // Filter Trigger Block Based on Scores + bool filterBasedOnVolumes; // Filter Trigger Block Based on Volumes + + // + // Constructor ... + XCAEATriggerBlockConfiguration() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + + // + // Validating ... + minZoneLength = 0; + forceHasSwing = false; + maxZoneRangeInPoints = 0.0; + forceHasPinBarEntry = false; + forceGapBarsBreakout = false; + maxAllowedEntryDistance = 0.0; + + // + // Filtering ... + filterBasedOnSar = false; + filterBasedOnRSI = false; + filterBasedOnADX = false; + filterBasedOnTrend = false; + + // + ZeroMemory(this); + } + + // + // Preset Configurations ... + + // + // Commons Verifications which used in all + // Preset Configurations ... + void ConfigureCommons() + { + // + minZoneLength = 7; + forceHasSwing = true; + maxZoneRangeInPoints = 70; + forceHasPinBarEntry = true; + forceGapBarsBreakout = true; + maxAllowedEntryDistance = 30; + } + + // + // Cleanup Range Verifications ... + void CleanRanges() + { + // + maxZoneRangeInPoints = 0; + maxAllowedEntryDistance = 0; + } + + // + void ConfigureFullFilter() + { + // + // Apply Common Configurations ... + ConfigureCommons(); + + // + // Apply Full Filters ... + filterBasedOnSar = true; + filterBasedOnRSI = true; + filterBasedOnADX = true; + filterBasedOnTrend = true; + } + + // + void ConfigureFullFilterNoRange() + { + // + // Apply Common Configurations ... + ConfigureCommons(); + + // + // Clean Ranges ... + CleanRanges(); + + // + // Apply Full Filters ... + filterBasedOnSar = true; + filterBasedOnRSI = true; + filterBasedOnADX = true; + filterBasedOnTrend = true; + } + + // + void ConfigureSarRsiAdxFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnTrend = false; + } + + // + void ConfigureSarRsiTrendFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnADX = false; + } + + // + void ConfigureSarAdxTrendFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnRSI = false; + } + + // + void ConfigureRsiAdxTrendFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnSar = false; + } + + // + void ConfigureSarRsiFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnADX = false; + filterBasedOnTrend = false; + } + + // + void ConfigureSarAdxFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnRSI = false; + filterBasedOnTrend = false; + } + + // + void ConfigureSarTrendFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnRSI = false; + filterBasedOnADX = false; + } + + // + void ConfigureRsiAdxFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnSar = false; + filterBasedOnTrend = false; + } + + // + void ConfigureRsiTrendFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnSar = false; + filterBasedOnADX = false; + } + + // + void ConfigureAdxTrendFilter() + { + // + ConfigureFullFilter(); + + // + filterBasedOnSar = false; + filterBasedOnRSI = false; + } + + // +}; + +// +struct XTriggerBlock +{ + // + // Props ... + XBoxZone ob; // Order Block + XBoxZone fvg; // Fair Value Gap + XOHCL swingBar; // Swing of Trigger + XBoxZone trigger; // Trigger Block + XBoxZone rLiquidity; // Reversal Liquidity + XBoxZone fLiquidity; // Following Liquidity + XCAEAConditions conditions; // Market Conditions + XCAEATriggerBlockConfiguration configuration; // Detection Configuration + + // + // Constructor ... + XTriggerBlock() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + ob.Clean(); + fvg.Clean(); + trigger.Clean(); + swingBar.Clean(); + rLiquidity.Clean(); + fLiquidity.Clean(); + conditions.Clean(); + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = ob.IsValid() && + fvg.IsValid() && + trigger.IsValid(); + + // + return result; + } + + // +}; + +// +// Extensions ... + +/** + * Detect a Trigger Block ... + * + * @param triggerBlock: XBoxZone instance reference, The Detected Trigger Block ... + * @param conditions: XCAEAConditions instance reference, The Block Verification Conditions ... + * @param helper: XCXCAEAHelper instance pointer, Specified The Helper Class Instance which used to Detect Conditions ... + * @param config: XCAEATriggerBlockConfiguration instance reference, Specified The Trigger Block Detection Configuration ... + * @param bar_index: int, Specified The Bar Index to Start Detection ... + * @param loopback: int, Specified The Loopback Length to Detect Helper Conditions ... + * + * @return ( bool ) + */ +bool DetectTriggerBlock( + XBoxZone &triggerBlock, + XCAEAConditions &conditions, + XCXCAEAHelper *helper, + XCAEATriggerBlockConfiguration &config, + int bar_index = 0, + int loopback = 6 // +) +{ + // + bool result = false; + + // + conditions.Clean(); + triggerBlock.Clean(); + + // + // Normalize Args ... + loopback = NormalizeInt(loopback, 6); + bar_index = NormalizeInt(bar_index, 0); + + // + // Validate Args ... + result = helper != NULL; + if (!result) + { + return result; + } + + // + // Provide base Requirements ... + + // + string symbol = helper.GetSymbol(); + double points = GetPoints(symbol); + ENUM_TIMEFRAMES period = helper.GetPeriod(); + + // + // Conditions Reading Indexes ... + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + double ll = 0; + double hh = 0; + bool has = false; + ENUM_X_DIRECTION iDir; + + // + // Retrieve Current Conditions ... + result = helper.GetConditions( + conditions, + bar_index, + loopback // + ); + + // + // Retrieve Required Bars ... + + // + XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... + XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ... + XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ... + XOHCL p2Bar; // Determines FVG's Start Bar in a Block ... + XOHCL p3Bar; // First Verification of Block ... + XOHCL p4Bar; // Seccond Verification of Block ... + + // + result = zBar.Init( + symbol, + period, + bar_index // + ); + result = + result && + zBar.GetPreviousBar(cBar); + result = + result && + cBar.GetPreviousBar(pBar); + result = + result && + pBar.GetPreviousBar(p2Bar); + result = + result && + p2Bar.GetPreviousBar(p3Bar); + result = + result && + p3Bar.GetPreviousBar(p4Bar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + + // + // Detect Based Order Block using CBar ... + result = + helper + .barAnalyser + .IsOB( + cBar, + triggerBlock, + true, // Force FVG Bar Type ... + true // Force Block Two Bar Checking ... + ); + + // + // Ensure a Block is Detected ... + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + + // + // Reading Some Block Based Requirements ... + + // + bool isBullish = + result && + triggerBlock.IsBullish(); + + // + bool isBearish = + result && + triggerBlock.IsBearish(); + + // + int toIDX = triggerBlock.ToIndex(); + int fromIDX = triggerBlock.FromIndex(); + + // + // Start Validating ... + + // + // Validating p2Bar and p3Bar Direction ... + if (result) + { + // + iDir = Opposit(triggerBlock.dir); + + // + result = + iDir == p3Bar.GetDirection() || + iDir == p4Bar.GetDirection(); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validating Using Max Range ... + result = config.maxZoneRangeInPoints > 0; + if (result) + { + // + double range = triggerBlock.GetRange(); + result = range <= config.maxZoneRangeInPoints * points; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validate Gap Endup with PinBar ... + result = config.forceHasPinBarEntry; + if (result) + { + // + bool isBullishRejected = + isBullish && + cBar.IsBullish() && + cBar.GetLowShadow() > cBar.GetHighShadow(); + + // + bool isBearishRejected = + isBearish && + cBar.IsBearish() && + cBar.GetLowShadow() < cBar.GetHighShadow(); + + // + result = isBullishRejected || + isBearishRejected; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validating Gap Bar must a Momentum Bar and + // Breakes out Zone's Directional Edge ... + // for Bullish: Upper + // for Bearish: Lower + result = config.forceGapBarsBreakout; + if (result) + { + // + // Gap Bar is PBar ... + + // + // Check Gap Bar is Momentum Bar ... + result = + helper + .barAnalyser + .IsMomentum( + pBar, + iDir // + ); + bool isBullishMomentum = + result && + IsBullish(iDir); + bool isBearishMomentum = + result && + IsBearish(iDir); + + // + // Check Gap Bar's Breakout ... + + // + bool isBullishBreakedout = + isBullish && + pBar.IsBullish() && + isBullishMomentum && + pBar.GetUp() > triggerBlock.upper && + pBar.GetDown() < triggerBlock.upper; + + // + bool isBearishBreakedout = + isBearish && + pBar.IsBearish() && + isBearishMomentum && + pBar.GetUp() > triggerBlock.lower && + pBar.GetDown() < triggerBlock.lower; + + // + result = isBullishBreakedout || + isBearishBreakedout; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validate Zone Has Propper Swing ... + // for Bullish: p2Bar or p3Bar must be a Swing Low ... + // for Bearish: p2Bar or p3Bar must be a Swing High ... + result = config.forceHasSwing; + if (result) + { + // + // p2Bar ... + bool isP2BarSwing = + helper + .barAnalyser + .IsSimpleSwing( + p2Bar, + iDir // + ); + bool isP2BarSwingLow = + isP2BarSwing && + IsBullish(iDir); + bool isP2BarSwingHigh = + isP2BarSwing && + IsBearish(iDir); + + // + // p3Bar ... + bool isP3BarSwing = + helper + .barAnalyser + .IsSimpleSwing( + p3Bar, + iDir // + ); + bool isP3BarSwingLow = + isP3BarSwing && + IsBullish(iDir); + bool isP3BarSwingHigh = + isP3BarSwing && + IsBearish(iDir); + + // + bool hasSwingLow = + isBullish && + (isP2BarSwingLow || + isP3BarSwingLow); + + // + bool hasSwingHigh = + isBearish && + (isP2BarSwingHigh || + isP3BarSwingHigh); + + // + result = + hasSwingLow || + hasSwingHigh; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validating Using Swing Length ... + result = config.minZoneLength > 0; + if (result) + { + // + XOHCL fromBar; + has = triggerBlock.FromBar(fromBar); + if (result) + { + // + // Retrieve HH and LL ... + ll = fromBar.FindLowest(config.minZoneLength, MODE_LOW); + hh = fromBar.FindHighest(config.minZoneLength, MODE_HIGH); + + // + // Validate Using HH and LL ... + + // + bool isBullishValid = + isBullish && + ll >= triggerBlock.lower; + + // + bool isBearishValid = + isBearish && + hh <= triggerBlock.upper; + + // + result = isBullishValid || + isBearishValid; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + + // + // Update Zone's From Time ... + triggerBlock.from = GetBarTime( + triggerBlock.symbol, + triggerBlock.period, + fromBar.Index() + config.minZoneLength // + ); + } + + // + fromBar.Clean(); + } + + // + // Validate Max Allowed Entry Distance ... + result = config.maxAllowedEntryDistance > 0; + if (result) + { + // + double base = + isBullish + ? triggerBlock.upper + : triggerBlock.lower; + double entryDistance = MathAbs(zBar.open - base); + result = entryDistance <= config.maxAllowedEntryDistance * points; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Here we Ensure which have a Valid Zone using Different Applied Validations ... + // from now we are Going to Filterd Validate Zones ... + + // + // Check Exists Filters or not ... + result = config.filterBasedOnSar || + config.filterBasedOnRSI || + config.filterBasedOnADX || + config.filterBasedOnTrend; + if (result) + { + // + // Do Apply Several Exists Filters ... + + // + // SAR Filter ... + if (config.filterBasedOnSar) + { + // + // Reading Conditions Values ... + + // + 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]; + double p4Sar = conditions.sarBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + bool isZSarBullish = zSar < zBar.low; + bool isZSarBearish = zSar > zBar.high; + + // + bool isCSarBullish = cSar < cBar.low; + bool isCSarBearish = cSar > cBar.high; + + // + bool isPSarBullish = pSar < pBar.low; + bool isPSarBearish = pSar > pBar.high; + + // + bool isP2SarBullish = p2Sar < p2Bar.low; + bool isP2SarBearish = p2Sar > p2Bar.high; + + // + bool isCSarSwitchedToBullish = + isZSarBullish && + isCSarBullish && + !isPSarBullish && + cBar.IsBullish() && + cBar.GetUp() > pSar; + + // + bool isCSarSwitchedToBearish = + isZSarBearish && + isCSarBearish && + !isPSarBearish && + cBar.IsBearish() && + cBar.GetDown() < pSar; + + // + bool isPSarSwitchedToBullish = + isZSarBullish && + isCSarBullish && + isPSarBullish && + !isP2SarBullish && + pBar.IsBullish() && + pBar.GetUp() > p2Sar; + + // + bool isPSarSwitchedToBearish = + isZSarBearish && + isCSarBearish && + isPSarBearish && + !isP2SarBearish && + pBar.IsBearish() && + pBar.GetDown() < p2Sar; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + (isCSarSwitchedToBullish || + isPSarSwitchedToBullish); + + // + bool isBearishFilterd = + isBearish && + (isCSarSwitchedToBearish || + isPSarSwitchedToBearish); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // RSI Filter ... + if (config.filterBasedOnRSI) + { + // + // Reading Conditions Values ... + + // + double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2; + + // + double zRSI = conditions.rsiBuffer[zIDX]; + double cRSI = conditions.rsiBuffer[cIDX]; + double pRSI = conditions.rsiBuffer[pIDX]; + double p2RSI = conditions.rsiBuffer[p2IDX]; + double p3RSI = conditions.rsiBuffer[p3IDX]; + double p4RSI = conditions.rsiBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + bool isZRSIBullish = zRSI > rsiTrend; + bool isZRSIBearish = zRSI < rsiTrend; + + // + bool isCRSIBullish = cRSI > rsiTrend; + bool isCRSIBearish = cRSI < rsiTrend; + + // + bool isPRSIBullish = pRSI > rsiTrend; + bool isPRSIBearish = pRSI < rsiTrend; + + // + bool isP2RSIBullish = p2RSI > rsiTrend; + bool isP2RSIBearish = p2RSI < rsiTrend; + + // + bool isP3RSIBullish = p3RSI > rsiTrend; + bool isP3RSIBearish = p3RSI < rsiTrend; + + // + // Trending Conditions ... + + // + bool isCRSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + !isPRSIBullish; + + // + bool isCRSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + !isPRSIBearish; + + // + bool isPRSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + isPRSIBullish && + !isP2RSIBullish; + + // + bool isPRSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + isPRSIBearish && + !isP2RSIBearish; + + // + bool isP2RSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + isPRSIBullish && + isP2RSIBullish && + !isP3RSIBullish; + + // + bool isP2RSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + isPRSIBearish && + isP2RSIBearish && + !isP3RSIBearish; + + // + // Crosses Conditions ... + + // + bool isCBarCrossedOverOS = + zRSI > conditions.rsiOSLevel && + cRSI > conditions.rsiOSLevel && + pRSI <= conditions.rsiOSLevel; + + // + bool isCBarCrossedUnderOB = + zRSI < conditions.rsiOBLevel && + cRSI < conditions.rsiOBLevel && + pRSI >= conditions.rsiOBLevel; + + // + bool isPBarCrossedOverOS = + zRSI > conditions.rsiOSLevel && + cRSI > conditions.rsiOSLevel && + pRSI > conditions.rsiOSLevel && + p2RSI <= conditions.rsiOSLevel; + + // + bool isPBarCrossedUnderOB = + zRSI < conditions.rsiOBLevel && + cRSI < conditions.rsiOBLevel && + pRSI < conditions.rsiOBLevel && + p2RSI >= conditions.rsiOBLevel; + + // + // V Pattern Conditions ... + + // + bool isCRSIHasVBullishPattern = + zRSI >= cRSI && + cRSI > pRSI && + p2RSI > pRSI && + cRSI >= p2RSI; + + // + bool isCRSIHasVBearishPattern = + zRSI <= cRSI && + cRSI < pRSI && + p2RSI < pRSI && + cRSI <= p2RSI; + + // + // Continuation Conditions ... + + // + bool isRSIUp = + zRSI >= cRSI && + (cRSI >= pRSI || + pRSI >= p2RSI || + p2RSI >= p3RSI); + + // + bool isRSIDown = + zRSI <= cRSI && + (cRSI <= pRSI || + pRSI <= p2RSI || + p2RSI <= p3RSI); + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isRSIUp + // + || + // + // Crosses ... + (isCBarCrossedOverOS || + isPBarCrossedOverOS) + // + || + // + // V Pattern ... + isCRSIHasVBullishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBullish || + isPRSISwitchedToBullish || + isP2RSISwitchedToBullish) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isRSIDown + // + || + // + // Crosses ... + (isCBarCrossedUnderOB || + isPBarCrossedUnderOB) + // + || + // + // V Pattern ... + isCRSIHasVBearishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBearish || + isPRSISwitchedToBearish || + isP2RSISwitchedToBearish) + // + ); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // ADX Filter ... + if (config.filterBasedOnADX) + { + // + // Reading Conditions Values ... + + // + // ADX ... + double zADX = conditions.adxBuffer[zIDX]; + double cADX = conditions.adxBuffer[cIDX]; + double pADX = conditions.adxBuffer[pIDX]; + double p2ADX = conditions.adxBuffer[p2IDX]; + double p3ADX = conditions.adxBuffer[p3IDX]; + double p4ADX = conditions.adxBuffer[p4IDX]; + + // + // ADX +DI ... + double zADXP = conditions.adxpBuffer[zIDX]; + double cADXP = conditions.adxpBuffer[cIDX]; + double pADXP = conditions.adxpBuffer[pIDX]; + double p2ADXP = conditions.adxpBuffer[p2IDX]; + double p3ADXP = conditions.adxpBuffer[p3IDX]; + double p4ADXP = conditions.adxpBuffer[p4IDX]; + + // + // ADX -DI ... + double zADXN = conditions.adxnBuffer[zIDX]; + double cADXN = conditions.adxnBuffer[cIDX]; + double pADXN = conditions.adxnBuffer[pIDX]; + double p2ADXN = conditions.adxnBuffer[p2IDX]; + double p3ADXN = conditions.adxnBuffer[p3IDX]; + double p4ADXN = conditions.adxnBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + // Grows ... + + // + bool isADXUp = + zADX >= cADX && + (cADX >= pADX || + pADX >= p2ADX); + + // + bool isADXDown = + zADX <= cADX && + (cADX <= pADX || + pADX <= p2ADX); + + // + // Trending ... + + // + bool isZADXBullish = zADX > conditions.adxThreshold; + bool isZADXBearish = zADX < conditions.adxThreshold; + + // + bool isCADXBullish = cADX > conditions.adxThreshold; + bool isCADXBearish = cADX < conditions.adxThreshold; + + // + bool isPADXBullish = pADX > conditions.adxThreshold; + bool isPADXBearish = pADX < conditions.adxThreshold; + + // + bool isP2ADXBullish = p2ADX > conditions.adxThreshold; + bool isP2ADXBearish = p2ADX < conditions.adxThreshold; + + // + bool isP3ADXBullish = p3ADX > conditions.adxThreshold; + bool isP3ADXBearish = p3ADX < conditions.adxThreshold; + + // + bool isP4ADXBullish = p4ADX > conditions.adxThreshold; + bool isP4ADXBearish = p4ADX < conditions.adxThreshold; + + // + bool isCADXSwitchedToBullish = + isZADXBullish && + isCADXBullish && + !isPADXBullish; + + // + bool isCADXSwitchedToBearish = + isZADXBearish && + isCADXBearish && + !isPADXBearish; + + // + bool isPADXSwitchedToBullish = + isZADXBullish && + isCADXBullish && + isPADXBullish && + !isP2ADXBullish; + + // + bool isPADXSwitchedToBearish = + isZADXBearish && + isCADXBearish && + isPADXBearish && + !isP2ADXBearish; + + // + // Powering ... + + // + bool isZADXHasBullishPower = zADXP > zADXN; + bool isZADXHasBearishPower = zADXN > zADXP; + + // + bool isCADXHasBullishPower = cADXP > cADXN; + bool isCADXHasBearishPower = cADXN > cADXP; + + // + bool isPADXHasBullishPower = pADXP > pADXN; + bool isPADXHasBearishPower = pADXN > pADXP; + + // + bool isP2ADXHasBullishPower = p2ADXP > p2ADXN; + bool isP2ADXHasBearishPower = p2ADXN > p2ADXP; + + // + bool isP3ADXHasBullishPower = p3ADXP > p3ADXN; + bool isP3ADXHasBearishPower = p3ADXN > p3ADXP; + + // + bool isP4ADXHasBullishPower = p4ADXP > p4ADXN; + bool isP4ADXHasBearishPower = p4ADXN > p4ADXP; + + // + bool isCADXSwitchedToBullishPower = + isZADXHasBullishPower && + isCADXHasBullishPower && + !isPADXHasBullishPower; + + // + bool isCADXSwitchedToBearishPower = + isZADXHasBearishPower && + isCADXHasBearishPower && + !isPADXHasBearishPower; + + // + bool isPADXSwitchedToBullishPower = + isZADXHasBullishPower && + isCADXHasBullishPower && + isPADXHasBullishPower && + !isP2ADXHasBullishPower; + + // + bool isPADXSwitchedToBearishPower = + isZADXHasBearishPower && + isCADXHasBearishPower && + isPADXHasBearishPower && + !isP2ADXHasBearishPower; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isADXUp + // + || + // + // Trending ... + (isCADXSwitchedToBullish || + isPADXSwitchedToBullish) + // + || + // + // Powering ... + (isCADXSwitchedToBullishPower || + isPADXSwitchedToBullishPower) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isADXDown + // + || + // + // Trending ... + (isCADXSwitchedToBearish || + isPADXSwitchedToBearish) + // + || + // + // Powering ... + (isCADXSwitchedToBearishPower || + isPADXSwitchedToBearishPower) + // + ); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // TREND Filter ... + if (config.filterBasedOnTrend) + { + // + // Reading Conditions Values ... + + // + double zTrend = conditions.trendBuffer[zIDX]; + double cTrend = conditions.trendBuffer[cIDX]; + double pTrend = conditions.trendBuffer[pIDX]; + double p2Trend = conditions.trendBuffer[p2IDX]; + double p3Trend = conditions.trendBuffer[p3IDX]; + double p4Trend = conditions.trendBuffer[p4IDX]; + + // + double trends[] = { + zTrend, + cTrend, + pTrend, + p2Trend, + p3Trend, + p4Trend // + }; + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); + + // + double zTrendState = conditions.trendStateBuffer[zIDX]; + double cTrendState = conditions.trendStateBuffer[cIDX]; + double pTrendState = conditions.trendStateBuffer[pIDX]; + double p2TrendState = conditions.trendStateBuffer[p2IDX]; + double p3TrendState = conditions.trendStateBuffer[p3IDX]; + double p4TrendState = conditions.trendStateBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + // Grows ... + + // + bool isTrendUp = + zTrend >= cTrend && + cTrend >= trendsAVG && + cTrend > trendsMin; + + // + bool isTrendDown = + zTrend <= cTrend && + cTrend <= trendsAVG && + cTrend < trendsMax; + + // + // Stating ... + + // + bool isCTrendBullish = + zTrendState > 0 && + cTrendState > 0; + + // + bool isCTrendBearish = + zTrendState < 0 && + cTrendState < 0; + + // + bool isPTrendBullish = + zTrendState > 0 && + cTrendState > 0 && + pTrendState > 0; + + // + bool isPTrendBearish = + zTrendState < 0 && + cTrendState < 0 && + pTrendState < 0; + + // + bool isP2TrendBullish = + zTrendState > 0 && + cTrendState > 0 && + pTrendState > 0 && + p2TrendState > 0; + + // + bool isP2TrendBearish = + zTrendState < 0 && + cTrendState < 0 && + pTrendState < 0 && + p2TrendState < 0; + + // + bool isCTrendSwitchedToBullish = + isCTrendBullish && + !isPTrendBullish; + + // + bool isCTrendSwitchedToBearish = + isCTrendBearish && + !isPTrendBearish; + + // + bool isPTrendSwitchedToBullish = + isCTrendBullish && + isPTrendBullish && + !isP2TrendBullish; + + // + bool isPTrendSwitchedToBearish = + isCTrendBearish && + isPTrendBearish && + !isP2TrendBearish; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isTrendUp + // + || + // + // Trend Stating ... + (isCTrendBullish && + isPTrendBullish) + // + || + // + // Switching ... + (isCTrendSwitchedToBullish || + isPTrendSwitchedToBullish) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isTrendDown + // + || + // + // Trend Stating ... + (isCTrendBearish && + isPTrendBearish) + // + || + // + // Switching ... + (isCTrendSwitchedToBearish || + isPTrendSwitchedToBearish) + // + ); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // SCORE Filter ... + + // + // VOLUME Filter ... + } + + // + result = triggerBlock.IsValid(); + if (result) + { + // + triggerBlock.type = + isBullish + ? ToString(XCA_TRIGGER_BULL) + : ToString(XCA_TRIGGER_BEAR); + } + + // + // Cleanup Resources ... + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + if (!result) + { + // + conditions.Clean(); + triggerBlock.Clean(); + } + + // + return result; +}; + +bool DetectTriggerBlock1( + XBoxZone &triggerBlock, + XCAEAConditions &conditions, + XCXCAEAHelper *helper, + XCAEATriggerBlockConfiguration &config, + int bar_index = 0, + int loopback = 6 // +) +{ + // + bool result = false; + + // + conditions.Clean(); + triggerBlock.Clean(); + + // + // Normalize Args ... + loopback = NormalizeInt(loopback, 6); + bar_index = NormalizeInt(bar_index, 0); + + // + // Validate Args ... + result = helper != NULL; + if (!result) + { + return result; + } + + // + // Provide base Requirements ... + + // + string symbol = helper.GetSymbol(); + double points = GetPoints(symbol); + ENUM_TIMEFRAMES period = helper.GetPeriod(); + + // + // Conditions Reading Indexes ... + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + double ll = 0; + double hh = 0; + bool has = false; + ENUM_X_DIRECTION iDir; + + // + // Retrieve Current Conditions ... + result = helper.GetConditions( + conditions, + bar_index, + loopback // + ); + + // + // Retrieve Required Bars ... + + // + XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... + XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ... + XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ... + XOHCL p2Bar; // Determines FVG's Start Bar in a Block ... + XOHCL p3Bar; // First Verification of Block ... + XOHCL p4Bar; // Seccond Verification of Block ... + + // + result = zBar.Init( + symbol, + period, + bar_index // + ); + result = + result && + zBar.GetPreviousBar(cBar); + result = + result && + cBar.GetPreviousBar(pBar); + result = + result && + pBar.GetPreviousBar(p2Bar); + result = + result && + p2Bar.GetPreviousBar(p3Bar); + result = + result && + p3Bar.GetPreviousBar(p4Bar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + + // + // Detect Based Order Block using CBar ... + result = + helper + .barAnalyser + .IsOB( + cBar, + triggerBlock, + true, // Force FVG Bar Type ... + true // Force Block Two Bar Checking ... + ); + + // + // Ensure a Block is Detected ... + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + return result; + + // + // Reading Some Block Based Requirements ... + + // + bool isBullish = + result && + triggerBlock.IsBullish(); + + // + bool isBearish = + result && + triggerBlock.IsBearish(); + + // + int toIDX = triggerBlock.ToIndex(); + int fromIDX = triggerBlock.FromIndex(); + + // + // Start Validating ... + + // + // Validating p2Bar and p3Bar Direction ... + if (result) + { + // + iDir = Opposit(triggerBlock.dir); + + // + result = + iDir == p3Bar.GetDirection() || + iDir == p4Bar.GetDirection(); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validating Using Max Range ... + result = config.maxZoneRangeInPoints > 0; + if (result) + { + // + double range = triggerBlock.GetRange(); + result = range <= config.maxZoneRangeInPoints * points; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validate Gap Endup with PinBar ... + result = config.forceHasPinBarEntry; + if (result) + { + // + bool isBullishRejected = + isBullish && + cBar.IsBullish() && + cBar.GetLowShadow() > cBar.GetHighShadow(); + + // + bool isBearishRejected = + isBearish && + cBar.IsBearish() && + cBar.GetLowShadow() < cBar.GetHighShadow(); + + // + result = isBullishRejected || + isBearishRejected; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validating Gap Bar must a Momentum Bar and + // Breakes out Zone's Directional Edge ... + // for Bullish: Upper + // for Bearish: Lower + result = config.forceGapBarsBreakout; + if (result) + { + // + // Gap Bar is PBar ... + + // + // Check Gap Bar is Momentum Bar ... + result = + helper + .barAnalyser + .IsMomentum( + pBar, + iDir // + ); + bool isBullishMomentum = + result && + IsBullish(iDir); + bool isBearishMomentum = + result && + IsBearish(iDir); + + // + // Check Gap Bar's Breakout ... + + // + bool isBullishBreakedout = + isBullish && + pBar.IsBullish() && + isBullishMomentum && + pBar.GetUp() > triggerBlock.upper && + pBar.GetDown() < triggerBlock.upper; + + // + bool isBearishBreakedout = + isBearish && + pBar.IsBearish() && + isBearishMomentum && + pBar.GetUp() > triggerBlock.lower && + pBar.GetDown() < triggerBlock.lower; + + // + result = isBullishBreakedout || + isBearishBreakedout; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validate Zone Has Propper Swing ... + // for Bullish: p2Bar or p3Bar must be a Swing Low ... + // for Bearish: p2Bar or p3Bar must be a Swing High ... + result = config.forceHasSwing; + if (result) + { + // + // p2Bar ... + bool isP2BarSwing = + helper + .barAnalyser + .IsSimpleSwing( + p2Bar, + iDir // + ); + bool isP2BarSwingLow = + isP2BarSwing && + IsBullish(iDir); + bool isP2BarSwingHigh = + isP2BarSwing && + IsBearish(iDir); + + // + // p3Bar ... + bool isP3BarSwing = + helper + .barAnalyser + .IsSimpleSwing( + p3Bar, + iDir // + ); + bool isP3BarSwingLow = + isP3BarSwing && + IsBullish(iDir); + bool isP3BarSwingHigh = + isP3BarSwing && + IsBearish(iDir); + + // + bool hasSwingLow = + isBullish && + (isP2BarSwingLow || + isP3BarSwingLow); + + // + bool hasSwingHigh = + isBearish && + (isP2BarSwingHigh || + isP3BarSwingHigh); + + // + result = + hasSwingLow || + hasSwingHigh; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Validating Using Swing Length ... + result = config.minZoneLength > 0; + if (result) + { + // + XOHCL fromBar; + has = triggerBlock.FromBar(fromBar); + if (result) + { + // + // Retrieve HH and LL ... + ll = fromBar.FindLowest(config.minZoneLength, MODE_LOW); + hh = fromBar.FindHighest(config.minZoneLength, MODE_HIGH); + + // + // Validate Using HH and LL ... + + // + bool isBullishValid = + isBullish && + ll >= triggerBlock.lower; + + // + bool isBearishValid = + isBearish && + hh <= triggerBlock.upper; + + // + result = isBullishValid || + isBearishValid; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + + // + // Update Zone's From Time ... + triggerBlock.from = GetBarTime( + triggerBlock.symbol, + triggerBlock.period, + fromBar.Index() + config.minZoneLength // + ); + } + + // + fromBar.Clean(); + } + + // + // Validate Max Allowed Entry Distance ... + result = config.maxAllowedEntryDistance > 0; + if (result) + { + // + double base = + isBullish + ? triggerBlock.upper + : triggerBlock.lower; + double entryDistance = MathAbs(zBar.open - base); + result = entryDistance <= config.maxAllowedEntryDistance * points; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // Here we Ensure which have a Valid Zone using Different Applied Validations ... + // from now we are Going to Filterd Validate Zones ... + + // + // Check Exists Filters or not ... + result = config.filterBasedOnSar || + config.filterBasedOnRSI || + config.filterBasedOnADX || + config.filterBasedOnTrend; + if (result) + { + // + // Do Apply Several Exists Filters ... + + // + // SAR Filter ... + if (config.filterBasedOnSar) + { + // + // Reading Conditions Values ... + + // + 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]; + double p4Sar = conditions.sarBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + bool isZSarBullish = zSar < zBar.low; + bool isZSarBearish = zSar > zBar.high; + + // + bool isCSarBullish = cSar < cBar.low; + bool isCSarBearish = cSar > cBar.high; + + // + bool isPSarBullish = pSar < pBar.low; + bool isPSarBearish = pSar > pBar.high; + + // + bool isP2SarBullish = p2Sar < p2Bar.low; + bool isP2SarBearish = p2Sar > p2Bar.high; + + // + bool isCSarSwitchedToBullish = + isZSarBullish && + isCSarBullish && + !isPSarBullish && + cBar.IsBullish() && + cBar.GetUp() > pSar; + + // + bool isCSarSwitchedToBearish = + isZSarBearish && + isCSarBearish && + !isPSarBearish && + cBar.IsBearish() && + cBar.GetDown() < pSar; + + // + bool isPSarSwitchedToBullish = + isZSarBullish && + isCSarBullish && + isPSarBullish && + !isP2SarBullish && + pBar.IsBullish() && + pBar.GetUp() > p2Sar; + + // + bool isPSarSwitchedToBearish = + isZSarBearish && + isCSarBearish && + isPSarBearish && + !isP2SarBearish && + pBar.IsBearish() && + pBar.GetDown() < p2Sar; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + (isCSarSwitchedToBullish || + isPSarSwitchedToBullish); + + // + bool isBearishFilterd = + isBearish && + (isCSarSwitchedToBearish || + isPSarSwitchedToBearish); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // RSI Filter ... + if (config.filterBasedOnRSI) + { + // + // Reading Conditions Values ... + + // + double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2; + + // + double zRSI = conditions.rsiBuffer[zIDX]; + double cRSI = conditions.rsiBuffer[cIDX]; + double pRSI = conditions.rsiBuffer[pIDX]; + double p2RSI = conditions.rsiBuffer[p2IDX]; + double p3RSI = conditions.rsiBuffer[p3IDX]; + double p4RSI = conditions.rsiBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + bool isZRSIBullish = zRSI > rsiTrend; + bool isZRSIBearish = zRSI < rsiTrend; + + // + bool isCRSIBullish = cRSI > rsiTrend; + bool isCRSIBearish = cRSI < rsiTrend; + + // + bool isPRSIBullish = pRSI > rsiTrend; + bool isPRSIBearish = pRSI < rsiTrend; + + // + bool isP2RSIBullish = p2RSI > rsiTrend; + bool isP2RSIBearish = p2RSI < rsiTrend; + + // + bool isP3RSIBullish = p3RSI > rsiTrend; + bool isP3RSIBearish = p3RSI < rsiTrend; + + // + // Trending Conditions ... + + // + bool isCRSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + !isPRSIBullish; + + // + bool isCRSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + !isPRSIBearish; + + // + bool isPRSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + isPRSIBullish && + !isP2RSIBullish; + + // + bool isPRSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + isPRSIBearish && + !isP2RSIBearish; + + // + bool isP2RSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + isPRSIBullish && + isP2RSIBullish && + !isP3RSIBullish; + + // + bool isP2RSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + isPRSIBearish && + isP2RSIBearish && + !isP3RSIBearish; + + // + // Crosses Conditions ... + + // + bool isCBarCrossedOverOS = + zRSI > conditions.rsiOSLevel && + cRSI > conditions.rsiOSLevel && + pRSI <= conditions.rsiOSLevel; + + // + bool isCBarCrossedUnderOB = + zRSI < conditions.rsiOBLevel && + cRSI < conditions.rsiOBLevel && + pRSI >= conditions.rsiOBLevel; + + // + bool isPBarCrossedOverOS = + zRSI > conditions.rsiOSLevel && + cRSI > conditions.rsiOSLevel && + pRSI > conditions.rsiOSLevel && + p2RSI <= conditions.rsiOSLevel; + + // + bool isPBarCrossedUnderOB = + zRSI < conditions.rsiOBLevel && + cRSI < conditions.rsiOBLevel && + pRSI < conditions.rsiOBLevel && + p2RSI >= conditions.rsiOBLevel; + + // + // V Pattern Conditions ... + + // + bool isCRSIHasVBullishPattern = + zRSI >= cRSI && + cRSI > pRSI && + p2RSI > pRSI && + cRSI >= p2RSI; + + // + bool isCRSIHasVBearishPattern = + zRSI <= cRSI && + cRSI < pRSI && + p2RSI < pRSI && + cRSI <= p2RSI; + + // + // Continuation Conditions ... + + // + bool isRSIUp = + zRSI >= cRSI && + (cRSI >= pRSI || + pRSI >= p2RSI || + p2RSI >= p3RSI); + + // + bool isRSIDown = + zRSI <= cRSI && + (cRSI <= pRSI || + pRSI <= p2RSI || + p2RSI <= p3RSI); + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isRSIUp + // + || + // + // Crosses ... + (isCBarCrossedOverOS || + isPBarCrossedOverOS) + // + || + // + // V Pattern ... + isCRSIHasVBullishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBullish || + isPRSISwitchedToBullish || + isP2RSISwitchedToBullish) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isRSIDown + // + || + // + // Crosses ... + (isCBarCrossedUnderOB || + isPBarCrossedUnderOB) + // + || + // + // V Pattern ... + isCRSIHasVBearishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBearish || + isPRSISwitchedToBearish || + isP2RSISwitchedToBearish) + // + ); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // ADX Filter ... + if (config.filterBasedOnADX) + { + // + // Reading Conditions Values ... + + // + // ADX ... + double zADX = conditions.adxBuffer[zIDX]; + double cADX = conditions.adxBuffer[cIDX]; + double pADX = conditions.adxBuffer[pIDX]; + double p2ADX = conditions.adxBuffer[p2IDX]; + double p3ADX = conditions.adxBuffer[p3IDX]; + double p4ADX = conditions.adxBuffer[p4IDX]; + + // + // ADX +DI ... + double zADXP = conditions.adxpBuffer[zIDX]; + double cADXP = conditions.adxpBuffer[cIDX]; + double pADXP = conditions.adxpBuffer[pIDX]; + double p2ADXP = conditions.adxpBuffer[p2IDX]; + double p3ADXP = conditions.adxpBuffer[p3IDX]; + double p4ADXP = conditions.adxpBuffer[p4IDX]; + + // + // ADX -DI ... + double zADXN = conditions.adxnBuffer[zIDX]; + double cADXN = conditions.adxnBuffer[cIDX]; + double pADXN = conditions.adxnBuffer[pIDX]; + double p2ADXN = conditions.adxnBuffer[p2IDX]; + double p3ADXN = conditions.adxnBuffer[p3IDX]; + double p4ADXN = conditions.adxnBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + // Grows ... + + // + bool isADXUp = + zADX >= cADX && + (cADX >= pADX || + pADX >= p2ADX); + + // + bool isADXDown = + zADX <= cADX && + (cADX <= pADX || + pADX <= p2ADX); + + // + // Trending ... + + // + bool isZADXBullish = zADX > conditions.adxThreshold; + bool isZADXBearish = zADX < conditions.adxThreshold; + + // + bool isCADXBullish = cADX > conditions.adxThreshold; + bool isCADXBearish = cADX < conditions.adxThreshold; + + // + bool isPADXBullish = pADX > conditions.adxThreshold; + bool isPADXBearish = pADX < conditions.adxThreshold; + + // + bool isP2ADXBullish = p2ADX > conditions.adxThreshold; + bool isP2ADXBearish = p2ADX < conditions.adxThreshold; + + // + bool isP3ADXBullish = p3ADX > conditions.adxThreshold; + bool isP3ADXBearish = p3ADX < conditions.adxThreshold; + + // + bool isP4ADXBullish = p4ADX > conditions.adxThreshold; + bool isP4ADXBearish = p4ADX < conditions.adxThreshold; + + // + bool isCADXSwitchedToBullish = + isZADXBullish && + isCADXBullish && + !isPADXBullish; + + // + bool isCADXSwitchedToBearish = + isZADXBearish && + isCADXBearish && + !isPADXBearish; + + // + bool isPADXSwitchedToBullish = + isZADXBullish && + isCADXBullish && + isPADXBullish && + !isP2ADXBullish; + + // + bool isPADXSwitchedToBearish = + isZADXBearish && + isCADXBearish && + isPADXBearish && + !isP2ADXBearish; + + // + // Powering ... + + // + bool isZADXHasBullishPower = zADXP > zADXN; + bool isZADXHasBearishPower = zADXN > zADXP; + + // + bool isCADXHasBullishPower = cADXP > cADXN; + bool isCADXHasBearishPower = cADXN > cADXP; + + // + bool isPADXHasBullishPower = pADXP > pADXN; + bool isPADXHasBearishPower = pADXN > pADXP; + + // + bool isP2ADXHasBullishPower = p2ADXP > p2ADXN; + bool isP2ADXHasBearishPower = p2ADXN > p2ADXP; + + // + bool isP3ADXHasBullishPower = p3ADXP > p3ADXN; + bool isP3ADXHasBearishPower = p3ADXN > p3ADXP; + + // + bool isP4ADXHasBullishPower = p4ADXP > p4ADXN; + bool isP4ADXHasBearishPower = p4ADXN > p4ADXP; + + // + bool isCADXSwitchedToBullishPower = + isZADXHasBullishPower && + isCADXHasBullishPower && + !isPADXHasBullishPower; + + // + bool isCADXSwitchedToBearishPower = + isZADXHasBearishPower && + isCADXHasBearishPower && + !isPADXHasBearishPower; + + // + bool isPADXSwitchedToBullishPower = + isZADXHasBullishPower && + isCADXHasBullishPower && + isPADXHasBullishPower && + !isP2ADXHasBullishPower; + + // + bool isPADXSwitchedToBearishPower = + isZADXHasBearishPower && + isCADXHasBearishPower && + isPADXHasBearishPower && + !isP2ADXHasBearishPower; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isADXUp + // + || + // + // Trending ... + (isCADXSwitchedToBullish || + isPADXSwitchedToBullish) + // + || + // + // Powering ... + (isCADXSwitchedToBullishPower || + isPADXSwitchedToBullishPower) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isADXDown + // + || + // + // Trending ... + (isCADXSwitchedToBearish || + isPADXSwitchedToBearish) + // + || + // + // Powering ... + (isCADXSwitchedToBearishPower || + isPADXSwitchedToBearishPower) + // + ); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // TREND Filter ... + if (config.filterBasedOnTrend) + { + // + // Reading Conditions Values ... + + // + double zTrend = conditions.trendBuffer[zIDX]; + double cTrend = conditions.trendBuffer[cIDX]; + double pTrend = conditions.trendBuffer[pIDX]; + double p2Trend = conditions.trendBuffer[p2IDX]; + double p3Trend = conditions.trendBuffer[p3IDX]; + double p4Trend = conditions.trendBuffer[p4IDX]; + + // + double trends[] = { + zTrend, + cTrend, + pTrend, + p2Trend, + p3Trend, + p4Trend // + }; + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); + + // + double zTrendState = conditions.trendStateBuffer[zIDX]; + double cTrendState = conditions.trendStateBuffer[cIDX]; + double pTrendState = conditions.trendStateBuffer[pIDX]; + double p2TrendState = conditions.trendStateBuffer[p2IDX]; + double p3TrendState = conditions.trendStateBuffer[p3IDX]; + double p4TrendState = conditions.trendStateBuffer[p4IDX]; + + // + // Create Required Conditions ... + + // + // Grows ... + + // + bool isTrendUp = + zTrend >= cTrend && + cTrend >= trendsAVG && + cTrend > trendsMin; + + // + bool isTrendDown = + zTrend <= cTrend && + cTrend <= trendsAVG && + cTrend < trendsMax; + + // + // Stating ... + + // + bool isCTrendBullish = + zTrendState > 0 && + cTrendState > 0; + + // + bool isCTrendBearish = + zTrendState < 0 && + cTrendState < 0; + + // + bool isPTrendBullish = + zTrendState > 0 && + cTrendState > 0 && + pTrendState > 0; + + // + bool isPTrendBearish = + zTrendState < 0 && + cTrendState < 0 && + pTrendState < 0; + + // + bool isP2TrendBullish = + zTrendState > 0 && + cTrendState > 0 && + pTrendState > 0 && + p2TrendState > 0; + + // + bool isP2TrendBearish = + zTrendState < 0 && + cTrendState < 0 && + pTrendState < 0 && + p2TrendState < 0; + + // + bool isCTrendSwitchedToBullish = + isCTrendBullish && + !isPTrendBullish; + + // + bool isCTrendSwitchedToBearish = + isCTrendBearish && + !isPTrendBearish; + + // + bool isPTrendSwitchedToBullish = + isCTrendBullish && + isPTrendBullish && + !isP2TrendBullish; + + // + bool isPTrendSwitchedToBearish = + isCTrendBearish && + isPTrendBearish && + !isP2TrendBearish; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isTrendUp + // + || + // + // Trend Stating ... + (isCTrendBullish && + isPTrendBullish) + // + || + // + // Switching ... + (isCTrendSwitchedToBullish || + isPTrendSwitchedToBullish) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isTrendDown + // + || + // + // Trend Stating ... + (isCTrendBearish && + isPTrendBearish) + // + || + // + // Switching ... + (isCTrendSwitchedToBearish || + isPTrendSwitchedToBearish) + // + ); + + // + result = + isBullishFilterd || + isBearishFilterd; + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + conditions.Clean(); + triggerBlock.Clean(); + + // + return result; + } + } + + // + // SCORE Filter ... + + // + // VOLUME Filter ... + } + + // + result = triggerBlock.IsValid(); + if (result) + { + // + triggerBlock.type = + isBullish + ? ToString(XCA_TRIGGER_BULL) + : ToString(XCA_TRIGGER_BEAR); + } + + // + // Cleanup Resources ... + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + if (!result) + { + // + conditions.Clean(); + triggerBlock.Clean(); + } + + // + return result; +} + +/** + * Detect Trigger Block ... + * + * @param trigger: XTriggerBlock instance Reference, hold founded Trigger Block + * @param helper: XCXCAEAHelper instance Reference Pointer, XCAEA Market nalyser Helper for acc Drawer + * @param config: XCAEATriggerBlockConfiguration instance Reference, Trigger Block Detecting Configuration + * @param bar_index: int, Bar Index to Start Detecting + * @param loopback: int, Loopback Bars Count + * + * @return ( bool ) + */ +bool DetectTriggerBlock( + XTriggerBlock &trigger, + XCXCAEAHelper *helper, + XCAEATriggerBlockConfiguration &config, + int bar_index = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Normalize Args ... + trigger.Clean(); + loopback = NormalizeInt(loopback, 10); + bar_index = NormalizeInt(bar_index, 0); + + // + // Validate Args ... + result = helper != NULL; + if (!result) + { + return result; + } + + // + // Extract Required Informations ... + + // + string symbol = helper.GetSymbol(); + ENUM_TIMEFRAMES period = helper.GetPeriod(); + + // + double points = GetPoints(symbol); + + // + // Retrieve Indexed Bar ... + XOHCL zBar; + XOHCL cBar; + XOHCL pBar; + XOHCL p2Bar; + result = zBar.Init( + symbol, + period, + bar_index // + ); + result = result && + zBar.GetPreviousBar(cBar); + result = result && + cBar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + // Check Trigger Block Exists ... + result = + result && + helper + .barAnalyser + .IsTrigger( + cBar, + trigger.trigger, + trigger.ob, + trigger.fvg, + trigger.rLiquidity, + trigger.fLiquidity, + trigger.swingBar, + loopback, + config.maxAllowedRange, + config.minAllowedBlockEdgeLength, + config.forceOBOppositBar, + config.forceFVGBarType, + config.forceGapBarBreakout, + config.forceHasSwingBar, + config.forceHasLiquidity, + config.forceHasReversalLiquidity // + ); + + // + // Now we Have to Implement Required Validations ... + + // + bool isBullish = trigger.trigger.IsBullish(); + bool isBearish = trigger.trigger.IsBearish(); + + // + // First Reading Market Conditions ... + result = + result && + helper.GetConditions( + trigger.conditions, + bar_index, + loopback // + ); + + // + // All Custom andAdditional Validations and Filters + // Applied here ... + + // + // SAR Filter ... + if (config.filterBasedOnSar) + { + // + if (result) + { + // + // Reading Values ... + + // + double zSar = trigger.conditions.sarBuffer[zIDX]; + double cSar = trigger.conditions.sarBuffer[cIDX]; + double pSar = trigger.conditions.sarBuffer[pIDX]; + double p2Sar = trigger.conditions.sarBuffer[p2IDX]; + double p3Sar = trigger.conditions.sarBuffer[p3IDX]; + double p4Sar = trigger.conditions.sarBuffer[p4IDX]; + + // + // Preparing Conditions ... + + // + bool isZSarBullish = zSar < zBar.low; + bool isZSarBearish = zSar > zBar.high; + + // + bool isCSarBullish = cSar < cBar.low; + bool isCSarBearish = cSar > cBar.high; + + // + bool isPSarBullish = pSar < pBar.low; + bool isPSarBearish = pSar > pBar.high; + + // + bool isP2SarBullish = p2Sar < p2Bar.low; + bool isP2SarBearish = p2Sar > p2Bar.high; + + // + bool isCSarSwitchedToBullish = + isZSarBullish && + isCSarBullish && + !isPSarBullish && + cBar.IsBullish() && + cBar.GetUp() > pSar; + + // + bool isCSarSwitchedToBearish = + isZSarBearish && + isCSarBearish && + !isPSarBearish && + cBar.IsBearish() && + cBar.GetDown() < pSar; + + // + bool isPSarSwitchedToBullish = + isZSarBullish && + isCSarBullish && + isPSarBullish && + !isP2SarBullish && + pBar.IsBullish() && + pBar.GetUp() > p2Sar; + + // + bool isPSarSwitchedToBearish = + isZSarBearish && + isCSarBearish && + isPSarBearish && + !isP2SarBearish && + pBar.IsBearish() && + pBar.GetDown() < p2Sar; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + (isCSarSwitchedToBullish || + isPSarSwitchedToBullish); + + // + bool isBearishFilterd = + isBearish && + (isCSarSwitchedToBearish || + isPSarSwitchedToBearish); + + // + // Apply Result .... + + // + result = + result && + (isBullishFilterd || + isBearishFilterd); + } + } + + // + // RSI Filter ... + if (config.filterBasedOnRSI) + { + // + if (result) + { + // + // Reading Values ... + + // + double rsiTrend = (trigger.conditions.rsiOBLevel + trigger.conditions.rsiOSLevel) / 2; + + // + double zRSI = trigger.conditions.rsiBuffer[zIDX]; + double cRSI = trigger.conditions.rsiBuffer[cIDX]; + double pRSI = trigger.conditions.rsiBuffer[pIDX]; + double p2RSI = trigger.conditions.rsiBuffer[p2IDX]; + double p3RSI = trigger.conditions.rsiBuffer[p3IDX]; + double p4RSI = trigger.conditions.rsiBuffer[p4IDX]; + + // + // Preparing Conditions ... + + // + bool isZRSIBullish = zRSI > rsiTrend; + bool isZRSIBearish = zRSI < rsiTrend; + + // + bool isCRSIBullish = cRSI > rsiTrend; + bool isCRSIBearish = cRSI < rsiTrend; + + // + bool isPRSIBullish = pRSI > rsiTrend; + bool isPRSIBearish = pRSI < rsiTrend; + + // + bool isP2RSIBullish = p2RSI > rsiTrend; + bool isP2RSIBearish = p2RSI < rsiTrend; + + // + bool isP3RSIBullish = p3RSI > rsiTrend; + bool isP3RSIBearish = p3RSI < rsiTrend; + + // + // Trending Conditions ... + + // + bool isCRSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + !isPRSIBullish; + + // + bool isCRSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + !isPRSIBearish; + + // + bool isPRSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + isPRSIBullish && + !isP2RSIBullish; + + // + bool isPRSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + isPRSIBearish && + !isP2RSIBearish; + + // + bool isP2RSISwitchedToBullish = + isZRSIBullish && + isCRSIBullish && + isPRSIBullish && + isP2RSIBullish && + !isP3RSIBullish; + + // + bool isP2RSISwitchedToBearish = + isZRSIBearish && + isCRSIBearish && + isPRSIBearish && + isP2RSIBearish && + !isP3RSIBearish; + + // + // Crosses Conditions ... + + // + bool isCBarCrossedOverOS = + zRSI > trigger.conditions.rsiOSLevel && + cRSI > trigger.conditions.rsiOSLevel && + pRSI <= trigger.conditions.rsiOSLevel; + + // + bool isCBarCrossedUnderOB = + zRSI < trigger.conditions.rsiOBLevel && + cRSI < trigger.conditions.rsiOBLevel && + pRSI >= trigger.conditions.rsiOBLevel; + + // + bool isPBarCrossedOverOS = + zRSI > trigger.conditions.rsiOSLevel && + cRSI > trigger.conditions.rsiOSLevel && + pRSI > trigger.conditions.rsiOSLevel && + p2RSI <= trigger.conditions.rsiOSLevel; + + // + bool isPBarCrossedUnderOB = + zRSI < trigger.conditions.rsiOBLevel && + cRSI < trigger.conditions.rsiOBLevel && + pRSI < trigger.conditions.rsiOBLevel && + p2RSI >= trigger.conditions.rsiOBLevel; + + // + // V Pattern Conditions ... + + // + bool isCRSIHasVBullishPattern = + zRSI >= cRSI && + cRSI > pRSI && + p2RSI > pRSI && + cRSI >= p2RSI; + + // + bool isCRSIHasVBearishPattern = + zRSI <= cRSI && + cRSI < pRSI && + p2RSI < pRSI && + cRSI <= p2RSI; + + // + // Continuation Conditions ... + + // + bool isRSIUp = + zRSI >= cRSI && + (cRSI >= pRSI || + pRSI >= p2RSI || + p2RSI >= p3RSI); + + // + bool isRSIDown = + zRSI <= cRSI && + (cRSI <= pRSI || + pRSI <= p2RSI || + p2RSI <= p3RSI); + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isRSIUp + // + || + // + // Crosses ... + (isCBarCrossedOverOS || + isPBarCrossedOverOS) + // + || + // + // V Pattern ... + isCRSIHasVBullishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBullish || + isPRSISwitchedToBullish || + isP2RSISwitchedToBullish) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isRSIDown + // + || + // + // Crosses ... + (isCBarCrossedUnderOB || + isPBarCrossedUnderOB) + // + || + // + // V Pattern ... + isCRSIHasVBearishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBearish || + isPRSISwitchedToBearish || + isP2RSISwitchedToBearish) + // + ); + + // + // Apply Result .... + + // + result = + result && + (isBullishFilterd || + isBearishFilterd); + } + } + + // + // ADX Filter ... + if (config.filterBasedOnADX) + { + // + if (result) + { + // + // Reading Values ... + + // + // ADX ... + double zADX = trigger.conditions.adxBuffer[zIDX]; + double cADX = trigger.conditions.adxBuffer[cIDX]; + double pADX = trigger.conditions.adxBuffer[pIDX]; + double p2ADX = trigger.conditions.adxBuffer[p2IDX]; + double p3ADX = trigger.conditions.adxBuffer[p3IDX]; + double p4ADX = trigger.conditions.adxBuffer[p4IDX]; + + // + // ADX +DI ... + double zADXP = trigger.conditions.adxpBuffer[zIDX]; + double cADXP = trigger.conditions.adxpBuffer[cIDX]; + double pADXP = trigger.conditions.adxpBuffer[pIDX]; + double p2ADXP = trigger.conditions.adxpBuffer[p2IDX]; + double p3ADXP = trigger.conditions.adxpBuffer[p3IDX]; + double p4ADXP = trigger.conditions.adxpBuffer[p4IDX]; + + // + // ADX -DI ... + double zADXN = trigger.conditions.adxnBuffer[zIDX]; + double cADXN = trigger.conditions.adxnBuffer[cIDX]; + double pADXN = trigger.conditions.adxnBuffer[pIDX]; + double p2ADXN = trigger.conditions.adxnBuffer[p2IDX]; + double p3ADXN = trigger.conditions.adxnBuffer[p3IDX]; + double p4ADXN = trigger.conditions.adxnBuffer[p4IDX]; + + // + // Preparing Conditions ... + + // + // Grows ... + + // + bool isADXUp = + zADX >= cADX && + (cADX >= pADX || + pADX >= p2ADX); + + // + bool isADXDown = + zADX <= cADX && + (cADX <= pADX || + pADX <= p2ADX); + + // + // Trending ... + + // + bool isZADXBullish = zADX > trigger.conditions.adxThreshold; + bool isZADXBearish = zADX < trigger.conditions.adxThreshold; + + // + bool isCADXBullish = cADX > trigger.conditions.adxThreshold; + bool isCADXBearish = cADX < trigger.conditions.adxThreshold; + + // + bool isPADXBullish = pADX > trigger.conditions.adxThreshold; + bool isPADXBearish = pADX < trigger.conditions.adxThreshold; + + // + bool isP2ADXBullish = p2ADX > trigger.conditions.adxThreshold; + bool isP2ADXBearish = p2ADX < trigger.conditions.adxThreshold; + + // + bool isP3ADXBullish = p3ADX > trigger.conditions.adxThreshold; + bool isP3ADXBearish = p3ADX < trigger.conditions.adxThreshold; + + // + bool isP4ADXBullish = p4ADX > trigger.conditions.adxThreshold; + bool isP4ADXBearish = p4ADX < trigger.conditions.adxThreshold; + + // + bool isCADXSwitchedToBullish = + isZADXBullish && + isCADXBullish && + !isPADXBullish; + + // + bool isCADXSwitchedToBearish = + isZADXBearish && + isCADXBearish && + !isPADXBearish; + + // + bool isPADXSwitchedToBullish = + isZADXBullish && + isCADXBullish && + isPADXBullish && + !isP2ADXBullish; + + // + bool isPADXSwitchedToBearish = + isZADXBearish && + isCADXBearish && + isPADXBearish && + !isP2ADXBearish; + + // + // Powering ... + + // + bool isZADXHasBullishPower = zADXP > zADXN; + bool isZADXHasBearishPower = zADXN > zADXP; + + // + bool isCADXHasBullishPower = cADXP > cADXN; + bool isCADXHasBearishPower = cADXN > cADXP; + + // + bool isPADXHasBullishPower = pADXP > pADXN; + bool isPADXHasBearishPower = pADXN > pADXP; + + // + bool isP2ADXHasBullishPower = p2ADXP > p2ADXN; + bool isP2ADXHasBearishPower = p2ADXN > p2ADXP; + + // + bool isP3ADXHasBullishPower = p3ADXP > p3ADXN; + bool isP3ADXHasBearishPower = p3ADXN > p3ADXP; + + // + bool isP4ADXHasBullishPower = p4ADXP > p4ADXN; + bool isP4ADXHasBearishPower = p4ADXN > p4ADXP; + + // + bool isCADXSwitchedToBullishPower = + isZADXHasBullishPower && + isCADXHasBullishPower && + !isPADXHasBullishPower; + + // + bool isCADXSwitchedToBearishPower = + isZADXHasBearishPower && + isCADXHasBearishPower && + !isPADXHasBearishPower; + + // + bool isPADXSwitchedToBullishPower = + isZADXHasBullishPower && + isCADXHasBullishPower && + isPADXHasBullishPower && + !isP2ADXHasBullishPower; + + // + bool isPADXSwitchedToBearishPower = + isZADXHasBearishPower && + isCADXHasBearishPower && + isPADXHasBearishPower && + !isP2ADXHasBearishPower; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isADXUp + // + || + // + // Trending ... + (isCADXSwitchedToBullish || + isPADXSwitchedToBullish) + // + || + // + // Powering ... + (isCADXSwitchedToBullishPower || + isPADXSwitchedToBullishPower) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isADXDown + // + || + // + // Trending ... + (isCADXSwitchedToBearish || + isPADXSwitchedToBearish) + // + || + // + // Powering ... + (isCADXSwitchedToBearishPower || + isPADXSwitchedToBearishPower) + // + ); + + // + // Apply Result .... + + // + result = + result && + (isBullishFilterd || + isBearishFilterd); + } + } + + // + // TREND Filter ... + if (config.filterBasedOnTrend) + { + // + if (result) + { + // + // Reading Values ... + + // + double zTrend = trigger.conditions.trendBuffer[zIDX]; + double cTrend = trigger.conditions.trendBuffer[cIDX]; + double pTrend = trigger.conditions.trendBuffer[pIDX]; + double p2Trend = trigger.conditions.trendBuffer[p2IDX]; + double p3Trend = trigger.conditions.trendBuffer[p3IDX]; + double p4Trend = trigger.conditions.trendBuffer[p4IDX]; + + // + double trends[] = { + zTrend, + cTrend, + pTrend, + p2Trend, + p3Trend, + p4Trend // + }; + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); + + // + double zTrendState = trigger.conditions.trendStateBuffer[zIDX]; + double cTrendState = trigger.conditions.trendStateBuffer[cIDX]; + double pTrendState = trigger.conditions.trendStateBuffer[pIDX]; + double p2TrendState = trigger.conditions.trendStateBuffer[p2IDX]; + double p3TrendState = trigger.conditions.trendStateBuffer[p3IDX]; + double p4TrendState = trigger.conditions.trendStateBuffer[p4IDX]; + + // + // Preparing Conditions ... + + // + // Grows ... + + // + bool isTrendUp = + zTrend >= cTrend && + cTrend >= trendsAVG && + cTrend > trendsMin; + + // + bool isTrendDown = + zTrend <= cTrend && + cTrend <= trendsAVG && + cTrend < trendsMax; + + // + // Stating ... + + // + bool isCTrendBullish = + zTrendState > 0 && + cTrendState > 0; + + // + bool isCTrendBearish = + zTrendState < 0 && + cTrendState < 0; + + // + bool isPTrendBullish = + zTrendState > 0 && + cTrendState > 0 && + pTrendState > 0; + + // + bool isPTrendBearish = + zTrendState < 0 && + cTrendState < 0 && + pTrendState < 0; + + // + bool isP2TrendBullish = + zTrendState > 0 && + cTrendState > 0 && + pTrendState > 0 && + p2TrendState > 0; + + // + bool isP2TrendBearish = + zTrendState < 0 && + cTrendState < 0 && + pTrendState < 0 && + p2TrendState < 0; + + // + bool isCTrendSwitchedToBullish = + isCTrendBullish && + !isPTrendBullish; + + // + bool isCTrendSwitchedToBearish = + isCTrendBearish && + !isPTrendBearish; + + // + bool isPTrendSwitchedToBullish = + isCTrendBullish && + isPTrendBullish && + !isP2TrendBullish; + + // + bool isPTrendSwitchedToBearish = + isCTrendBearish && + isPTrendBearish && + !isP2TrendBearish; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + ( + // + // Grows ... + isTrendUp + // + || + // + // Trend Stating ... + (isCTrendBullish && + isPTrendBullish) + // + || + // + // Switching ... + (isCTrendSwitchedToBullish || + isPTrendSwitchedToBullish) + // + ); + + // + bool isBearishFilterd = + isBearish && + ( + // + // Grows ... + isTrendDown + // + || + // + // Trend Stating ... + (isCTrendBearish && + isPTrendBearish) + // + || + // + // Switching ... + (isCTrendSwitchedToBearish || + isPTrendSwitchedToBearish) + // + ); + + // + // Apply Result .... + + // + result = + result && + (isBullishFilterd || + isBearishFilterd); + } + } + + // + // SCORE Filter ... + if (config.filterBasedOnScores) + { + // + if (result) + { + // + // Reading Values ... + + // + double bullishScore = 0; + double bearishScore = 0; + + // + trigger.conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + // Preparing Conditions ... + + // + bool isScoreBullish = bullishScore > bearishScore; + bool isScoreBearish = bearishScore > bullishScore; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + isScoreBullish; + + // + bool isBearishFilterd = + isBearish && + isScoreBearish; + + // + // Apply Result .... + + // + result = + result && + (isBullishFilterd || + isBearishFilterd); + } + } + + // + // VOLUME Filter ... + if (config.filterBasedOnVolumes) + { + // + if (result) + { + // + // Reading Values ... + + // + double bullishVolume = 0; + double bearishVolume = 0; + + // + helper + .barAnalyser + .CalculateRangeVolume( + zBar, + bullishVolume, + bearishVolume, + loopback // + ); + + // + // Preparing Conditions ... + + // + bool isVolumeBullish = bullishVolume > bearishVolume; + bool isVolumeBearish = bearishVolume > bullishVolume; + + // + // Summarize Filtering ... + + // + bool isBullishFilterd = + isBullish && + isVolumeBullish; + + // + bool isBearishFilterd = + isBearish && + isVolumeBearish; + + // + // Apply Result .... + + // + result = + result && + (isBullishFilterd || + isBearishFilterd); + } + } + + // + // Cleanup Resources ... + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + if (!result) + { + trigger.Clean(); + } + + // + // Attach Configuration if Trigger Block Founded ... + if (result) + { + trigger.configuration = config; + } + + // + return result; +} + +/** + * Draw Specified Trigger Block ... + * + * @param trigger: XTriggerBlock instance Reference, specified Trigger Block to Draw + * @param objects: CArrayObj instance Reference Pointer, Objects Array for Providing Drawn Objects + * @param helper: XCXCAEAHelper instance Reference Pointer, XCAEA Market nalyser Helper for acc Drawer + * @param to: datetime, specified Time for update Trigger parts + * + * @return ( bool ) + */ +bool DrawTriggerBlock( + XTriggerBlock &trigger, + CArrayObj *&objects, + XCXCAEAHelper *helper, + datetime to = NULL // +) +{ + // + bool result = false; + + // + // Validate Args ... + result = helper != NULL && + trigger.IsValid(); + if (!result) + { + return result; + } + + // + // Update To ... + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + // + trigger.trigger.to = to; + trigger.rLiquidity.to = to; + trigger.fLiquidity.to = to; + } + + // + // Draw OB ... + if (trigger.ob.IsValid()) + { + // + XCBoxObject *iOBObj; + result = helper.poiDrawer.DrawBox( + trigger.ob, + iOBObj // + ); + if (result) + { + objects.Add(iOBObj); + } + ZeroMemory(iOBObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw FVG ... + if (trigger.fvg.IsValid()) + { + // + XCBoxObject *iFVGObj; + result = helper.poiDrawer.DrawBox( + trigger.fvg, + iFVGObj // + ); + if (result) + { + // + // Style Object ... + color clr = + trigger.fvg.IsBullish() + ? clrAqua + : clrMagenta; + iFVGObj.BoxWidth(2); + iFVGObj.BoxColor(clr); + iFVGObj.BoxStyle(STYLE_SOLID); + + // + // Store Object ... + objects.Add(iFVGObj); + } + ZeroMemory(iFVGObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Trigger ... + if (trigger.trigger.IsValid()) + { + // + XCBoxObject *iTriggerObj; + result = helper.poiDrawer.DrawBox( + trigger.trigger, + iTriggerObj // + ); + if (result) + { + objects.Add(iTriggerObj); + } + ZeroMemory(iTriggerObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Liquidities ... + + // + // Reversla Liquidity ... + if (trigger.rLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = helper.poiDrawer.DrawBox( + trigger.rLiquidity, + iLiqObj // + ); + if (result) + { + objects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Following Liquidity ... + if (trigger.fLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = helper.poiDrawer.DrawBox( + trigger.fLiquidity, + iLiqObj // + ); + if (result) + { + objects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Swing Bar ... + if (trigger.swingBar.IsValid()) + { + // + color swingColor = + trigger.fvg.IsBullish() + ? clrAqua + : clrMagenta; + ENUM_X_PRICE swingPType = + trigger.fvg.IsBullish() + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *swingObj; + result = helper.poiDrawer.CreateBarArrow( + trigger.swingBar, + swingObj, + swingPType, + 159, + swingColor // + ); + if (result) + { + objects.Add(swingObj); + } + ZeroMemory(swingObj); + + // + if (!result) + { + return result; + } + } + + // + return result; +} + +// \ No newline at end of file diff --git a/Documents/BKP/xcatb.tm.inputs.mq5 b/Documents/BKP/xcatb.tm.inputs.mq5 new file mode 100644 index 00000000..313c39d3 --- /dev/null +++ b/Documents/BKP/xcatb.tm.inputs.mq5 @@ -0,0 +1,316 @@ +// +// Market ... +ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period +ENUM_TIMEFRAMES scPeriod = NULL; // Short Period +ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period +ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period +ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period +ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period +ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + +// +// Signal ... +int signalR2R = 4; // Risk Reward Ratio +bool drawSignals = true; // Draw Signal +double slAtrMultiplier = 1.0; // ATR Multiplier for SL + +// +// Validating ... +bool forceHasSwing = false; // Force Blocks to Have Swing +bool forceObBarType = false; // Force Block Has Reversal Bar +bool forceOBFVGBarType = false; // Force FVG Has Same Bars +bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +bool validateGapSequence = false; // Validate Block's Gap Sequence +bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +bool filterBasedOnPV = false; // Filter Based on Peak and Vale +bool filterBasedOnSar = false; // Filter Based on Sar +bool filterBasedOnRSI = false; // Filter Based on RSI +bool filterBasedOnADX = false; // Filter Based on ADX +bool filterBasedOnATR = false; // Filter Based on ATR +bool filterBasedOnTrend = false; // Filter Based on Trend +bool filterBasedOnDelta = false; // Filter Based on Delta +bool filterBasedOnVolume = false; // Filter Based on Volume +bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar +bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +string mAlertPrefix = ""; // Alert Prefix +bool _logAlerts = true; // Log Alerts +bool _pushAlerts = false; // Push Alerts +bool _mailAlerts = false; // Mail Alerts +bool _terminalAlerts = true; // Terminal Alerts + +// +// Presentation ... +bool showBars = true; // Show Bars +bool showPV = false; // Show PV +bool showPVGolden = false; // Show PV Golden +bool showSar = false; // Show Sar +bool showTrend = false; // Show Trend +bool showATRBand = false; // Show ATR Band +bool showTrendBars = false; // Show Trend Bars +bool showSignalBars = false; // Show Signal Bars +bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars + +// +int startCalculationForLastBars = 1500; // Calculate Last n Bars + +///////////////////////////////////////////////////////////////// + +// +// Market ... +ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period +ENUM_TIMEFRAMES scPeriod; // Short Period +ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period +ENUM_TIMEFRAMES mcPeriod; // Medium Period +ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period +ENUM_TIMEFRAMES lcPeriod; // Long Period +ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period +ENUM_TIMEFRAMES hcPeriod; // Hind Period +ENUM_X_MARKET_CYCLES appliedCycle; // Applied Cycle + +// +// Signal ... +int signalR2R; // Risk Reward Ratio +bool drawSignals; // Draw Signal +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 +bool showPV; // Show PV +bool showPVGolden; // Show PV Golden +bool showSar; // Show Sar +bool showTrend; // Show Trend +bool showATRBand; // Show ATR Band +bool showTrendBars; // Show Trend Bars +bool showSignalBars; // Show Signal Bars +bool showHKSignalBars; // Show Hiken Ashi Signal Bars + +// +int startCalculationForLastBars; // Calculate Last n Bars + +////////////////////////////////////////////////////////////////////// + +// +// Market ... +scMethod = X_PERIOD_AUTO; // How to Find Short Period +scPeriod = NULL; // Short Period +mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +mcPeriod = NULL; // Medium Period +lcMethod = X_PERIOD_AUTO; // How to Find Long Period +lcPeriod = NULL; // Long Period +hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +hcPeriod = NULL; // Hind Period +appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + +// +// Signal ... +signalR2R = 4; // Risk Reward Ratio +drawSignals = true; // Draw Signal +slAtrMultiplier = 1.0; // ATR Multiplier for SL + +// +// 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 ... +mAlertPrefix = ""; // Alert Prefix +_logAlerts = true; // Log Alerts +_pushAlerts = false; // Push Alerts +_mailAlerts = false; // Mail Alerts +_terminalAlerts = true; // Terminal Alerts + +// +// Presentation ... +showBars = true; // Show Bars +showPV = false; // Show PV +showPVGolden = false; // Show PV Golden +showSar = false; // Show Sar +showTrend = false; // Show Trend +showATRBand = false; // Show ATR Band +showTrendBars = false; // Show Trend Bars +showSignalBars = false; // Show Signal Bars +showHKSignalBars = false; // Show Hiken Ashi Signal Bars + +// +startCalculationForLastBars = 1500; // Calculate Last n Bars + + +////////////////////////////////////////////////////////////////////////////// + + X121_XCATB_SAR_LINE + sarBuffer + + X121_XCATB_SAR_STATE_LINE + sarStateBuffer + + X121_XCATB_PEAK_LINE + peakBuffer + + X121_XCATB_VALE_LINE + valeBuffer + + X121_XCATB_PEAK_GOLDEN_LINE + peakGoldenBuffer + + X121_XCATB_VALE_GOLDEN_LINE + valeGoldenBuffer + + X121_XCATB_ATR_BAND_UPPER_LINE + atrUpperBuffer + + X121_XCATB_ATR_BAND_LOWER_LINE + atrLowerBuffer + + X121_XCATB_TREND_LINE + trendBuffer + + X121_XCATB_TREND_STATE_LINE + trendStateBuffer + + X121_XCATB_SBAR_O_LINE + sBarOpenSBuffer + + X121_XCATB_SBAR_C_LINE + sBarCloseBuffer + + X121_XCATB_HK_SBAR_O_LINE + hkSBarOpenBuffer + + X121_XCATB_HK_SBAR_C_LINE + hkSBarCloseBuffer + + X121_XCATB_S_HH_LINE + sHHBuffer + + X121_XCATB_S_LL_LINE + sLLBuffer + + X121_XCATB_M_HH_LINE + mHHBuffer + + X121_XCATB_M_LL_LINE + mLLBuffer + + X121_XCATB_L_HH_LINE + lHHBuffer + + X121_XCATB_L_LL_LINE + lLLBuffer + + X121_XCATB_H_HH_LINE + hHHBuffer + + X121_XCATB_H_LL_LINE + hLLBuffer + + X121_XCATB_RSI_LINE + rsiBuffer + + X121_XCATB_ADX_LINE + adxBuffer + + X121_XCATB_ADXP_LINE + adxpBuffer + + X121_XCATB_ADXN_LINE + adxnBuffer + + X121_XCATB_DELTA_LINE + deltaBuffer + + X121_XCATB_DELTA_SIGNAL_LINE + deltaSignalBuffer + + X121_XCATB_VOLUME_BULLISH_LINE + bullishVolumeBuffer + + X121_XCATB_VOLUME_BEARISH_LINE + bearishVolumeBuffer + + X121_XCATB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE + bullishVolumeSignalBuffer + + X121_XCATB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE + bearishVolumeSignalBuffer + + X121_XCATB_ATR_LINE + atrBuffer + + X121_XCATB_ATR_BAND_RAW_UPPER_LINE + atrUpperBuffer + + X121_XCATB_ATR_BAND_RAW_LOWER_LINE + atrLowerBuffer + + X121_XCATB_HK_BAR_O_LINE + hkOpenBuffer + + X121_XCATB_HK_BAR_H_LINE + hkHighBuffer + + X121_XCATB_HK_BAR_L_LINE + hkLowBuffer + + X121_XCATB_HK_BAR_C_LINE + hkCloseBuffer + diff --git a/Experts/xczone.test.ea.mq5 b/Documents/BKP/xczone.test.ea.mq5 similarity index 100% rename from Experts/xczone.test.ea.mq5 rename to Documents/BKP/xczone.test.ea.mq5 diff --git a/Experts/xcatb.test.ea.mq5 b/Experts/xcatb.test.ea.mq5 new file mode 100644 index 00000000..2b173097 --- /dev/null +++ b/Experts/xcatb.test.ea.mq5 @@ -0,0 +1,836 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XCATB MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XCAEA +// Description: an Exper Advisor which used XCATB +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "EA based on X121 XCATB indicator" +#property strict + +// +// Include Common Library ... +#include "../Classes/x-saherelm.x-alert.class.mq5" +#include "../Classes/x-saherelm.x-trade.class.mq5" +#include "../Classes/x-saherelm.x-volume.class.mq5" +#include "../Helpers/x-saherelm.x121.xcatb.helper.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.x121.xcatb.lib.mq5" +#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5" + +// +#define ShortName "XCATBEA" + +// +// Inputs ... + +// +// Common ... +input group "Common"; +input long eaMagicNumber = 78692110; // Magic Number +input int eaSlippage = 10; // Slippgae +input string eaLogSuffix = ""; // Log Suffix + +// +// Detector ... +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 + +// +// 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 + +// +// Signal ... +input group "Signal"; +input int eaSignalR2R = 3; // Risk Reward Ratio +input double eaSLAtrMultiplier = 0.5; // ATR Multiplier for SL + +// +// Volume ... +input group "Volume"; +input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_EQUITY; // Volume Applying Type +input double eaStaticVoluem = 0.0; // Static Volume +input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume +input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing +input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade +input double eaConstantPercent = 0.5; // Constant Percent of Balance Per Trade +input double eaConstantBalance = 0.0; // Constant Balance for Calculations + +// +// Management ... +input group "Management"; +input bool eaAllowTrade = true; // Allow Trade on Signals +input bool eaAllowLongs = true; // Allow Long Trades +input bool eaAllowShorts = true; // Allow Short Trades +input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_NONE; // Trade Restrictions Period +input int eaMaxAllowedTPs = 0; // Max Allowed TP(s) per Day +input int eaMaxAllowedSLs = 0; // Max Allowed SL(s) per Day +input int eaMaxAllowedTrades = 0; // Max Allowed Trades per Day +input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades +input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade +input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade +input string eaCloseAllOpenTradesAt = ""; // Close All Open Trades per Day At Specified Time + +// +// Alert ... +// Here we Provider All Requirements for +// Configuring Alert Provider ... +input group "Alert"; +input bool eaEnableAlerts = true; // Enable Alerts +input bool eaLogAlerts = true; // Log Alerts +input bool eaMailAlerts = false; // Mail Alerts +input bool eaPushAlerts = true; // Push Alerts +input bool eaTerminalAlerts = true; // Terminal Alerts + +// +// Time Report ... +input group "Reports"; +input bool eaReportNewMonths = false; // Report New Month +input bool eaReportNewWeeks = false; // Report New Weeks +input bool eaReportNewDays = true; // Report New Days +input bool eaReportNewHours = false; // Report New Hours +input bool eaReportTrades = true; // Report Trades +input bool eaReportSignals = true; // Report Signals +input bool eaReportProtector = true; // Report Protector Actions +input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished + +// +// Variables ... + +// +XCAlert *eaAlert; +XCTrade *eaTrade; +XSignal eaSignal; +XCVolume *eaVolume; +X121XCatbInputs eaInputs; +XCX121XCatbHelper *eaHelper; +XBarTracker eaBarTraker; +XTimeTracker eaTimeTracker; +XCXCAEATradeManager *eaTradeManager; +XCAEAStrategyConditions eaConditions; + +// +XTriggerBlock eaTB; + +// +CArrayObj *eaObjects; + +// +string eaTag = ""; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs and Required Parameters + // for EA to Works fine ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initial Requirements ... + InitRequirements(); + + // + // Initialize Volume Manger ... + if (!InitVolume()) + { + return INIT_FAILED; + } + + // + return (INIT_SUCCEEDED); +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // eaObjects.Clear(); + + // + delete eaHelper; + ZeroMemory(eaHelper); + + // + delete eaAlert; + ZeroMemory(eaAlert); + + // + delete eaTrade; + ZeroMemory(eaTrade); + + // + delete eaVolume; + ZeroMemory(eaVolume); + + // + eaSignal.Clean(); + eaBarTraker.Clean(); + eaConditions.Clean(); + eaTimeTracker.Clean(); + + // + DestroyTimer(); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + HandleTimeReport(); + + // + // Handle Position Management / Protections ... + eaTradeManager.Manage(); + + // + eaSignal.Clean(); + eaConditions.Clean(); + + // + // Check Bar Processing ... + if (!eaBarTraker.CanProcessBar()) + { + return; + } + + // + bool has = false; + + // + // Retrieve Bars ... + XOHCL zBar; + XOHCL cBar; + has = zBar.Init( + _Symbol, + _Period, + 0 // + ); + has = + has && + zBar.GetPreviousBar(cBar); + if (!has) + { + // + zBar.Clean(); + cBar.Clean(); + + // + return; + } + + // + double bid = GetBid(zBar.symbol); + + // + XTriggerBlock iTB; + has = GetNewestX121TriggerBlock( + _Symbol, + _Period, + iTB // + ); + if (has) + { + // + // Check Newest TB is Newer Than Exists TB ... + bool canPass = + !eaTB.IsValid() + ? true + : iTB.ToIndex() < eaTB.ToIndex(); + if (canPass) + { + // + eaTB = iTB; + eaSignal = iTB.signal; + + // + // Prepare eaConditions if Reuqired ... + } + } + + // + has = eaSignal.IsValid(); + if (has) + { + // + // Here we ensure which has a New Signal and must + // prepare and Execute it ... + Print("new Signal Detected ..."); + } + + // + // eaTB.Clean(); + zBar.Clean(); + cBar.Clean(); + eaSignal.Clean(); + eaConditions.Clean(); +} + +// +// Handle On Trade Event ... +void OnTrade() +{ + eaTrade.HandleOnTrade(); +} + +// +// On Timer ... +void OnTimer() +{ +} + +// +// Chart Event Handler ... +void OnChartEvent( + const int id, + const long &lparam, + const double &dparam, + const string &sparam // +) +{ +} + +// +// Event Listeners ... + +/** + * Handle StopLoss Triggered Positions ... + * + * @param deal: XDeal instance ... + */ +void OnStopLossTriggered(const XDeal &deal) +{ + eaTradeManager.HandleSL(deal); +} + +/** + * Handle Take Profit Triggered Positions ... + * + * @param deal: XDeal instance ... + */ +void OnTakeProfitTriggered(const XDeal &deal) +{ + eaTradeManager.HandleTP(deal); +} + +/** + * Handle Force Close a Position ... + * + * @param ticket: ULONG ... + * @param position: XPosition instance ... + * @param comment: string ... + */ +void OnPositionForceClosed( + const ulong ticket, + const XPosition &position, + const string comment // +) +{ + eaTradeManager.HandleForceClose(position); +} + +/** + * Handle Position Partially Closed Event ... + * + * @param ticket: ULONG ... + * @param profit: double ... + * @param comment: string ... + */ +void OnPositionPartiallyClosed( + const ulong ticket, + const double profit, + const string comment // +) +{ + eaTradeManager.HandlePartiallyClosed( + ticket, + profit, + comment // + ); +} + +/** + * Handle Deals Changes ... + * + * @param count: Integer, Number of Changes ... + */ +void OnDealsChanged(int count) +{ +} + +/** + * Handle Orders Changes ... + * + * @param count: Integer, Number of Changes ... + */ +void OnOrdersChanged(int count) +{ +} + +/** + * Handle Positions Changes ... + * + * @param count: Integer, Number of Changes ... + */ +void OnPositionsChanged(int count) +{ +} + +// +// Custom Functions ... + +/** + * Validate all Inputs of Expert Adviser ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + string errMessage = ""; + + // + bool isCommonValid = ( + // + eaSlippage > 0 && + eaMagicNumber > 0 + // + ); + if (!isCommonValid) + { + // + errMessage += "common configurations error;" + "\n"; + } + + // + result = + // + // Common ... + isCommonValid && + // + // Otere ... + true + // + ; + + // + if (!result) + { + // + // Since here Logger not Initiallized, we Use Raw Print Command ... + Print(ShortName + " Errors: \n", errMessage); + } + + // + return result; +} + +/** + * Initialize Timer ... + * + * @return ( bool ) + */ +bool InitTimer() +{ + // + bool result = false; + + // + // TODO: Initialize Timer if necessary ... + // result = EventSetTimer(1); + // result = EventSetMillisecondTimer(100); + result = true; + + // + return result; +} + +/** + * Destroy Timer ... + */ +void DestroyTimer() +{ + // + // TODO: Use This ... + // EventKillTimer(); +} + +/** + * Initial Volume Manager Class Based on Given Configuration ... + * + * @return ( bool ) + */ +bool InitVolume() +{ + // + bool result = false; + + // + eaVolume = new XCVolume(); + + // + result = eaVolume.Init( + eaVolumeSelect, + eaStaticVoluem, + eaDynamicVolumeStepBalance, + eaDynamicVolumeStepVolume, + eaConstantRiskBalance, + eaConstantPercent, + eaConstantBalance // + ); + + // + return result; +} + +/** + * Initial Requirements of EA ... + */ +void InitRequirements() +{ + // + // Preparing Tags ... + eaTag = + (IsValid(eaLogSuffix) + ? eaLogSuffix + "_" + : "") + + ShortName; + + // + // Initial Bar Tracker ... + eaBarTraker.Init( + _Symbol, + _Period // + ); + + // + // Objects ... + eaObjects = new CArrayObj(); + + // + // Configure XCA ... + eaInputs.Default(); + + // + // Hide all Visible Buffers ... + eaInputs.Hide(); + + // + // we Can make Show all requirements here ... + + // + // Signal ... + eaInputs.signalR2R = eaSignalR2R; + eaInputs.slAtrMultiplier = eaSLAtrMultiplier; + + // + // 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 = eaLogAlerts; + eaInputs.pushAlerts = eaMailAlerts; + eaInputs.mailAlerts = eaPushAlerts; + eaInputs.terminalAlerts = eaTerminalAlerts; + + // + eaHelper = new XCX121XCatbHelper(); + bool isInited = eaHelper.Init( + _Symbol, + _Period, + eaInputs // + ); + + // + // EA Alert ... + eaAlert = new XCAlert( + eaTag, + eaEnableAlerts, + eaLogAlerts, + eaTerminalAlerts, + eaMailAlerts, + eaPushAlerts // + ); + + // + // EA Trade ... + eaTrade = new XCTrade( + eaSlippage, + eaMagicNumber, + eaMaxAllowedSpread, + eaMaxAllowedPositions, + eaMaxAllowedDrawdownFactor // + ); + eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered); + eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); + eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed); + eaTrade.AddOnPartialClosePositionEventHandler(OnPositionPartiallyClosed); + + // + // EA Trae Manager ... + eaTradeManager = new XCXCAEATradeManager( + eaTrade // + ); + eaTradeManager.SaveTrades(true); + eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts); + eaTradeManager.SetAlertPrefix(eaTag); + eaTradeManager.SetAlertLogAlerts(eaLogAlerts); + eaTradeManager.SetAlertMailAlerts(eaMailAlerts); + eaTradeManager.SetAlertPushAlerts(eaPushAlerts); + eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts); + + // + // Setting Trade Reports ... + eaTradeManager + .SetTradeReports( + eaReportTrades, + eaReportSignals, + eaReportProtector, + eaReportAfterTradesBalance // + ); + + // + // Setting Trade Permissions ... + eaTradeManager + .SetTradePermissions( + eaAllowTrade, + eaAllowLongs, + eaAllowShorts // + ); + + // + // Setting Trade Restrictions ... + eaTradeManager + .SetTradeRestrictions( + eaRestrictionsPeriod, + eaMaxAllowedTPs, + eaMaxAllowedSLs, + eaMaxAllowedTrades // + ); +} + +/** + * Handling Time Reporting ... + */ +void HandleTimeReport() +{ + // + // Monthly Report .... + if (eaReportNewMonths && + eaTimeTracker.IsNewMonth()) + { + // + string msg = "New Month ..."; + + // + eaAlert.Alert(msg); + } + + // + // Weekly Report .... + if (eaReportNewWeeks && + eaTimeTracker.IsNewWeek()) + { + // + string msg = "New Week ..."; + + // + eaAlert.Alert(msg); + } + + // + // Daily Report .... + if (eaReportNewDays && + eaTimeTracker.IsNewDay()) + { + // + string msg = "New Day ..."; + + // + eaAlert.Alert(msg); + } + + // + // Hourly Report .... + if (eaReportNewHours && + eaTimeTracker.IsNewHour()) + { + // + string msg = "New Hour ..."; + + // + eaAlert.Alert(msg); + } +} + +// +// Apply Signal Targets ... +void ApplySignalTargets(XSignal &signal) +{ + // + bool has = signal.IsValid(); + if (!has) + { + return; + } + + // + // Clean Signal Targets ... + Clean(signal.targets); + + // + // Calculate Requirements ... + double r2r = 1; + // maxAllowedR2R > 0 + // ? maxAllowedR2R + // : 1; + double risk = signal.GetRisk(); + double reward = risk * r2r; + + // + double isLong = IsLong(signal.type); + + // + // Handling Signal TP ... + signal.tp = + isLong + ? signal.entry + reward + : signal.entry - reward; + + // + // Try to Apply Money Management ... + + // + if (r2r <= 1) + { + return; + } + + // + // XTarget iTarget; + + // // + // // Partial Close 0.5 of Position on Reward 1 ... + // reward = risk * 1; + // iTarget.target = + // isLong + // ? signal.entry + reward + // : signal.entry - reward; + // iTarget.volumeMultiplier = 0.5; + + // // + // AddRef(iTarget, signal.targets); + // iTarget.Clean(); + + // // + // if (r2r <= 2) + // { + // return; + // } + + // + // Making Loop ... + // for (int i = 2; i < ((int)r2r - 1); i++) + // { + // // + // iTarget.Clean(); + + // // + // reward = i * risk; + // iTarget.target = + // isLong + // ? signal.entry + reward + // : signal.entry - reward; + // iTarget.volumeMultiplier = 1 / (r2r - 2); + + // // + // AddRef(iTarget, signal.targets); + // } + + // + // Sort Targets ... + ENUM_X_DIRECTION sortingDir = + isLong + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + ApplySortOnTargets( + sortingDir, + signal.targets // + ); +} diff --git a/Helpers/x-saherelm.x121.xcatb.helper.mq5 b/Helpers/x-saherelm.x121.xcatb.helper.mq5 new file mode 100644 index 00000000..aff9d55d --- /dev/null +++ b/Helpers/x-saherelm.x121.xcatb.helper.mq5 @@ -0,0 +1,3789 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121XCatbHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.x-helper.class.mq5" + +// +// Definitions ... + +// +// Buffers ... +enum ENUM_X121_XCATB_BUFFERS +{ + X121_XCATB_SAR_LINE = 0, + X121_XCATB_SAR_STATE_LINE = 28, + X121_XCATB_PEAK_LINE = 2, + X121_XCATB_VALE_LINE = 3, + X121_XCATB_PEAK_GOLDEN_LINE = 4, + X121_XCATB_VALE_GOLDEN_LINE = 5, + X121_XCATB_ATR_BAND_UPPER_LINE = 6, + X121_XCATB_ATR_BAND_LOWER_LINE = 7, + X121_XCATB_TREND_LINE = 8, + X121_XCATB_TREND_STATE_LINE = 29, + X121_XCATB_SBAR_O_LINE = 10, + X121_XCATB_SBAR_H_LINE = 11, + X121_XCATB_SBAR_L_LINE = 12, + X121_XCATB_SBAR_C_LINE = 13, + X121_XCATB_HK_SBAR_O_LINE = 15, + X121_XCATB_HK_SBAR_H_LINE = 16, + X121_XCATB_HK_SBAR_L_LINE = 17, + X121_XCATB_HK_SBAR_C_LINE = 18, + X121_XCATB_S_HH_LINE = 20, + X121_XCATB_S_LL_LINE = 21, + X121_XCATB_M_HH_LINE = 22, + X121_XCATB_M_LL_LINE = 23, + X121_XCATB_L_HH_LINE = 24, + X121_XCATB_L_LL_LINE = 25, + X121_XCATB_H_HH_LINE = 26, + X121_XCATB_H_LL_LINE = 27, + X121_XCATB_RSI_LINE = 30, + X121_XCATB_ADX_LINE = 31, + X121_XCATB_ADXP_LINE = 32, + X121_XCATB_ADXN_LINE = 33, + X121_XCATB_DELTA_LINE = 34, + X121_XCATB_DELTA_SIGNAL_LINE = 35, + X121_XCATB_VOLUME_BULLISH_LINE = 36, + X121_XCATB_VOLUME_BEARISH_LINE = 37, + X121_XCATB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE = 38, + X121_XCATB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE = 39, + X121_XCATB_ATR_LINE = 40, + X121_XCATB_ATR_BAND_RAW_UPPER_LINE = 41, + X121_XCATB_ATR_BAND_RAW_LOWER_LINE = 42, + X121_XCATB_HK_BAR_O_LINE = 43, + X121_XCATB_HK_BAR_H_LINE = 44, + X121_XCATB_HK_BAR_L_LINE = 45, + X121_XCATB_HK_BAR_C_LINE = 46, +}; + +// +// Input Models ... +struct X121XCatbInputs +{ + // + // Props ... + + // + // Market ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period + ENUM_TIMEFRAMES scPeriod; // Short Period + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period + ENUM_TIMEFRAMES mcPeriod; // Medium Period + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period + ENUM_TIMEFRAMES lcPeriod; // Long Period + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period + ENUM_TIMEFRAMES hcPeriod; // Hind Period + ENUM_X_MARKET_CYCLES appliedCycle; // Applied Cycle + + // + // Signal ... + int signalR2R; // Risk Reward Ratio + bool drawSignals; // Draw Signal + 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 + bool showPV; // Show PV + bool showPVGolden; // Show PV Golden + bool showSar; // Show Sar + bool showTrend; // Show Trend + bool showATRBand; // Show ATR Band + bool showTrendBars; // Show Trend Bars + bool showSignalBars; // Show Signal Bars + bool showHKSignalBars; // Show Hiken Ashi Signal Bars + + // + int startCalculationForLastBars; // Calculate Last n Bars + + // + // Constructor(s) ... + X121XCatbInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + scMethod = X_PERIOD_AUTO; // How to Find Short Period + scPeriod = NULL; // Short Period + mcMethod = X_PERIOD_AUTO; // How to Find Medium Period + mcPeriod = NULL; // Medium Period + lcMethod = X_PERIOD_AUTO; // How to Find Long Period + lcPeriod = NULL; // Long Period + hcMethod = X_PERIOD_AUTO; // How to Find Hind Period + hcPeriod = NULL; // Hind Period + appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + + // + // Signal ... + signalR2R = 0; // Risk Reward Ratio + drawSignals = false; // Draw Signal + slAtrMultiplier = 0; // ATR Multiplier for SL + + // + // 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 = NULL; // Alert Prefix + logAlerts = false; // Log Alerts + pushAlerts = false; // Push Alerts + mailAlerts = false; // Mail Alerts + terminalAlerts = false; // Terminal Alerts + + // + // Presentation ... + showBars = false; // Show Bars + showPV = false; // Show PV + showPVGolden = false; // Show PV Golden + showSar = false; // Show Sar + showTrend = false; // Show Trend + showATRBand = false; // Show ATR Band + showTrendBars = false; // Show Trend Bars + showSignalBars = false; // Show Signal Bars + showHKSignalBars = false; // Show Hiken Ashi Signal Bars + + // + startCalculationForLastBars = 0; // Calculate Last n Bars + + // + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + // Market ... + scMethod = X_PERIOD_AUTO; // How to Find Short Period + scPeriod = NULL; // Short Period + mcMethod = X_PERIOD_AUTO; // How to Find Medium Period + mcPeriod = NULL; // Medium Period + lcMethod = X_PERIOD_AUTO; // How to Find Long Period + lcPeriod = NULL; // Long Period + hcMethod = X_PERIOD_AUTO; // How to Find Hind Period + hcPeriod = NULL; // Hind Period + appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + + // + // Signal ... + signalR2R = 4; // Risk Reward Ratio + drawSignals = false; // Draw Signal + slAtrMultiplier = 1.0; // ATR Multiplier for SL + + // + // 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 = NULL; // Alert Prefix + logAlerts = true; // Log Alerts + pushAlerts = false; // Push Alerts + mailAlerts = false; // Mail Alerts + terminalAlerts = true; // Terminal Alerts + + // + // Presentation ... + showBars = true; // Show Bars + showPV = false; // Show PV + showPVGolden = false; // Show PV Golden + showSar = false; // Show Sar + showTrend = false; // Show Trend + showATRBand = false; // Show ATR Band + showTrendBars = false; // Show Trend Bars + showSignalBars = false; // Show Signal Bars + showHKSignalBars = false; // Show Hiken Ashi Signal Bars + + // + startCalculationForLastBars = 1500; // Calculate Last n Bars + } + + // + // Hide all Visible Buffers ... + void Hide() + { + // + showPV = false; + showPVGolden = false; + showSar = false; + showTrend = false; + showATRBand = false; + showTrendBars = false; + showSignalBars = false; + showHKSignalBars = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(appliedCycle) && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + return result; + } + + // +}; + +// +// Conditions ... +struct X121XCatbConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + double sarBuffer[]; + double atrBuffer[]; + double rsiBuffer[]; + double adxBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double adxpBuffer[]; + double adxnBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double deltaBuffer[]; + double trendBuffer[]; + double hkLowBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkCloseBuffer[]; + double sarStateBuffer[]; + double atrUpperBuffer[]; + double atrLowerBuffer[]; + double sBarOpenBuffer[]; + double sBarCloseBuffer[]; + double trendStateBuffer[]; + double hkSBarOpenBuffer[]; + double peakGoldenBuffer[]; + double valeGoldenBuffer[]; + double hkSBarCloseBuffer[]; + double deltaSignalBuffer[]; + double bullishVolumeBuffer[]; + double bearishVolumeBuffer[]; + double bullishVolumeSignalBuffer[]; + double bearishVolumeSignalBuffer[]; + + // + // Conditions ... + + // + // Constructor ... + X121XCatbConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + symbol = NULL; + period = NULL; + time = NULL; + + // + // Buffers ... + + // + Clean(sarBuffer); + Clean(atrBuffer); + Clean(rsiBuffer); + Clean(adxBuffer); + Clean(sHHBuffer); + Clean(sLLBuffer); + Clean(mHHBuffer); + Clean(mLLBuffer); + Clean(lHHBuffer); + Clean(lLLBuffer); + Clean(hHHBuffer); + Clean(hLLBuffer); + Clean(adxpBuffer); + Clean(adxnBuffer); + Clean(peakBuffer); + Clean(valeBuffer); + Clean(deltaBuffer); + Clean(trendBuffer); + Clean(hkLowBuffer); + Clean(hkOpenBuffer); + Clean(hkHighBuffer); + Clean(hkCloseBuffer); + Clean(sarStateBuffer); + Clean(atrUpperBuffer); + Clean(atrLowerBuffer); + Clean(sBarOpenBuffer); + Clean(sBarCloseBuffer); + Clean(trendStateBuffer); + Clean(hkSBarOpenBuffer); + Clean(peakGoldenBuffer); + Clean(valeGoldenBuffer); + Clean(hkSBarCloseBuffer); + Clean(deltaSignalBuffer); + Clean(bullishVolumeBuffer); + Clean(bearishVolumeBuffer); + Clean(bullishVolumeSignalBuffer); + Clean(bearishVolumeSignalBuffer); + + // + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(rsiBuffer, true); + ArraySetAsSeries(adxBuffer, true); + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(adxpBuffer, true); + ArraySetAsSeries(adxnBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(deltaBuffer, true); + ArraySetAsSeries(trendBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(atrUpperBuffer, true); + ArraySetAsSeries(atrLowerBuffer, true); + ArraySetAsSeries(sBarOpenBuffer, true); + ArraySetAsSeries(sBarCloseBuffer, true); + ArraySetAsSeries(trendStateBuffer, true); + ArraySetAsSeries(hkSBarOpenBuffer, true); + ArraySetAsSeries(peakGoldenBuffer, true); + ArraySetAsSeries(valeGoldenBuffer, true); + ArraySetAsSeries(hkSBarCloseBuffer, true); + ArraySetAsSeries(deltaSignalBuffer, true); + ArraySetAsSeries(bullishVolumeBuffer, true); + ArraySetAsSeries(bearishVolumeBuffer, true); + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + + // + // Conditions ... + + // + ZeroMemory(this); + } + + /** + * Generate Conditions Scores ... + * + * @param bullishScore: Double, Directional Scores Reference ... + * @param bearishScore: Double, Directional Scores Reference ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + double score = 1; + double minScore = 0.5; + double highScore = 1.5; + } + + /** + * Generate Summary String for Represent Conditions State ... + * + * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... + * @param onlyConditions: Boolean, Just Generate Only Conditions ... + * @param includeScores: Boolean, Attach Scores Representations on Result ... + * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... + * @param separator: String, Separate Lines ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Retrieve nique Tag Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + return GetTypeName(this); + } + + // +}; + +// +// Class ... +class XCX121XCatbHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Buffers ... + double sarBuffer[]; + double atrBuffer[]; + double rsiBuffer[]; + double adxBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double adxpBuffer[]; + double adxnBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double deltaBuffer[]; + double trendBuffer[]; + double hkLowBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkCloseBuffer[]; + double sarStateBuffer[]; + double atrUpperBuffer[]; + double atrLowerBuffer[]; + double sBarOpenBuffer[]; + double sBarCloseBuffer[]; + double trendStateBuffer[]; + double hkSBarOpenBuffer[]; + double peakGoldenBuffer[]; + double valeGoldenBuffer[]; + double hkSBarCloseBuffer[]; + double deltaSignalBuffer[]; + double bullishVolumeBuffer[]; + double bearishVolumeBuffer[]; + double bullishVolumeSignalBuffer[]; + double bearishVolumeSignalBuffer[]; + + // + // Constructors ... + XCX121XCatbHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XCatbHelper() + { + // + mInputs.Clean(); + + // + Clean(sarBuffer); + Clean(atrBuffer); + Clean(rsiBuffer); + Clean(adxBuffer); + Clean(sHHBuffer); + Clean(sLLBuffer); + Clean(mHHBuffer); + Clean(mLLBuffer); + Clean(lHHBuffer); + Clean(lLLBuffer); + Clean(hHHBuffer); + Clean(hLLBuffer); + Clean(adxpBuffer); + Clean(adxnBuffer); + Clean(peakBuffer); + Clean(valeBuffer); + Clean(deltaBuffer); + Clean(trendBuffer); + Clean(hkLowBuffer); + Clean(hkOpenBuffer); + Clean(hkHighBuffer); + Clean(hkCloseBuffer); + Clean(sarStateBuffer); + Clean(atrUpperBuffer); + Clean(atrLowerBuffer); + Clean(sBarOpenBuffer); + Clean(sBarCloseBuffer); + Clean(trendStateBuffer); + Clean(hkSBarOpenBuffer); + Clean(peakGoldenBuffer); + Clean(valeGoldenBuffer); + Clean(hkSBarCloseBuffer); + Clean(deltaSignalBuffer); + Clean(bullishVolumeBuffer); + Clean(bearishVolumeBuffer); + Clean(bullishVolumeSignalBuffer); + Clean(bearishVolumeSignalBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XCatbInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(rsiBuffer, true); + ArraySetAsSeries(adxBuffer, true); + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(adxpBuffer, true); + ArraySetAsSeries(adxnBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(deltaBuffer, true); + ArraySetAsSeries(trendBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(atrUpperBuffer, true); + ArraySetAsSeries(atrLowerBuffer, true); + ArraySetAsSeries(sBarOpenBuffer, true); + ArraySetAsSeries(sBarCloseBuffer, true); + ArraySetAsSeries(trendStateBuffer, true); + ArraySetAsSeries(hkSBarOpenBuffer, true); + ArraySetAsSeries(peakGoldenBuffer, true); + ArraySetAsSeries(valeGoldenBuffer, true); + ArraySetAsSeries(hkSBarCloseBuffer, true); + ArraySetAsSeries(deltaSignalBuffer, true); + ArraySetAsSeries(bullishVolumeBuffer, true); + ArraySetAsSeries(bearishVolumeBuffer, true); + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xcatb", + "", // Market ... + mInputs.scMethod, + mInputs.scPeriod, + mInputs.mcMethod, + mInputs.mcPeriod, + mInputs.lcMethod, + mInputs.lcPeriod, + mInputs.hcMethod, + mInputs.hcPeriod, + mInputs.appliedCycle, + "", // Signal ... + mInputs.signalR2R, + mInputs.drawSignals, + mInputs.slAtrMultiplier, + "", // 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, + mInputs.showPVGolden, + mInputs.showSar, + mInputs.showTrend, + mInputs.showATRBand, + mInputs.showTrendBars, + mInputs.showSignalBars, + mInputs.showHKSignalBars, + mInputs.startCalculationForLastBars + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121XCatbInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XCatbInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Readers ... + + // + // SAR ... + + // + double GetSar( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sarBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sarBuffer[barIndex]; + } + + // + int CopySar( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sarBuffer, + buffer, + forceClean + // + ); + } + + // + // SAR State ... + + // + double GetSarState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sarStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sarStateBuffer[barIndex]; + } + + // + int CopySarState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sarStateBuffer, + buffer, + forceClean + // + ); + } + + // + // PEAK ... + + // + double GetPeak( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(peakBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return peakBuffer[barIndex]; + } + + // + int CopyPeak( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + peakBuffer, + buffer, + forceClean + // + ); + } + + // + // VALE ... + + // + double GetVale( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(valeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return valeBuffer[barIndex]; + } + + // + int CopyVale( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + valeBuffer, + buffer, + forceClean + // + ); + } + + // + // PEAK Golden ... + + // + double GetPeakGolden( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(peakGoldenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return peakGoldenBuffer[barIndex]; + } + + // + int CopyPeakGolden( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + peakGoldenBuffer, + buffer, + forceClean + // + ); + } + + // + // VALE Golden ... + + // + double GetValeGolden( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(valeGoldenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return valeGoldenBuffer[barIndex]; + } + + // + int CopyValeGolden( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + valeGoldenBuffer, + buffer, + forceClean + // + ); + } + + // + // ATR ... + + // + double GetATR( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrBuffer[barIndex]; + } + + // + int CopyATR( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + atrBuffer, + buffer, + forceClean + // + ); + } + + // + // ATR Band Upper ... + + // + double GetATRUpper( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrUpperBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrUpperBuffer[barIndex]; + } + + // + int CopyATRUpper( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + atrUpperBuffer, + buffer, + forceClean + // + ); + } + + // + // ATR Band Lower ... + + // + double GetATRLower( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrLowerBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrLowerBuffer[barIndex]; + } + + // + int CopyATRLower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + atrLowerBuffer, + buffer, + forceClean + // + ); + } + + // + // TREND ... + + // + double GetTrend( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(trendBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return trendBuffer[barIndex]; + } + + // + int CopyTrend( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + trendBuffer, + buffer, + forceClean + // + ); + } + + // + // TREND State ... + + // + double GetTrendState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(trendStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return trendStateBuffer[barIndex]; + } + + // + int CopyTrendState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + trendStateBuffer, + buffer, + forceClean + // + ); + } + + // + // SIGNAL Bar ... + + // + // OPEN ... + + // + double GetSBarOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sBarOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sBarOpenBuffer[barIndex]; + } + + // + int CopySBarOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sBarOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // CLOSE ... + + // + double GetSBarClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sBarCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sBarCloseBuffer[barIndex]; + } + + // + int CopySBarClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sBarCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK SIGNAL Bar ... + + // + // OPEN ... + + // + double GetHKSBarOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkSBarOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkSBarOpenBuffer[barIndex]; + } + + // + int CopyHKSBarOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkSBarOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // CLOSE ... + + // + double GetHKSBarClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkSBarCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkSBarCloseBuffer[barIndex]; + } + + // + int CopyHKSBarClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkSBarCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // CYCLES Range ... + + // + // SHORT ... + + // + // HH ... + + // + double GetSHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sHHBuffer[barIndex]; + } + + // + int CopySHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetSLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sLLBuffer[barIndex]; + } + + // + int CopySLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sLLBuffer, + buffer, + forceClean + // + ); + } + + // + // MEDIUM ... + + // + // HH ... + + // + double GetMHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mHHBuffer[barIndex]; + } + + // + int CopyMHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + mHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetMLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mLLBuffer[barIndex]; + } + + // + int CopyMLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + mLLBuffer, + buffer, + forceClean + // + ); + } + + // + // LONG ... + + // + // HH ... + + // + double GetLHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(lHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lHHBuffer[barIndex]; + } + + // + int CopyLHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + lHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetLLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(lLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lLLBuffer[barIndex]; + } + + // + int CopyLLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + lLLBuffer, + buffer, + forceClean + // + ); + } + + // + // HIND ... + + // + // HH ... + + // + double GetHHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hHHBuffer[barIndex]; + } + + // + int CopyHHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetHLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hLLBuffer[barIndex]; + } + + // + int CopyHLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hLLBuffer, + buffer, + forceClean + // + ); + } + + // + // ADX ... + + // + double GetADX( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(adxBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return adxBuffer[barIndex]; + } + + // + int CopyADX( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + adxBuffer, + buffer, + forceClean + // + ); + } + + // + // ADXP ... + + // + double GetADXP( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(adxpBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return adxpBuffer[barIndex]; + } + + // + int CopyADXP( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + adxpBuffer, + buffer, + forceClean + // + ); + } + + // + // ADXN ... + + // + double GetADXN( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(adxnBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return adxnBuffer[barIndex]; + } + + // + int CopyADXN( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + adxnBuffer, + buffer, + forceClean + // + ); + } + + // + // DELTA ... + + // + double GetDelta( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(deltaBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return deltaBuffer[barIndex]; + } + + // + int CopyDelta( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + deltaBuffer, + buffer, + forceClean + // + ); + } + + // + // DELTA Signal ... + + // + double GetDeltaSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(deltaSignalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return deltaSignalBuffer[barIndex]; + } + + // + int CopyDeltaSignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + deltaSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // VOLUME ... + + // + // Bullish ... + + // + double GetBullishVolume( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bullishVolumeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bullishVolumeBuffer[barIndex]; + } + + // + int CopyBullishVolume( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + bullishVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Bearish ... + + // + double GetBearishVolume( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bearishVolumeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bearishVolumeBuffer[barIndex]; + } + + // + int CopyBearishVolume( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + bearishVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // VOLUME Signal ... + + // + // Bullish ... + + // + double GetBullishVolumeSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bullishVolumeSignalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bullishVolumeSignalBuffer[barIndex]; + } + + // + int CopyBullishVolumeSignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + bullishVolumeSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // Bearish ... + + // + double GetBearishVolumeSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bearishVolumeSignalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bearishVolumeSignalBuffer[barIndex]; + } + + // + int CopyBearishVolumeSignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + bearishVolumeSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK ... + + // + // Open ... + + // + double GetHKOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkOpenBuffer[barIndex]; + } + + // + int CopyHKOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // High ... + + // + double GetHKHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkHighBuffer[barIndex]; + } + + // + int CopyHKHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkHighBuffer, + buffer, + forceClean + // + ); + } + + // + // Low ... + + // + double GetHKLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkLowBuffer[barIndex]; + } + + // + int CopyHKLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkLowBuffer, + buffer, + forceClean + // + ); + } + + // + // Close ... + + // + double GetHKClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkCloseBuffer[barIndex]; + } + + // + int CopyHKClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // RSI ... + + // + double GetRSI( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(rsiBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return rsiBuffer[barIndex]; + } + + // + int CopyRSI( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + rsiBuffer, + buffer, + forceClean + // + ); + } + + // + // Tools ... + + // + void Free() override + { + Cleanup(10); + } + + // + bool GetConditions( + X121XCatbConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + XOHCL zBar; + XOHCL cBar; + XOHCL pBar; + result = zBar.Init( + mSymbol, + mPeriod, + barIndex // + ); + result = + result && + zBar.GetPreviousBar(cBar); + result = + result && + cBar.GetPreviousBar(pBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + int zIndex = barIndex; + + // + // Buffers ... + + CopySar( + zIndex, + loopback, + conditions.sarBuffer // + ); + + // + CopySarState( + zIndex, + loopback, + conditions.sarStateBuffer // + ); + + // + CopyPeak( + zIndex, + loopback, + conditions.peakBuffer // + ); + + // + CopyVale( + zIndex, + loopback, + conditions.valeBuffer // + ); + + // + CopyPeakGolden( + zIndex, + loopback, + conditions.peakGoldenBuffer // + ); + + // + CopyValeGolden( + zIndex, + loopback, + conditions.valeGoldenBuffer // + ); + + // + CopyATR( + zIndex, + loopback, + conditions.atrBuffer // + ); + + // + CopyATRUpper( + zIndex, + loopback, + conditions.atrUpperBuffer // + ); + + // + CopyATRLower( + zIndex, + loopback, + conditions.atrLowerBuffer // + ); + + // + CopyTrend( + zIndex, + loopback, + conditions.trendBuffer // + ); + + // + CopyTrendState( + zIndex, + loopback, + conditions.trendStateBuffer // + ); + + // + CopySBarOpen( + zIndex, + loopback, + conditions.sBarOpenBuffer // + ); + + // + CopySBarClose( + zIndex, + loopback, + conditions.sBarCloseBuffer // + ); + + // + CopyHKSBarOpen( + zIndex, + loopback, + conditions.hkSBarOpenBuffer // + ); + + // + CopyHKSBarClose( + zIndex, + loopback, + conditions.hkSBarCloseBuffer // + ); + + // + CopySHH( + zIndex, + loopback, + conditions.sHHBuffer // + ); + + // + CopySLL( + zIndex, + loopback, + conditions.sLLBuffer // + ); + + // + CopyMHH( + zIndex, + loopback, + conditions.mHHBuffer // + ); + + // + CopyMLL( + zIndex, + loopback, + conditions.mLLBuffer // + ); + + // + CopyLHH( + zIndex, + loopback, + conditions.lHHBuffer // + ); + + // + CopyLLL( + zIndex, + loopback, + conditions.lLLBuffer // + ); + + // + CopyHHH( + zIndex, + loopback, + conditions.hHHBuffer // + ); + + // + CopyHLL( + zIndex, + loopback, + conditions.hLLBuffer // + ); + + // + CopyADX( + zIndex, + loopback, + conditions.adxBuffer // + ); + + // + CopyADXP( + zIndex, + loopback, + conditions.adxpBuffer // + ); + + // + CopyADXN( + zIndex, + loopback, + conditions.adxnBuffer // + ); + + // + CopyDelta( + zIndex, + loopback, + conditions.deltaBuffer // + ); + + // + CopyDeltaSignal( + zIndex, + loopback, + conditions.deltaSignalBuffer // + ); + + // + CopyBullishVolume( + zIndex, + loopback, + conditions.bullishVolumeBuffer // + ); + + // + CopyBearishVolume( + zIndex, + loopback, + conditions.bearishVolumeBuffer // + ); + + // + CopyBullishVolumeSignal( + zIndex, + loopback, + conditions.bullishVolumeSignalBuffer // + ); + + // + CopyBearishVolumeSignal( + zIndex, + loopback, + conditions.bearishVolumeSignalBuffer // + ); + + // + CopyHKOpen( + zIndex, + loopback, + conditions.hkOpenBuffer // + ); + + // + CopyHKHigh( + zIndex, + loopback, + conditions.hkHighBuffer // + ); + + // + CopyHKLow( + zIndex, + loopback, + conditions.hkLowBuffer // + ); + + // + CopyHKClose( + zIndex, + loopback, + conditions.hkCloseBuffer // + ); + + // + CopyRSI( + zIndex, + loopback, + conditions.rsiBuffer // + ); + + // + // Conditions ... + + // + int zIDX = 0; + int cIDX = 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + // Calculate ... + + // + // Attached ... + + // + // Cleanup Resources ... + + // + Cleanup(); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XCatbInputs mInputs; // Inputs ... + + // + // Buffers ... + // Define in Public ... + + // + void Calculate( + int barIndex = 0, + int maxRequiredBars = 100 // + ) + { + // + // Buffers ... + if (barIndex < 0) + { + barIndex = 0; + } + + // + CopyBuffer( + mHandler, + X121_XCATB_SAR_LINE, + barIndex, + maxRequiredBars, + sarBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_SAR_STATE_LINE, + barIndex, + maxRequiredBars, + sarStateBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_PEAK_LINE, + barIndex, + maxRequiredBars, + peakBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VALE_LINE, + barIndex, + maxRequiredBars, + valeBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_PEAK_GOLDEN_LINE, + barIndex, + maxRequiredBars, + peakGoldenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VALE_GOLDEN_LINE, + barIndex, + maxRequiredBars, + valeGoldenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ATR_BAND_UPPER_LINE, + barIndex, + maxRequiredBars, + atrUpperBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ATR_BAND_LOWER_LINE, + barIndex, + maxRequiredBars, + atrLowerBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_TREND_LINE, + barIndex, + maxRequiredBars, + trendBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_TREND_STATE_LINE, + barIndex, + maxRequiredBars, + trendStateBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_SBAR_O_LINE, + barIndex, + maxRequiredBars, + sBarOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_SBAR_C_LINE, + barIndex, + maxRequiredBars, + sBarCloseBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_SBAR_O_LINE, + barIndex, + maxRequiredBars, + hkSBarOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_SBAR_C_LINE, + barIndex, + maxRequiredBars, + hkSBarCloseBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_S_HH_LINE, + barIndex, + maxRequiredBars, + sHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_S_LL_LINE, + barIndex, + maxRequiredBars, + sLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_M_HH_LINE, + barIndex, + maxRequiredBars, + mHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_M_LL_LINE, + barIndex, + maxRequiredBars, + mLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_L_HH_LINE, + barIndex, + maxRequiredBars, + lHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_L_LL_LINE, + barIndex, + maxRequiredBars, + lLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_H_HH_LINE, + barIndex, + maxRequiredBars, + hHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_H_LL_LINE, + barIndex, + maxRequiredBars, + hLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_RSI_LINE, + barIndex, + maxRequiredBars, + rsiBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ADX_LINE, + barIndex, + maxRequiredBars, + adxBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ADXP_LINE, + barIndex, + maxRequiredBars, + adxpBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ADXN_LINE, + barIndex, + maxRequiredBars, + adxnBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_DELTA_LINE, + barIndex, + maxRequiredBars, + deltaBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_DELTA_SIGNAL_LINE, + barIndex, + maxRequiredBars, + deltaSignalBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_BULLISH_LINE, + barIndex, + maxRequiredBars, + bullishVolumeBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_BEARISH_LINE, + barIndex, + maxRequiredBars, + bearishVolumeBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE, + barIndex, + maxRequiredBars, + bullishVolumeSignalBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE, + barIndex, + maxRequiredBars, + bearishVolumeSignalBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ATR_LINE, + barIndex, + maxRequiredBars, + atrBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_O_LINE, + barIndex, + maxRequiredBars, + hkOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_H_LINE, + barIndex, + maxRequiredBars, + hkHighBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_L_LINE, + barIndex, + maxRequiredBars, + hkLowBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_C_LINE, + barIndex, + maxRequiredBars, + hkCloseBuffer // + ); + } + + // + void Cleanup( + int maxAllowed = 100 // + ) + { + // + CleanupArray( + sarBuffer, + maxAllowed // + ); + + // + CleanupArray( + sarStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + peakBuffer, + maxAllowed // + ); + + // + CleanupArray( + valeBuffer, + maxAllowed // + ); + + // + CleanupArray( + peakGoldenBuffer, + maxAllowed // + ); + + // + CleanupArray( + valeGoldenBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrUpperBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrLowerBuffer, + maxAllowed // + ); + + // + CleanupArray( + trendBuffer, + maxAllowed // + ); + + // + CleanupArray( + trendStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + sBarOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + sBarCloseBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkSBarOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkSBarCloseBuffer, + maxAllowed // + ); + + // + CleanupArray( + sHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + sLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + mHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + mLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + lHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + lLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + hHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + hLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + rsiBuffer, + maxAllowed // + ); + + // + CleanupArray( + adxBuffer, + maxAllowed // + ); + + // + CleanupArray( + adxpBuffer, + maxAllowed // + ); + + // + CleanupArray( + adxnBuffer, + maxAllowed // + ); + + // + CleanupArray( + deltaBuffer, + maxAllowed // + ); + + // + CleanupArray( + deltaSignalBuffer, + maxAllowed // + ); + + // + CleanupArray( + bullishVolumeBuffer, + maxAllowed // + ); + + // + CleanupArray( + bearishVolumeBuffer, + maxAllowed // + ); + + // + CleanupArray( + bullishVolumeSignalBuffer, + maxAllowed // + ); + + // + CleanupArray( + bearishVolumeSignalBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkHighBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkLowBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkCloseBuffer, + maxAllowed // + ); + } + + // +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.x121.xtb.helper.mq5 b/Helpers/x-saherelm.x121.xtb.helper.mq5 deleted file mode 100644 index 2adc0864..00000000 --- a/Helpers/x-saherelm.x121.xtb.helper.mq5 +++ /dev/null @@ -1,65 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Helper Class Library -// ---------------------------------------------- -// Name: XCX121XCTBHelper -// Description: provides all Indicator -// Helper requirements ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// Imports ... -#include "../Classes/x-saherelm.x-helper.class.mq5" - -// -// Definitions ... - -// -// Buffers ... -enum ENUM_X121_XTB_BUFFERS -{ - X121_XTB_TREND_LINE = 0, - X121_XTB_SAR_LINE = 2, - X121_XTB_SBAR_O_LINE = 4, - X121_XTB_SBAR_H_LINE = 5, - X121_XTB_SBAR_L_LINE = 6, - X121_XTB_SBAR_C_LINE = 7, - X121_XTB_HK_BAR_O_LINE = 9, - X121_XTB_HK_BAR_H_LINE = 10, - X121_XTB_HK_BAR_L_LINE = 11, - X121_XTB_HK_BAR_C_LINE = 12, - X121_XTB_HK_SBAR_O_LINE = 14, - X121_XTB_HK_SBAR_H_LINE = 15, - X121_XTB_HK_SBAR_L_LINE = 16, - X121_XTB_HK_SBAR_C_LINE = 17, - X121_XTB_ATR_BAND_UPPER_LINE = 19, - X121_XTB_ATR_BAND_LOWER_LINE = 20, - X121_XTB_TREND_STATE_LINE = 21, - X121_XTB_SAR_STATE_LINE = 22, - X121_XTB_RSI_LINE = 23, - X121_XTB_ADX_LINE = 24, - X121_XTB_ADXP_LINE = 25, - X121_XTB_ADXN_LINE = 26, - X121_XTB_DELTA_LINE = 27, - X121_XTB_DELTA_SIGNAL_LINE = 28, - X121_XTB_VOLUME_BULLISH_LINE = 29, - X121_XTB_VOLUME_BEARISH_LINE = 30, - X121_XTB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE = 31, - X121_XTB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE = 32, - X121_XTB_ATR_LINE = 33, - X121_XTB_ATR_BAND_RAW_UPPER_LINE = 34, - X121_XTB_ATR_BAND_RAW_LOWER_LINE = 35, -}; \ No newline at end of file diff --git a/Libraries/x-saherelm.x121.xcatb.lib.mq5 b/Libraries/x-saherelm.x121.xcatb.lib.mq5 index 0e69c47d..c5724551 100644 --- a/Libraries/x-saherelm.x121.xcatb.lib.mq5 +++ b/Libraries/x-saherelm.x121.xcatb.lib.mq5 @@ -29,58 +29,6 @@ // // Definiions ... -// -enum ENUM_XCAEA_TIGGER_TYPE -{ - XCA_TRIGGER_NONE, // None - XCA_TRIGGER_BULL, // TriggerBull - XCA_TRIGGER_BEAR, // TriggerBear -}; - -// -bool IsValid(ENUM_XCAEA_TIGGER_TYPE value) -{ - return value != XCA_TRIGGER_NONE; -} - -// -string ToString(ENUM_XCAEA_TIGGER_TYPE value) -{ - return EnumToString(value); -} - -// -ENUM_XCAEA_TIGGER_TYPE GetType(string type) -{ - // - ENUM_XCAEA_TIGGER_TYPE result = XCA_TRIGGER_NONE; - - // - bool isTriggerBull = type == ToString(XCA_TRIGGER_BULL); - bool isTriggerBear = type == ToString(XCA_TRIGGER_BEAR); - - // - if (isTriggerBull) - { - result = XCA_TRIGGER_BULL; - } - else if (isTriggerBear) - { - result = XCA_TRIGGER_BEAR; - } - - // - return result; -} - -// -ENUM_X_DIRECTION GetDirection(ENUM_XCAEA_TIGGER_TYPE value) -{ - return value == XCA_TRIGGER_BULL - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; -} - // struct XTriggerBlock { @@ -200,9 +148,70 @@ int CountX121TriggerBlocks() } // -void CleanX121TriggerBlocks() +void CleanX121TriggerBlocks(int maxAllowed = 0) { - Clean(mX121TriggerBlocks) l + // + if (maxAllowed <= 0) + { + Clean(mX121TriggerBlocks); + } + else if (maxAllowed > 0) + { + // + CleanupArray( + mX121TriggerBlocks, + maxAllowed // + ); + } +} + +// +bool GetNewestX121TriggerBlock( + string forSymbol, + ENUM_TIMEFRAMES forPeriod, + XTriggerBlock &tb // +) +{ + // + bool result = false; + + // + tb.Clean(); + + // + result = + IsValid(forSymbol) && + IsValid(forPeriod) && + HasX121TriggerBlocks(); + if (!result) + { + return result; + } + + // + // Loop Through Trigger Blocks to Find Filtered Newest ... + int count = CountX121TriggerBlocks(); + for (int i = 0; i < count; i++) + { + // + bool canSet = !tb.IsValid() + ? true + : tb.ToIndex() < mX121TriggerBlocks[i].ToIndex(); + if (canSet) + { + tb = mX121TriggerBlocks[i]; + } + } + + // + result = tb.IsValid(); + if (!result) + { + tb.Clean(); + } + + // + return result; } // @@ -365,7 +374,9 @@ bool DetectTriggerBlock( // Clone Trigger Block ... if (has) { + // tb.trigger = tb.ob; + tb.trigger.type = "XTRGB"; } // @@ -713,29 +724,29 @@ bool DetectTriggerBlock( double rsiTrend = (_rsiOBLevel + _rsiOSLevel) / 2; // - double iRSI = rsiBuffer[barIndex]; - double iPRSI = rsiBuffer[barIndex + 1]; - double iP2RSI = rsiBuffer[barIndex + 2]; + double iRSI = _rsiBuffer[barIndex]; + double iPRSI = _rsiBuffer[barIndex + 1]; + double iP2RSI = _rsiBuffer[barIndex + 2]; // bool isRSICrossedOverOS = - iRSI > rsiOSLevel && - iPRSI <= rsiOSLevel; + iRSI > _rsiOSLevel && + iPRSI <= _rsiOSLevel; // bool isRSICrossedUnderOB = - iRSI < rsiOBLevel && - iPRSI >= rsiOBLevel; + iRSI < _rsiOBLevel && + iPRSI >= _rsiOBLevel; // bool isPRSICrossedOverOS = - iPRSI > rsiOSLevel && - iP2RSI <= rsiOSLevel; + iPRSI > _rsiOSLevel && + iP2RSI <= _rsiOSLevel; // bool isPRSICrossedUnderOB = - iPRSI < rsiOBLevel && - iP2RSI >= rsiOBLevel; + iPRSI < _rsiOBLevel && + iP2RSI >= _rsiOBLevel; // has = @@ -754,36 +765,36 @@ bool DetectTriggerBlock( { // // ADX ... - double iADX = adxBuffer[barIndex]; - double iPADX = adxBuffer[barIndex + 1]; - double iP2ADX = adxBuffer[barIndex + 2]; + double iADX = _adxBuffer[barIndex]; + double iPADX = _adxBuffer[barIndex + 1]; + double iP2ADX = _adxBuffer[barIndex + 2]; // // ADX +DI ... - double iADXP = adxpBuffer[barIndex]; - double iPADXP = adxpBuffer[barIndex + 1]; - double iP2ADXP = adxpBuffer[barIndex + 2]; + double iADXP = _adxpBuffer[barIndex]; + double iPADXP = _adxpBuffer[barIndex + 1]; + double iP2ADXP = _adxpBuffer[barIndex + 2]; // // ADX -DI ... - double iADXN = adxnBuffer[barIndex]; - double iPADXN = adxnBuffer[barIndex + 1]; - double iP2ADXN = adxnBuffer[barIndex + 2]; + double iADXN = _adxnBuffer[barIndex]; + double iPADXN = _adxnBuffer[barIndex + 1]; + double iP2ADXN = _adxnBuffer[barIndex + 2]; // // Preparing Conditions ... // - bool isADXBullish = iADX > adxThreshold; - bool isADXBearish = iADX < adxThreshold; + bool isADXBullish = iADX > _adxThreshold; + bool isADXBearish = iADX < _adxThreshold; // - bool isPADXBullish = iPADX > adxThreshold; - bool isPADXBearish = iPADX < adxThreshold; + bool isPADXBullish = iPADX > _adxThreshold; + bool isPADXBearish = iPADX < _adxThreshold; // - bool isP2ADXBullish = iP2ADX > adxThreshold; - bool isP2ADXBearish = iP2ADX < adxThreshold; + bool isP2ADXBullish = iP2ADX > _adxThreshold; + bool isP2ADXBearish = iP2ADX < _adxThreshold; // bool isADXSwitchedToBullish = @@ -854,12 +865,12 @@ bool DetectTriggerBlock( double trends[]; int toIDX = tb.ToIndex(); int fromIDX = tb.FromIndex(); - double iTrend = trendBuffer[toIDX]; + double iTrend = _trendBuffer[toIDX]; for (int i = toIDX; i <= fromIDX; i++) { // Add( - trendBuffer[i], + _trendBuffer[i], trends // ); } @@ -1077,7 +1088,7 @@ bool DetectTriggerBlock( } // - double iATR = atrBuffer[barIndex]; + double iATR = _atrBuffer[barIndex]; double slAdditional = _slAtrMultiplier * iATR; // @@ -1089,10 +1100,13 @@ bool DetectTriggerBlock( ); // - Add( + // Add Trigger Block to Collection + // and Cleanup Unuseds ... + AddRef( tb, mX121TriggerBlocks // ); + CleanX121TriggerBlocks(20); } // diff --git a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 index 89fb6f88..404f1866 100644 --- a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 +++ b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 @@ -25,7 +25,6 @@ #include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Helpers/xcaea.helper.mq5" -#include "../Libraries/xcaea.trigger.block.lib.mq5" // // Definitions ... diff --git a/XCAEA/Libraries/xcaea.trigger.block.lib.mq5 b/XCAEA/Libraries/xcaea.trigger.block.lib.mq5 deleted file mode 100644 index 82abbc74..00000000 --- a/XCAEA/Libraries/xcaea.trigger.block.lib.mq5 +++ /dev/null @@ -1,1487 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Indicator -// ------------------------------------------------- -// Name: XCAEAHelper Lib -// Description: Library for XCAEA Signaller ... -// -// -// 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 Library for XCAEA Helper" -#property strict - -// -// Imports ... -#include "../../Libraries/x-saherelm.common.lib.mq5" -#include "../Classes/xcaea.x-poi.detector.class.mq5" -#include "../Helpers/xcaea.helper.mq5" - -// -// Definitions ... -enum ENUM_XCAEA_TIGGER_TYPE -{ - XCA_TRIGGER_NONE, // None - XCA_TRIGGER_BULL, // TriggerBull - XCA_TRIGGER_BEAR, // TriggerBear -}; - -// -bool IsValid(ENUM_XCAEA_TIGGER_TYPE value) -{ - return value != XCA_TRIGGER_NONE; -} - -// -string ToString(ENUM_XCAEA_TIGGER_TYPE value) -{ - return EnumToString(value); -} - -// -ENUM_XCAEA_TIGGER_TYPE GetType(string type) -{ - // - ENUM_XCAEA_TIGGER_TYPE result = XCA_TRIGGER_NONE; - - // - bool isTriggerBull = type == ToString(XCA_TRIGGER_BULL); - bool isTriggerBear = type == ToString(XCA_TRIGGER_BEAR); - - // - if (isTriggerBull) - { - result = XCA_TRIGGER_BULL; - } - else if (isTriggerBear) - { - result = XCA_TRIGGER_BEAR; - } - - // - return result; -} - -// -ENUM_X_DIRECTION GetDirection(ENUM_XCAEA_TIGGER_TYPE value) -{ - return value == XCA_TRIGGER_BULL - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; -} - -// -// Structues ... -struct XCAEATriggerBlockConfiguration -{ - // - // Props ... - - // - // Trigger Detection ... - - // - double maxAllowedRange; // Maximum Allowed Range - int minAllowedBlockEdgeLength; // Minimum Required Block Edge Length - - // - // Validation ... - bool forceOBOppositBar; // Force OB to Start by Opposit Bars - bool forceFVGBarType; // Force FVG to Has Same Type of Bars - bool forceGapBarBreakout; // Force FVG's Gap Bar to Breakeout OB Edge Side - bool forceHasSwingBar; // Force Has Propper Swing - bool forceHasLiquidity; // Force Has Following Liquidity Zone - bool forceHasReversalLiquidity; // Force Has Reversal Liquidity Zone - - // - // Filtering ... - bool filterBasedOnSar; // Filter Trigger Block Based on Sar - bool filterBasedOnRSI; // Filter Trigger Block Based on RSI - bool filterBasedOnADX; // Filter Trigger Block Based on ADX - bool filterBasedOnTrend; // Filter Trigger Block Based on Trend - bool filterBasedOnScores; // Filter Trigger Block Based on Scores - bool filterBasedOnVolumes; // Filter Trigger Block Based on Volumes - - // - double targets[]; // Targets Collection for R:R on Signal Preparation - - // - // Constructor ... - XCAEATriggerBlockConfiguration() - { - Clean(); - } - - // - // Tools ... - - // - // Cleanup ... - void Clean() - { - // - // Validating ... - maxAllowedRange = false; - minAllowedBlockEdgeLength = false; - - // - forceOBOppositBar = false; - forceFVGBarType = false; - forceGapBarBreakout = false; - forceHasSwingBar = false; - forceHasLiquidity = false; - forceHasReversalLiquidity = false; - - // - // Filtering ... - filterBasedOnSar = false; - filterBasedOnRSI = false; - filterBasedOnADX = false; - filterBasedOnTrend = false; - filterBasedOnScores = false; - filterBasedOnVolumes = false; - - // - Clean(targets); - - // - ZeroMemory(this); - } - - // - // Preset Configurations ... - - // -}; - -// -struct XTriggerBlock -{ - // - // Props ... - XBoxZone ob; // Order Block - XBoxZone fvg; // Fair Value Gap - XOHCL swingBar; // Swing of Trigger - XBoxZone trigger; // Trigger Block - XBoxZone rLiquidity; // Reversal Liquidity - XBoxZone fLiquidity; // Following Liquidity - XCAEAConditions conditions; // Market Conditions - XCAEATriggerBlockConfiguration configuration; // Detection Configuration - - // - XSignal signal; // Pepared Signal - - // - // Constructor ... - XTriggerBlock() - { - Clean(); - } - - // - // Tools ... - - // - // Cleanup ... - void Clean() - { - // - ob.Clean(); - fvg.Clean(); - signal.Clean(); - trigger.Clean(); - swingBar.Clean(); - rLiquidity.Clean(); - fLiquidity.Clean(); - conditions.Clean(); - - // - ZeroMemory(this); - } - - // - // Validate ... - bool IsValid() - { - // - bool result = false; - - // - result = ob.IsValid() && - fvg.IsValid() && - trigger.IsValid(); - - // - return result; - } - - // -}; - -// -// Extensions ... - -/** - * Detect Trigger Block ... - * - * @param trigger: XTriggerBlock instance Reference, hold founded Trigger Block - * @param helper: XCXCAEAHelper instance Reference Pointer, XCAEA Market nalyser Helper for acc Drawer - * @param config: XCAEATriggerBlockConfiguration instance Reference, Trigger Block Detecting Configuration - * @param bar_index: int, Bar Index to Start Detecting - * @param loopback: int, Loopback Bars Count - * - * @return ( bool ) - */ -bool DetectTriggerBlock( - XTriggerBlock &trigger, - XCXCAEAHelper *helper, - XCAEATriggerBlockConfiguration &config, - int bar_index = 0, - int loopback = 10, - double slAdditionalPoint = 0, - double slATRMultiplier = 0 // -) -{ - // - bool result = false; - - // - // Normalize Args ... - trigger.Clean(); - loopback = NormalizeInt(loopback, 10); - bar_index = NormalizeInt(bar_index, 0); - - // - // Validate Args ... - result = helper != NULL; - if (!result) - { - return result; - } - - // - // Extract Required Informations ... - - // - string symbol = helper.GetSymbol(); - ENUM_TIMEFRAMES period = helper.GetPeriod(); - - // - double points = GetPoints(symbol); - - // - // Retrieve Indexed Bar ... - XOHCL zBar; - XOHCL cBar; - XOHCL pBar; - XOHCL p2Bar; - result = zBar.Init( - symbol, - period, - bar_index // - ); - result = result && - zBar.GetPreviousBar(cBar); - result = result && - cBar.GetPreviousBar(pBar); - result = result && - pBar.GetPreviousBar(p2Bar); - - // - int zIDX = 0; - int cIDX = zIDX + 1; - int pIDX = cIDX + 1; - int p2IDX = pIDX + 1; - int p3IDX = p2IDX + 1; - int p4IDX = p3IDX + 1; - - // - // Check Trigger Block Exists ... - result = - result && - helper - .barAnalyser - .IsTrigger( - zBar, - trigger.trigger, - trigger.ob, - trigger.fvg, - trigger.rLiquidity, - trigger.fLiquidity, - trigger.swingBar, - loopback, - config.maxAllowedRange, - config.minAllowedBlockEdgeLength, - config.forceOBOppositBar, - config.forceFVGBarType, - config.forceGapBarBreakout, - config.forceHasSwingBar, - config.forceHasLiquidity, - config.forceHasReversalLiquidity // - ); - - // - // Now we Have to Implement Required Validations ... - - // - bool isBullish = trigger.trigger.IsBullish(); - bool isBearish = trigger.trigger.IsBearish(); - - // - // First Reading Market Conditions ... - result = - result && - helper.GetConditions( - trigger.conditions, - bar_index, - loopback // - ); - - // - // All Custom andAdditional Validations and Filters - // Applied here ... - - // - // SAR Filter ... - if (config.filterBasedOnSar) - { - // - if (result) - { - // - // Reading Values ... - - // - double zSar = trigger.conditions.sarBuffer[zIDX]; - double cSar = trigger.conditions.sarBuffer[cIDX]; - double pSar = trigger.conditions.sarBuffer[pIDX]; - double p2Sar = trigger.conditions.sarBuffer[p2IDX]; - double p3Sar = trigger.conditions.sarBuffer[p3IDX]; - double p4Sar = trigger.conditions.sarBuffer[p4IDX]; - - // - // Preparing Conditions ... - - // - bool isZSarBullish = zSar < zBar.low; - bool isZSarBearish = zSar > zBar.high; - - // - bool isCSarBullish = cSar < cBar.low; - bool isCSarBearish = cSar > cBar.high; - - // - bool isPSarBullish = pSar < pBar.low; - bool isPSarBearish = pSar > pBar.high; - - // - bool isP2SarBullish = p2Sar < p2Bar.low; - bool isP2SarBearish = p2Sar > p2Bar.high; - - // - bool isCSarSwitchedToBullish = - isZSarBullish && - isCSarBullish && - !isPSarBullish && - cBar.IsBullish() && - cBar.GetUp() > pSar; - - // - bool isCSarSwitchedToBearish = - isZSarBearish && - isCSarBearish && - !isPSarBearish && - cBar.IsBearish() && - cBar.GetDown() < pSar; - - // - bool isPSarSwitchedToBullish = - isZSarBullish && - isCSarBullish && - isPSarBullish && - !isP2SarBullish && - pBar.IsBullish() && - pBar.GetUp() > p2Sar; - - // - bool isPSarSwitchedToBearish = - isZSarBearish && - isCSarBearish && - isPSarBearish && - !isP2SarBearish && - pBar.IsBearish() && - pBar.GetDown() < p2Sar; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - (isCSarSwitchedToBullish || - isPSarSwitchedToBullish); - - // - bool isBearishFilterd = - isBearish && - (isCSarSwitchedToBearish || - isPSarSwitchedToBearish); - - // - // Apply Result .... - - // - result = - result && - (isBullishFilterd || - isBearishFilterd); - } - } - - // - // RSI Filter ... - if (config.filterBasedOnRSI) - { - // - if (result) - { - // - // Reading Values ... - - // - double rsiTrend = (trigger.conditions.rsiOBLevel + trigger.conditions.rsiOSLevel) / 2; - - // - double zRSI = trigger.conditions.rsiBuffer[zIDX]; - double cRSI = trigger.conditions.rsiBuffer[cIDX]; - double pRSI = trigger.conditions.rsiBuffer[pIDX]; - double p2RSI = trigger.conditions.rsiBuffer[p2IDX]; - double p3RSI = trigger.conditions.rsiBuffer[p3IDX]; - double p4RSI = trigger.conditions.rsiBuffer[p4IDX]; - - // - // Preparing Conditions ... - - // - bool isZRSIBullish = zRSI > rsiTrend; - bool isZRSIBearish = zRSI < rsiTrend; - - // - bool isCRSIBullish = cRSI > rsiTrend; - bool isCRSIBearish = cRSI < rsiTrend; - - // - bool isPRSIBullish = pRSI > rsiTrend; - bool isPRSIBearish = pRSI < rsiTrend; - - // - bool isP2RSIBullish = p2RSI > rsiTrend; - bool isP2RSIBearish = p2RSI < rsiTrend; - - // - bool isP3RSIBullish = p3RSI > rsiTrend; - bool isP3RSIBearish = p3RSI < rsiTrend; - - // - // Trending Conditions ... - - // - bool isCRSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - !isPRSIBullish; - - // - bool isCRSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - !isPRSIBearish; - - // - bool isPRSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - isPRSIBullish && - !isP2RSIBullish; - - // - bool isPRSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - isPRSIBearish && - !isP2RSIBearish; - - // - bool isP2RSISwitchedToBullish = - isZRSIBullish && - isCRSIBullish && - isPRSIBullish && - isP2RSIBullish && - !isP3RSIBullish; - - // - bool isP2RSISwitchedToBearish = - isZRSIBearish && - isCRSIBearish && - isPRSIBearish && - isP2RSIBearish && - !isP3RSIBearish; - - // - // Crosses Conditions ... - - // - bool isCBarCrossedOverOS = - zRSI > trigger.conditions.rsiOSLevel && - cRSI > trigger.conditions.rsiOSLevel && - pRSI <= trigger.conditions.rsiOSLevel; - - // - bool isCBarCrossedUnderOB = - zRSI < trigger.conditions.rsiOBLevel && - cRSI < trigger.conditions.rsiOBLevel && - pRSI >= trigger.conditions.rsiOBLevel; - - // - bool isPBarCrossedOverOS = - zRSI > trigger.conditions.rsiOSLevel && - cRSI > trigger.conditions.rsiOSLevel && - pRSI > trigger.conditions.rsiOSLevel && - p2RSI <= trigger.conditions.rsiOSLevel; - - // - bool isPBarCrossedUnderOB = - zRSI < trigger.conditions.rsiOBLevel && - cRSI < trigger.conditions.rsiOBLevel && - pRSI < trigger.conditions.rsiOBLevel && - p2RSI >= trigger.conditions.rsiOBLevel; - - // - // V Pattern Conditions ... - - // - bool isCRSIHasVBullishPattern = - zRSI >= cRSI && - cRSI > pRSI && - p2RSI > pRSI && - cRSI >= p2RSI; - - // - bool isCRSIHasVBearishPattern = - zRSI <= cRSI && - cRSI < pRSI && - p2RSI < pRSI && - cRSI <= p2RSI; - - // - // Continuation Conditions ... - - // - bool isRSIUp = - zRSI >= cRSI && - (cRSI >= pRSI || - pRSI >= p2RSI || - p2RSI >= p3RSI); - - // - bool isRSIDown = - zRSI <= cRSI && - (cRSI <= pRSI || - pRSI <= p2RSI || - p2RSI <= p3RSI); - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isRSIUp - // - || - // - // Crosses ... - (isCBarCrossedOverOS || - isPBarCrossedOverOS) - // - || - // - // V Pattern ... - isCRSIHasVBullishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBullish || - isPRSISwitchedToBullish || - isP2RSISwitchedToBullish) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isRSIDown - // - || - // - // Crosses ... - (isCBarCrossedUnderOB || - isPBarCrossedUnderOB) - // - || - // - // V Pattern ... - isCRSIHasVBearishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBearish || - isPRSISwitchedToBearish || - isP2RSISwitchedToBearish) - // - ); - - // - // Apply Result .... - - // - result = - result && - (isBullishFilterd || - isBearishFilterd); - } - } - - // - // ADX Filter ... - if (config.filterBasedOnADX) - { - // - if (result) - { - // - // Reading Values ... - - // - // ADX ... - double zADX = trigger.conditions.adxBuffer[zIDX]; - double cADX = trigger.conditions.adxBuffer[cIDX]; - double pADX = trigger.conditions.adxBuffer[pIDX]; - double p2ADX = trigger.conditions.adxBuffer[p2IDX]; - double p3ADX = trigger.conditions.adxBuffer[p3IDX]; - double p4ADX = trigger.conditions.adxBuffer[p4IDX]; - - // - // ADX +DI ... - double zADXP = trigger.conditions.adxpBuffer[zIDX]; - double cADXP = trigger.conditions.adxpBuffer[cIDX]; - double pADXP = trigger.conditions.adxpBuffer[pIDX]; - double p2ADXP = trigger.conditions.adxpBuffer[p2IDX]; - double p3ADXP = trigger.conditions.adxpBuffer[p3IDX]; - double p4ADXP = trigger.conditions.adxpBuffer[p4IDX]; - - // - // ADX -DI ... - double zADXN = trigger.conditions.adxnBuffer[zIDX]; - double cADXN = trigger.conditions.adxnBuffer[cIDX]; - double pADXN = trigger.conditions.adxnBuffer[pIDX]; - double p2ADXN = trigger.conditions.adxnBuffer[p2IDX]; - double p3ADXN = trigger.conditions.adxnBuffer[p3IDX]; - double p4ADXN = trigger.conditions.adxnBuffer[p4IDX]; - - // - // Preparing Conditions ... - - // - // Grows ... - - // - bool isADXUp = - zADX >= cADX && - (cADX >= pADX || - pADX >= p2ADX); - - // - bool isADXDown = - zADX <= cADX && - (cADX <= pADX || - pADX <= p2ADX); - - // - // Trending ... - - // - bool isZADXBullish = zADX > trigger.conditions.adxThreshold; - bool isZADXBearish = zADX < trigger.conditions.adxThreshold; - - // - bool isCADXBullish = cADX > trigger.conditions.adxThreshold; - bool isCADXBearish = cADX < trigger.conditions.adxThreshold; - - // - bool isPADXBullish = pADX > trigger.conditions.adxThreshold; - bool isPADXBearish = pADX < trigger.conditions.adxThreshold; - - // - bool isP2ADXBullish = p2ADX > trigger.conditions.adxThreshold; - bool isP2ADXBearish = p2ADX < trigger.conditions.adxThreshold; - - // - bool isP3ADXBullish = p3ADX > trigger.conditions.adxThreshold; - bool isP3ADXBearish = p3ADX < trigger.conditions.adxThreshold; - - // - bool isP4ADXBullish = p4ADX > trigger.conditions.adxThreshold; - bool isP4ADXBearish = p4ADX < trigger.conditions.adxThreshold; - - // - bool isCADXSwitchedToBullish = - isZADXBullish && - isCADXBullish && - !isPADXBullish; - - // - bool isCADXSwitchedToBearish = - isZADXBearish && - isCADXBearish && - !isPADXBearish; - - // - bool isPADXSwitchedToBullish = - isZADXBullish && - isCADXBullish && - isPADXBullish && - !isP2ADXBullish; - - // - bool isPADXSwitchedToBearish = - isZADXBearish && - isCADXBearish && - isPADXBearish && - !isP2ADXBearish; - - // - // Powering ... - - // - bool isZADXHasBullishPower = zADXP > zADXN; - bool isZADXHasBearishPower = zADXN > zADXP; - - // - bool isCADXHasBullishPower = cADXP > cADXN; - bool isCADXHasBearishPower = cADXN > cADXP; - - // - bool isPADXHasBullishPower = pADXP > pADXN; - bool isPADXHasBearishPower = pADXN > pADXP; - - // - bool isP2ADXHasBullishPower = p2ADXP > p2ADXN; - bool isP2ADXHasBearishPower = p2ADXN > p2ADXP; - - // - bool isP3ADXHasBullishPower = p3ADXP > p3ADXN; - bool isP3ADXHasBearishPower = p3ADXN > p3ADXP; - - // - bool isP4ADXHasBullishPower = p4ADXP > p4ADXN; - bool isP4ADXHasBearishPower = p4ADXN > p4ADXP; - - // - bool isCADXSwitchedToBullishPower = - isZADXHasBullishPower && - isCADXHasBullishPower && - !isPADXHasBullishPower; - - // - bool isCADXSwitchedToBearishPower = - isZADXHasBearishPower && - isCADXHasBearishPower && - !isPADXHasBearishPower; - - // - bool isPADXSwitchedToBullishPower = - isZADXHasBullishPower && - isCADXHasBullishPower && - isPADXHasBullishPower && - !isP2ADXHasBullishPower; - - // - bool isPADXSwitchedToBearishPower = - isZADXHasBearishPower && - isCADXHasBearishPower && - isPADXHasBearishPower && - !isP2ADXHasBearishPower; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isADXUp - // - || - // - // Trending ... - (isCADXSwitchedToBullish || - isPADXSwitchedToBullish) - // - || - // - // Powering ... - (isCADXSwitchedToBullishPower || - isPADXSwitchedToBullishPower) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isADXDown - // - || - // - // Trending ... - (isCADXSwitchedToBearish || - isPADXSwitchedToBearish) - // - || - // - // Powering ... - (isCADXSwitchedToBearishPower || - isPADXSwitchedToBearishPower) - // - ); - - // - // Apply Result .... - - // - result = - result && - (isBullishFilterd || - isBearishFilterd); - } - } - - // - // TREND Filter ... - if (config.filterBasedOnTrend) - { - // - if (result) - { - // - // Reading Values ... - - // - double zTrend = trigger.conditions.trendBuffer[zIDX]; - double cTrend = trigger.conditions.trendBuffer[cIDX]; - double pTrend = trigger.conditions.trendBuffer[pIDX]; - double p2Trend = trigger.conditions.trendBuffer[p2IDX]; - double p3Trend = trigger.conditions.trendBuffer[p3IDX]; - double p4Trend = trigger.conditions.trendBuffer[p4IDX]; - - // - double trends[] = { - zTrend, - cTrend, - pTrend, - p2Trend, - p3Trend, - p4Trend // - }; - double trendsMin = GetMin(trends); - double trendsMax = GetMax(trends); - double trendsAVG = GetAverage(trends); - - // - double zTrendState = trigger.conditions.trendStateBuffer[zIDX]; - double cTrendState = trigger.conditions.trendStateBuffer[cIDX]; - double pTrendState = trigger.conditions.trendStateBuffer[pIDX]; - double p2TrendState = trigger.conditions.trendStateBuffer[p2IDX]; - double p3TrendState = trigger.conditions.trendStateBuffer[p3IDX]; - double p4TrendState = trigger.conditions.trendStateBuffer[p4IDX]; - - // - // Preparing Conditions ... - - // - // Grows ... - - // - bool isTrendUp = - zTrend >= cTrend && - cTrend >= trendsAVG && - cTrend > trendsMin; - - // - bool isTrendDown = - zTrend <= cTrend && - cTrend <= trendsAVG && - cTrend < trendsMax; - - // - // Stating ... - - // - bool isCTrendBullish = - zTrendState > 0 && - cTrendState > 0; - - // - bool isCTrendBearish = - zTrendState < 0 && - cTrendState < 0; - - // - bool isPTrendBullish = - zTrendState > 0 && - cTrendState > 0 && - pTrendState > 0; - - // - bool isPTrendBearish = - zTrendState < 0 && - cTrendState < 0 && - pTrendState < 0; - - // - bool isP2TrendBullish = - zTrendState > 0 && - cTrendState > 0 && - pTrendState > 0 && - p2TrendState > 0; - - // - bool isP2TrendBearish = - zTrendState < 0 && - cTrendState < 0 && - pTrendState < 0 && - p2TrendState < 0; - - // - bool isCTrendSwitchedToBullish = - isCTrendBullish && - !isPTrendBullish; - - // - bool isCTrendSwitchedToBearish = - isCTrendBearish && - !isPTrendBearish; - - // - bool isPTrendSwitchedToBullish = - isCTrendBullish && - isPTrendBullish && - !isP2TrendBullish; - - // - bool isPTrendSwitchedToBearish = - isCTrendBearish && - isPTrendBearish && - !isP2TrendBearish; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - ( - // - // Grows ... - isTrendUp - // - || - // - // Trend Stating ... - (isCTrendBullish && - isPTrendBullish) - // - || - // - // Switching ... - (isCTrendSwitchedToBullish || - isPTrendSwitchedToBullish) - // - ); - - // - bool isBearishFilterd = - isBearish && - ( - // - // Grows ... - isTrendDown - // - || - // - // Trend Stating ... - (isCTrendBearish && - isPTrendBearish) - // - || - // - // Switching ... - (isCTrendSwitchedToBearish || - isPTrendSwitchedToBearish) - // - ); - - // - // Apply Result .... - - // - result = - result && - (isBullishFilterd || - isBearishFilterd); - } - } - - // - // SCORE Filter ... - if (config.filterBasedOnScores) - { - // - if (result) - { - // - // Reading Values ... - - // - double bullishScore = 0; - double bearishScore = 0; - - // - trigger.conditions.GenerateScore( - bullishScore, - bearishScore // - ); - - // - // Preparing Conditions ... - - // - bool isScoreBullish = bullishScore > bearishScore; - bool isScoreBearish = bearishScore > bullishScore; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - isScoreBullish; - - // - bool isBearishFilterd = - isBearish && - isScoreBearish; - - // - // Apply Result .... - - // - result = - result && - (isBullishFilterd || - isBearishFilterd); - } - } - - // - // VOLUME Filter ... - if (config.filterBasedOnVolumes) - { - // - if (result) - { - // - // Reading Values ... - - // - double bullishVolume = 0; - double bearishVolume = 0; - - // - helper - .barAnalyser - .CalculateRangeVolume( - zBar, - bullishVolume, - bearishVolume, - loopback // - ); - - // - // Preparing Conditions ... - - // - bool isVolumeBullish = bullishVolume > bearishVolume; - bool isVolumeBearish = bearishVolume > bullishVolume; - - // - // Summarize Filtering ... - - // - bool isBullishFilterd = - isBullish && - isVolumeBullish; - - // - bool isBearishFilterd = - isBearish && - isVolumeBearish; - - // - // Apply Result .... - - // - result = - result && - (isBullishFilterd || - isBearishFilterd); - } - } - - // - // Cleanup Resources ... - - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - - // - if (!result) - { - trigger.Clean(); - } - - // - // Attach Configuration if Trigger Block Founded ... - if (result) - { - // - trigger.configuration = config; - - // - // Prepare Trigger Signal ... - if (HasChild(config.targets)) - { - // - // Calculating Additional SL Value for Signals ... - double additionalSL = 0; - if (slATRMultiplier > 0) - { - // - double cATR = trigger.conditions.atrBuffer[cIDX]; - additionalSL += (cATR * slATRMultiplier); - } - if (slAdditionalPoint > 0) - { - additionalSL += (slAdditionalPoint * points); - } - - // - ToSignal( - trigger.trigger, - trigger.signal, - config.targets, - additionalSL // - ); - } - } - - // - return result; -} - -/** - * Draw Specified Trigger Block ... - * - * @param trigger: XTriggerBlock instance Reference, specified Trigger Block to Draw - * @param objects: CArrayObj instance Reference Pointer, Objects Array for Providing Drawn Objects - * @param helper: XCXCAEAHelper instance Reference Pointer, XCAEA Market nalyser Helper for acc Drawer - * @param to: datetime, specified Time for update Trigger parts - * - * @return ( bool ) - */ -bool DrawTriggerBlock( - XTriggerBlock &trigger, - CArrayObj *&objects, - XCXCAEAHelper *helper, - datetime to = NULL, - int rrZoneLength = 10 // -) -{ - // - bool result = false; - - // - // Validate Args ... - result = helper != NULL && - trigger.IsValid(); - if (!result) - { - return result; - } - - // - // Update To ... - bool canUpdateTo = IsValid(to); - if (canUpdateTo) - { - // - trigger.trigger.to = to; - trigger.rLiquidity.to = to; - trigger.fLiquidity.to = to; - } - - // - // Draw OB ... - if (trigger.ob.IsValid()) - { - // - XCBoxObject *iOBObj; - result = helper.poiDrawer.DrawBox( - trigger.ob, - iOBObj // - ); - if (result) - { - objects.Add(iOBObj); - } - ZeroMemory(iOBObj); - - // - if (!result) - { - return result; - } - } - - // - // Draw FVG ... - if (trigger.fvg.IsValid()) - { - // - XCBoxObject *iFVGObj; - result = helper.poiDrawer.DrawBox( - trigger.fvg, - iFVGObj // - ); - if (result) - { - // - // Style Object ... - color clr = - trigger.fvg.IsBullish() - ? clrAqua - : clrMagenta; - iFVGObj.BoxWidth(2); - iFVGObj.BoxColor(clr); - iFVGObj.BoxStyle(STYLE_SOLID); - - // - // Store Object ... - objects.Add(iFVGObj); - } - ZeroMemory(iFVGObj); - - // - if (!result) - { - return result; - } - } - - // - // Draw Trigger ... - if (trigger.trigger.IsValid()) - { - // - XCBoxObject *iTriggerObj; - result = helper.poiDrawer.DrawBox( - trigger.trigger, - iTriggerObj // - ); - if (result) - { - objects.Add(iTriggerObj); - } - ZeroMemory(iTriggerObj); - - // - if (!result) - { - return result; - } - } - - // - // Draw Liquidities ... - - // - // Reversla Liquidity ... - if (trigger.rLiquidity.IsValid()) - { - // - XCBoxObject *iLiqObj; - result = helper.poiDrawer.DrawBox( - trigger.rLiquidity, - iLiqObj // - ); - if (result) - { - objects.Add(iLiqObj); - } - ZeroMemory(iLiqObj); - - // - if (!result) - { - return result; - } - } - - // - // Following Liquidity ... - if (trigger.fLiquidity.IsValid()) - { - // - XCBoxObject *iLiqObj; - result = helper.poiDrawer.DrawBox( - trigger.fLiquidity, - iLiqObj // - ); - if (result) - { - objects.Add(iLiqObj); - } - ZeroMemory(iLiqObj); - - // - if (!result) - { - return result; - } - } - - // - // Draw Swing Bar ... - if (trigger.swingBar.IsValid()) - { - // - color swingColor = - trigger.fvg.IsBullish() - ? clrAqua - : clrMagenta; - ENUM_X_PRICE swingPType = - trigger.fvg.IsBullish() - ? X_PRICE_LOW - : X_PRICE_HIGH; - - // - XCBarArrowObject *swingObj; - result = helper.poiDrawer.CreateBarArrow( - trigger.swingBar, - swingObj, - swingPType, - 159, - swingColor // - ); - if (result) - { - objects.Add(swingObj); - } - ZeroMemory(swingObj); - - // - if (!result) - { - return result; - } - } - - // - // Draw RR of Signal ... - if (trigger.signal.IsValid() && - rrZoneLength > 0) - { - // - XCRRObject *iRRObj; - iRRObj = new XCRRObject(); - result = iRRObj.Create( - helper.poiDrawer.ChartIdentification(), - helper.poiDrawer.SubWindowIdentification(), - trigger.signal, - rrZoneLength // - ); - if (result) - { - // - int iWidth = 2; - ENUM_LINE_STYLE iStyle = STYLE_SOLID; - - // - iRRObj.TPWidth(iWidth); - iRRObj.SLWidth(iWidth); - iRRObj.EntryWidth(iWidth); - iRRObj.TargetWidth(iWidth); - - // - iRRObj.TPStyle(iStyle); - iRRObj.SLStyle(iStyle); - iRRObj.EntryStyle(iStyle); - iRRObj.TargetStyle(iStyle); - - // - iRRObj.TPColor(clrLime); - iRRObj.SLColor(clrRed); - iRRObj.EntryColor(clrYellow); - iRRObj.TargetColor(clrLightBlue); - - // - objects.Add(iRRObj); - } - ZeroMemory(iRRObj); - - // - if (result) - { - return result; - } - } - - // - return result; -} - -// \ No newline at end of file