/////////////////////////////////////////////////////// // // 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; } //