/////////////////////////////////////////////////////// // // 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 ... // // 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 Pivots Based on Sar bool filterBasedOnRSI; // Filter Pivots Based on RSI bool filterBasedOnADX; // Filter Pivots Based on ADX bool filterBasedOnTrend; // Filter Pivots Based on Trend // // 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; } // }; // // 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; // return result; } //