From 1c6a60cf1a355611d9f57d611ec884a2ec236847 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 18 May 2025 18:35:34 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-cobject.class.mq5 | 6 +- .../test.mq5 => Documents/BKP/test.1.mq5 | 0 Experts/x-saherelm.xcaea.ea.mq5 | 5 +- XCAEA/Classes/xcaea.x-poi.detector.class.mq5 | 25 +- XCAEA/Libraries/xcaea.trigger.block.lib.mq5 | 1484 +++++++++++++++++ XCAEA/Signals/xcaea.signaller.class.mq5 | 109 +- 6 files changed, 1542 insertions(+), 87 deletions(-) rename Indicators/test.mq5 => Documents/BKP/test.1.mq5 (100%) create mode 100644 XCAEA/Libraries/xcaea.trigger.block.lib.mq5 diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 9088424c..d23bcd57 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -219,9 +219,6 @@ bool ToSignal( // double points = GetPoints(box.symbol); - // - double risk = box.GetRange(); - // double entry = isBullish @@ -235,6 +232,9 @@ bool ToSignal( ? box.lower : box.upper; + // + double risk = MathAbs(entry - sl); + // double tp = 0; diff --git a/Indicators/test.mq5 b/Documents/BKP/test.1.mq5 similarity index 100% rename from Indicators/test.mq5 rename to Documents/BKP/test.1.mq5 diff --git a/Experts/x-saherelm.xcaea.ea.mq5 b/Experts/x-saherelm.xcaea.ea.mq5 index 02bbd3fb..c2de1afd 100644 --- a/Experts/x-saherelm.xcaea.ea.mq5 +++ b/Experts/x-saherelm.xcaea.ea.mq5 @@ -264,10 +264,7 @@ void OnTick() // // Detect Signal Setups ... - has = eaSignallers[is].DetectSignalSetup( - r2r, - 300 // Max Allowed SL Distance ... - ); + has = eaSignallers[is].DetectSignalSetup(r2r); if (has) { // diff --git a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 index c5701267..89fb6f88 100644 --- a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 +++ b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 @@ -25,6 +25,7 @@ #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 ... @@ -45,8 +46,6 @@ enum ENUM_XCA_PIVOTS XCA_RSI_CUOB, // RSICUOB XCA_TREND_BULL, // TrendBull XCA_TREND_BEAR, // TrendBear - XCA_TRIGGER_BULL, // TriggerBull - XCA_TRIGGER_BEAR, // TriggerBear }; // @@ -91,7 +90,6 @@ ENUM_X_DIRECTION GetDirection(ENUM_XCA_PIVOTS value) case XCA_FVG_BULL: case XCA_RSI_COOS: case XCA_TREND_BULL: - case XCA_TRIGGER_BULL: result = X_DIRECTION_BULLISH; break; @@ -102,7 +100,6 @@ ENUM_X_DIRECTION GetDirection(ENUM_XCA_PIVOTS value) case XCA_FVG_BEAR: case XCA_RSI_CUOB: case XCA_TREND_BEAR: - case XCA_TRIGGER_BEAR: result = X_DIRECTION_BEARISH; break; } @@ -145,12 +142,6 @@ string GetBoxType(ENUM_XCA_PIVOTS value) case XCA_TREND_BEAR: result = "XCA_TREND"; break; - - // - case XCA_TRIGGER_BULL: - case XCA_TRIGGER_BEAR: - result = "XCA_TRIGGER"; - break; } // @@ -195,10 +186,6 @@ ENUM_XCA_PIVOTS GetPivotType(XBoxZone &value) value.dir == GetDirection(XCA_TREND_BULL); bool isTrendBearish = value.type == GetBoxType(XCA_TREND_BEAR) && value.dir == GetDirection(XCA_TREND_BEAR); - bool isTriggerBullish = value.type == GetBoxType(XCA_TRIGGER_BULL) && - value.dir == GetDirection(XCA_TRIGGER_BULL); - bool isTriggerBearish = value.type == GetBoxType(XCA_TRIGGER_BEAR) && - value.dir == GetDirection(XCA_TRIGGER_BEAR); // if (isSWL) @@ -249,14 +236,6 @@ ENUM_XCA_PIVOTS GetPivotType(XBoxZone &value) { result = XCA_TREND_BEAR; } - else if (isTriggerBullish) - { - result = XCA_TRIGGER_BULL; - } - else if (isTriggerBearish) - { - result = XCA_TRIGGER_BEAR; - } // return result; @@ -1023,7 +1002,7 @@ class XCXCAEAPOIDetector : public XCBase // continue; } - + // // Checking Pivots ... diff --git a/XCAEA/Libraries/xcaea.trigger.block.lib.mq5 b/XCAEA/Libraries/xcaea.trigger.block.lib.mq5 new file mode 100644 index 00000000..be28d947 --- /dev/null +++ b/XCAEA/Libraries/xcaea.trigger.block.lib.mq5 @@ -0,0 +1,1484 @@ +/////////////////////////////////////////////////////// +// +// 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; + } + + // +}; + +// +// 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 = + has && + triggerBlock.IsBullish(); + + // + bool isBearish = + has && + triggerBlock.IsBearish(); + + // + int toIDX = triggerBlock.ToIndex(); + int fromIDX = triggerBlock.FromIndex(); + + // + // Start Validating ... + + // + // Validating p2Bar and p3Bar Direction ... + if (result) + { + // + iDir = Opposit(triggerBlock.dir); + + // + has = + 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 Filtered 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 isBullishFiltered = + isBullish && + (isCSarSwitchedToBullish || + isPSarSwitchedToBullish); + + // + bool isBearishFiltered = + isBearish && + (isCSarSwitchedToBearish || + isPSarSwitchedToBearish); + + // + result = + isBullishFiltered || + isBearishFiltered; + 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 isBullishFiltered = + isBullish && + ( + // + // Grows ... + isRSIUp + // + || + // + // Crosses ... + (isCBarCrossedOverOS || + isPBarCrossedOverOS) + // + || + // + // V Pattern ... + isCRSIHasVBullishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBullish || + isPRSISwitchedToBullish || + isP2RSISwitchedToBullish) + // + ); + + // + bool isBearishFiltered = + isBearish && + ( + // + // Grows ... + isRSIDown + // + || + // + // Crosses ... + (isCBarCrossedUnderOB || + isPBarCrossedUnderOB) + // + || + // + // V Pattern ... + isCRSIHasVBearishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBearish || + isPRSISwitchedToBearish || + isP2RSISwitchedToBearish) + // + ); + + // + result = + isBullishFiltered || + isBearishFiltered; + 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 isBullishFiltered = + isBullish && + ( + // + // Grows ... + isADXUp + // + || + // + // Trending ... + (isCADXSwitchedToBullish || + isPADXSwitchedToBullish) + // + || + // + // Powering ... + (isCADXSwitchedToBullishPower || + isPADXSwitchedToBullishPower) + // + ); + + // + bool isBearishFiltered = + isBearish && + ( + // + // Grows ... + isADXDown + // + || + // + // Trending ... + (isCADXSwitchedToBearish || + isPADXSwitchedToBearish) + // + || + // + // Powering ... + (isCADXSwitchedToBearishPower || + isPADXSwitchedToBearishPower) + // + ); + + // + result = + isBullishFiltered || + isBearishFiltered; + 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 isBullishFiltered = + isBullish && + ( + // + // Grows ... + isTrendUp + // + || + // + // Trend Stating ... + (isCTrendBullish && + isPTrendBullish) + // + || + // + // Switching ... + (isCTrendSwitchedToBullish || + isPTrendSwitchedToBullish) + // + ); + + // + bool isBearishFiltered = + isBearish && + ( + // + // Grows ... + isTrendDown + // + || + // + // Trend Stating ... + (isCTrendBearish && + isPTrendBearish) + // + || + // + // Switching ... + (isCTrendSwitchedToBearish || + isPTrendSwitchedToBearish) + // + ); + + // + result = + isBullishFiltered || + isBearishFiltered; + 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(); + + // + // Cleanup Resources ... + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + if (!result) + { + // + conditions.Clean(); + triggerBlock.Clean(); + } + + // + return result; +}; + +// \ No newline at end of file diff --git a/XCAEA/Signals/xcaea.signaller.class.mq5 b/XCAEA/Signals/xcaea.signaller.class.mq5 index 58db14ec..7ae8e9c9 100644 --- a/XCAEA/Signals/xcaea.signaller.class.mq5 +++ b/XCAEA/Signals/xcaea.signaller.class.mq5 @@ -51,6 +51,8 @@ class XCXCAEASignaller : XCBase XCXCAEAHelper *analyseHelper; XCXCAEAPOIDetector *detector; XCAEAStrategyConditions mConditions; + bool allowAnalyseDecisionZoneSignalling; + bool allowTriggerBlockDecisionZoneSignalling; XCAEAStrategyConditions mConditionsCollection[]; // @@ -92,6 +94,11 @@ class XCXCAEASignaller : XCBase allowDrawPOIs = false; maxAllowedSetupAge = 576; + // + // Signallings ... + allowAnalyseDecisionZoneSignalling = false; + allowTriggerBlockDecisionZoneSignalling = true; + // // Initial Bar Tracker ... barTraker.Init( @@ -166,13 +173,16 @@ class XCXCAEASignaller : XCBase * @return ( bool ) */ bool DetectSignalSetup( - double tpReward = 3, - double maxAllowedSLDistanceInPoint = 100 // + double tpReward = 3 // ) { // bool result = false; + // + // Normalize Args ... + tpReward = NormalizeDouble(tpReward, 1); + // // Check Bar Processing ... if (!barTraker.CanProcessBar()) @@ -181,59 +191,30 @@ class XCXCAEASignaller : XCBase } // + int idx = -1; + int count = 0; + int zIndex = 0; + bool has = false; + int loopback = 10; bool isBullish = false; bool isBearish = false; - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int p2Index = pIndex + 1; - - // - int loopback = 10; - - // - int idx = -1; - int count = 0; - bool has = false; - - // - double ask = GetAsk(symbol); - double bid = GetBid(symbol); - datetime cTime = TimeCurrent(); - double points = GetPoints(symbol); - // XOHCL zBar; - XOHCL cBar; - XOHCL pBar; - XOHCL pPBar; result = zBar.Init( symbol, period, zIndex // ); - result = - result && - zBar.GetPreviousBar(cBar); - result = - result && - cBar.GetPreviousBar(pBar); - result = - result && - pBar.GetPreviousBar(pPBar); if (!result) { // zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - pPBar.Clean(); // return result; } + datetime cTime = zBar.time; // // Detect Pivots ... @@ -262,23 +243,42 @@ class XCXCAEASignaller : XCBase ENUM_X_DIRECTION decisionZoneDir = X_DIRECTION_NONE; // - // Checking Signal's Decision Zone ... - // On Analyse Time Frame ... - hasDecisionZone = DetectDecisionZone( - analyseHelper, - drawer, - decisionZone, - decisionZoneDir, - unavailables, - conditions, - zIndex, - loopback // - ); + // Check Decision Zone Detection Based On Several Signalling ... + + // + // Analyse DecisionZone ... + // In this Used Case we fond an Analyse TF OB + // then waits for trigger on it ... + if (allowAnalyseDecisionZoneSignalling) + { + // + // Checking Signal's Decision Zone ... + // On Analyse Time Frame ... + hasDecisionZone = DetectDecisionZone( + analyseHelper, + drawer, + decisionZone, + decisionZoneDir, + unavailables, + conditions, + zIndex, + loopback // + ); + + // + // Here we Can Validate Decision Zone ... + if (hasDecisionZone) + { + } + } // - // Here we Can Validate Decision Zone ... - if (hasDecisionZone) - { + // TriggerBlock Decision Zone ... + // In this Used Case we found a Tigger Block and use it + // for Triggering ... + if (!hasDecisionZone && + allowTriggerBlockDecisionZoneSignalling) { + // } // @@ -339,11 +339,6 @@ class XCXCAEASignaller : XCBase // zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - pPBar.Clean(); - - // conditions.Clean(); decisionZone.Clean();