From ccbb9e0105a14c2c6d5e4cd6d92e22d9c81cca70 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 18 May 2025 06:23:43 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-cobject.class.mq5 | 274 ++++- Classes/x-saherelm.x-poi.drawer.class.mq5 | 5 +- Indicators/x-saherelm.x121.xczone.mq5 | 955 ++++-------------- .../x-saherelm.common.extensions.lib.mq5 | 12 +- 4 files changed, 506 insertions(+), 740 deletions(-) diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 25bd7381..a9726d7b 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -26,9 +26,9 @@ // #include #include +#include #include #include -#include #include // @@ -155,6 +155,207 @@ string ToString(ENUM_X_CHART_IDS value) return result; } +// +// Library Functions ... + +/** + * Converts a XBoxZone struct to XSignal instance ... + * + * @param box: XBoxZone instance reference, provide source info ... + * @param signal: XSignal instance reference, holds prepared converted signal ... + * + * @return ( bool ) + */ +bool ToSignal( + XBoxZone &box, + XSignal &signal, + double &rewardRatios[] // +) +{ + // + bool result = false; + + // + signal.Clean(); + + // + result = box.IsValid() && + HasChild(rewardRatios); + if (!result) + { + return result; + } + + // + XOHCL entryBar; + result = entryBar.Init( + box.symbol, + box.period, + box.ToIndex() - 1 // + ); + if (!result) + { + // + entryBar.Clean(); + + // + return result; + } + + // + bool isBullish = box.IsBullish(); + bool isBearish = box.IsBearish(); + + // + ENUM_POSITION_TYPE iType = + isBullish + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_POSITION_TYPES iXType = + isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + double points = GetPoints(box.symbol); + + // + double risk = box.GetRange(); + + // + double entry = + isBullish + ? box.upper + : box.lower; + entry = entryBar.open; + + // + double sl = + isBullish + ? box.lower + : box.upper; + + // + double tp = 0; + + // + // Calculate Target ... + XTarget targets[]; + + // + double tmp[]; + int idx = -1; + XTarget iTarget; + bool has = false; + double iRatio = 0; + double iReward = 0; + double iRewardPrice = 0; + Copy( + rewardRatios, + tmp // + ); + while (HasChild(tmp)) + { + // + idx = -1; + iRatio = GetMaxWidthIndex( + tmp, + idx // + ); + + // + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + has = iRatio > 0; + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + + // + bool canSetTP = tp <= 0; + + // + iReward = iRatio * risk; + + // + iRewardPrice = + isBullish + ? entry + iReward + : entry - iReward; + if (canSetTP) + { + tp = iRewardPrice; + } + else + { + // + iTarget.target = iRewardPrice; + AddRef( + iTarget, + targets // + ); + + // + iTarget.Clean(); + } + } + Clean(tmp); + + // + // Filling Signal ... + signal.tp = tp; + signal.sl = sl; + signal.type = iType; + signal.comment = ""; + signal.entry = entry; + signal.time = box.to; + signal.volume = 0.01; + signal.provider = box.type; + signal.symbol = box.symbol; + signal.period = box.period; + signal.mode = X_ORDER_MODE_MARKET; + + // + if (HasChild(targets)) + { + // + Copy( + targets, + signal.targets // + ); + } + + // + result = signal.IsValid(); + + // + // Cleanup Resources ... + + // + if (!result) + { + signal.Clean(); + } + + // + Clean(tmp); + Clean(targets); + iTarget.Clean(); + entryBar.Clean(); + + // + return result; +} + // // Implementation ... @@ -1774,6 +1975,7 @@ class XCSignalObject : public XCBaseObject * @param name: String ... * @param window: Integer ... * @param signal: XSignal instance ... + * @param length: int, Specified Length of Signal ... * * @return ( bool ) */ @@ -1781,12 +1983,16 @@ class XCSignalObject : public XCBaseObject long chart_id, const int window, XSignal &signal, + int length = 3, string prefix = NULL // ) { // bool result = false; + // + length = NormalizeInt(length, 3); + // result = signal.IsValid(); if (!result) @@ -1803,7 +2009,7 @@ class XCSignalObject : public XCBaseObject string nameMD5 = ToMD5(name); // - int delay = (PeriodSeconds(signal.period) * 2); + int delay = (PeriodSeconds(signal.period) * length); datetime time1 = (datetime)((int)signal.time - delay); datetime time2 = (datetime)((int)signal.time + delay); @@ -2108,6 +2314,70 @@ class XCSignalObject : public XCBaseObject CArrayObj mTargetTrends; }; +// +// XRR Object ... +class XCRRObject : public XCSignalObject +{ + // + // Public ... + public: + // + // Constructor ... + bool CreateBoxRR( + long chart_id, + const int window, + XBoxZone &box, + double &rewardRatios[], + int length = 3, + string prefix = NULL // + ) + { + // + bool result = false; + + // + length = NormalizeInt(length, 3); + + // + result = box.IsValid(); + if (!result) + { + return result; + } + + // + XSignal signal; + result = ToSignal( + box, + signal, + rewardRatios // + ); + if (!result) + { + // + signal.Clean(); + + // + return result; + } + + // + result = Create( + chart_id, + window, + signal, + length, + prefix // + ); + + // + signal.Clean(); + + // + return result; + } +}; + class XCOHCLObject : public XCBaseObject { // diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 5a31af80..adc86929 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -3267,7 +3267,8 @@ class XCPOIDrawer : public XCBase */ bool DrawSignal( XSignal &signal, - XCSignalObject *&object // + XCSignalObject *&object, + int length = 3 // ) { // @@ -3275,6 +3276,7 @@ class XCPOIDrawer : public XCBase // object = NULL; + length = NormalizeInt(length, 3); // result = signal.IsValid(); @@ -3294,6 +3296,7 @@ class XCPOIDrawer : public XCBase chartID, window, signal, + length, prefix // ); if (!result) diff --git a/Indicators/x-saherelm.x121.xczone.mq5 b/Indicators/x-saherelm.x121.xczone.mq5 index 8f1f4be6..f5321b92 100644 --- a/Indicators/x-saherelm.x121.xczone.mq5 +++ b/Indicators/x-saherelm.x121.xczone.mq5 @@ -26,6 +26,7 @@ // // Includes Common Library ... +#include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" @@ -34,8 +35,6 @@ // // Inputs ... input group "Market"; -input int minZoneLength = 15; // Minimum Length of Consolidation Zone -input double maxZoneRangeInPoints = 0; // Max Zone Range in Point input ENUM_X_PERIOD_METHOD trendPeriodMethod = X_PERIOD_AUTO; // How to Find Trend Period input ENUM_TIMEFRAMES trendPeriod = NULL; // Trend Time Period input ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode @@ -52,17 +51,20 @@ input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To // // Validating ... input group "Validating"; -input bool forceGapBarsBreakout = true; // Force Zone's Gap Bar's Breakes Out -input bool forceHasSwing = true; // Force Zone's Has Propper Swing +input int minZoneLength = 7; // Minimum Length of Consolidation Zone +input double maxZoneRangeInPoints = 70; // Max Zone Range in Point +input double maxAllowedEntryDistance = 30; // Max Allowed Entry Distance +input bool forceGapBarsBreakout = true; // Force Zone's Gap Bar's Breakes Out +input bool forceHasSwing = true; // Force Zone's Has Propper Swing +input bool forceHasPinBarEntry = true; // Force Zone's Ends with a Pin Bar // // Filtering ... input group "Filtering"; -input bool filterBasedOnSar = false; // Filter Pivots Based on Sar -input bool filterBasedOnRSI = false; // Filter Pivots Based on RSI -input bool filterBasedOnADX = false; // Filter Pivots Based on ADX -input bool filterBasedOnTrend = false; // Filter Pivots Based on Trend -input bool filterBasedOnAnalysePivots = false; // Filter Pivots Based on Analyse Pivots +input bool filterBasedOnSar = false; // Filter Pivots Based on Sar +input bool filterBasedOnRSI = false; // Filter Pivots Based on RSI +input bool filterBasedOnADX = false; // Filter Pivots Based on ADX +input bool filterBasedOnTrend = false; // Filter Pivots Based on Trend // // Presentation ... @@ -70,7 +72,8 @@ input group "Presentation"; input bool showSar = false; // Show Sar input bool showTrend = false; // Show Trend input bool rayLeft = false; // Ray to Left -input bool drawAnalysePivots = false; // Draw Analyse Pivots +input bool drawZones = true; // Draw Detected Zones +input bool drawRRofZones = true; // Draw Zone's Risk Reward Ratios input int boxWidth = 2; // Box Width input color bullishColor = clrLime; // Bullish Color input color bearishColor = clrRed; // Bearish Color @@ -79,6 +82,16 @@ input ENUM_LINE_STYLE boxStyle = STYLE_SOLID; // Box Style // input int startCalculationForLastBars = 5000; // Calculate Last n Bars int sarArrowCode = 159; // Sar Arrow Code +int rrZoneLength = 7; // Draw Risk Reward Ratio till n Bars + +// +// Alert ... +input group "Alerts"; +input string alertPrefix = ""; // Alert Prefix +input bool _logAlerts = true; // Log Alerts +input bool _pushAlerts = true; // Push Alerts +input bool _mailAlerts = false; // Mail Alerts +input bool _terminalAlerts = true; // Terminal Alerts // // Buffers ... @@ -183,11 +196,11 @@ int limit; int maxLength; // +XCAlert *alert; double mPoints = 0; CArrayObj mObjects; XCPOIDrawer *drawer; -XBoxZone analyseOBs[]; -XBoxZone analysePivot; +bool mEnableAlerts = false; XCBarAnalyser *barAnalyser; int mTrendPeriodLength = 0; int sarHandler = INVALID_HANDLE; @@ -216,6 +229,25 @@ int OnInit() // // Initialize Indicator Handlers ... + // + // Configure Alert ... + alert = new XCAlert(); + mEnableAlerts = + _logAlerts || + _pushAlerts || + _mailAlerts || + _terminalAlerts; + string mPrefix = ShortName + + (!IsValid(alertPrefix) + ? "" + : "[" + alertPrefix + "]"); + alert.SetPrefix(mPrefix); + alert.SetLogAlerts(_logAlerts); + alert.SetMailAlerts(_mailAlerts); + alert.SetPushAlerts(_pushAlerts); + alert.SetEnableAlerts(mEnableAlerts); + alert.SetTerminalAlerts(_terminalAlerts); + // drawer = new XCPOIDrawer(); barAnalyser = new XCBarAnalyser(); @@ -341,11 +373,14 @@ void OnDeinit(const int reason) // REASON_CLOSE 9 Terminal closed // - Clean(analyseOBs); - analysePivot.Clean(); + mObjects.Clear(); // - mObjects.Clear(); + delete alert; + delete drawer; + + // + ZeroMemory(alert); ZeroMemory(drawer); ZeroMemory(barAnalyser); @@ -466,7 +501,7 @@ int OnCalculate( // // TREND ... - int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit + 1, trendBuffer); + int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit, trendBuffer); // // Validate Copied Items ... @@ -702,15 +737,15 @@ void FillBuffersZero(int barIndex) { // // SAR ... - sarBuffer[barIndex] = emptyValue; - sarColorBuffer[barIndex] = hideColorIDX; - sarStateBuffer[barIndex] = neuturalState; + // sarBuffer[barIndex] = emptyValue; + // sarColorBuffer[barIndex] = hideColorIDX; + // sarStateBuffer[barIndex] = neuturalState; // // TREND ... - trendBuffer[barIndex] = emptyValue; - trendColorBuffer[barIndex] = hideColorIDX; - trendStateBuffer[barIndex] = neuturalState; + // trendBuffer[barIndex] = emptyValue; + // trendColorBuffer[barIndex] = hideColorIDX; + // trendStateBuffer[barIndex] = neuturalState; } /** @@ -818,700 +853,6 @@ void CalculateValues( low, tickVolume // ); - return; - - // - // Prevent Calculation ... - if (maxBarIndex - bar_index < minZoneLength) - { - return; - } - - // - // Detect Consolidation Zone ... - XOHCL iBar; - bool has = iBar.Init( - _Symbol, - _Period, - bar_index // - ); - if (!has) - { - return; - } - - // - // Checking Base Zone Exists ... - XBoxZone iZone; - has = barAnalyser.IsOB( - iBar, - iZone, - true, // Force FVG Bar Type ... - true // Force Two Bar ... - ); - if (!has) - { - // - iBar.Clean(); - iZone.Clean(); - } - bool isBullish = - has && - iZone.IsBullish(); - bool isBearish = - has && - iZone.IsBearish(); - - // - // Apply Max Range ... - has = maxZoneRangeInPoints > 0; - if (has) - { - // - double range = iZone.GetRange(); - has = range <= maxZoneRangeInPoints * points; - if (!has) - { - // - iBar.Clean(); - iZone.Clean(); - } - } - - // - XOHCL iPBar; - has = iBar.GetPreviousBar(iPBar); - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - - // - return; - } - - // - // Ensure we Have Order Block ... - ENUM_X_DIRECTION iDir; - - // - // Validate FVG Gap Candle Breakeout by Body ... - - // - // Check iPBar is Momentum Bar ... - has = barAnalyser.IsMomentum( - iPBar, - iDir // - ); - bool isBullishMomentum = - has && - IsBullish(iDir); - bool isBearishMomentum = - has && - IsBearish(iDir); - - // - bool isBullishBreakedOut = - isBullish && - iPBar.IsBullish() && - isBullishMomentum && - iPBar.GetUp() > iZone.upper && - iPBar.GetDown() < iZone.upper; - - // - bool isBearishBreakedOut = - isBearish && - iPBar.IsBearish() && - isBearishMomentum && - iPBar.GetUp() > iZone.lower && - iPBar.GetDown() < iZone.lower; - - // - has = - isBullishBreakedOut || - isBearishBreakedOut; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - - // - return; - } - - // - // Check Has Proper Swing ... - - // - bool isIBarSimpleSwing = - barAnalyser.IsSimpleSwing( - iBar, - iDir // - ); - bool isIBarBullishSimpleSwing = - isIBarSimpleSwing && - IsBullish(iDir); - bool isIBarBearishSimpleSwing = - isIBarSimpleSwing && - IsBearish(iDir); - - // - bool isIPBarSimpleSwing = - barAnalyser.IsSimpleSwing( - iPBar, - iDir // - ); - bool isIPBarBullishSimpleSwing = - isIPBarSimpleSwing && - IsBullish(iDir); - bool isIPBarBearishSimpleSwing = - isIPBarSimpleSwing && - IsBearish(iDir); - - // - bool isBullishSwimpleSwing = - isBullish && - (isIBarBullishSimpleSwing || - isIPBarBullishSimpleSwing); - - // - bool isBearishSwimpleSwing = - isBearish && - (isIBarBearishSimpleSwing || - isIPBarBearishSimpleSwing); - - // - has = isBullishSwimpleSwing || - isBearishSwimpleSwing; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - - // - return; - } - - // - int toIDX = iZone.ToIndex(); - int fromIDX = iZone.FromIndex(); - - // - // Retrieve Box From Bar ... - XOHCL fromBar; - has = iZone.FromBar(fromBar); - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - - // - // Retrieve Highest High and Lowest Low ... - double ll = fromBar.FindLowest(minZoneLength, MODE_LOW); - double hh = fromBar.FindHighest(minZoneLength, MODE_HIGH); - - // - // Validate Directional Based HH/LL Passed ... - - // - bool isBullishLLPassed = - isBullish && - ll >= iZone.lower; - - // - bool isBearishHHPassed = - isBearish && - hh <= iZone.upper; - - // - has = - isBullishLLPassed || - isBearishHHPassed; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - - // - // Update Zone From ... - datetime iFrom = GetBarTime( - _Symbol, - _Period, - fromBar.Index() + minZoneLength // - ); - iZone.from = iFrom; - - // - toIDX = iZone.ToIndex(); - fromIDX = iZone.FromIndex(); - - // - // Apply Filters ... - has = filterBasedOnSar || - filterBasedOnRSI || - filterBasedOnADX || - filterBasedOnTrend || - filterBasedOnAnalysePivots; - if (has) - { - // - // Retrieve Indexes ... - int iBarIndex = iBar.Index(); - int ipBarIndex = iPBar.Index(); - int iBarPrevIndex = iBarIndex + 1; - int ipBarPrevIndex = ipBarIndex + 1; - - // - // Apply Using Sar ... - if (filterBasedOnSar) - { - // - double iSarState = sarStateBuffer[iBarIndex]; - double iPSarState = sarStateBuffer[ipBarIndex]; - double iSarPrevState = sarStateBuffer[iBarPrevIndex]; - double iPSarPrevState = sarStateBuffer[ipBarPrevIndex]; - - // - bool isISarBullish = iSarState > 0; - bool isIPSarBullish = iPSarState > 0; - bool isISarPrevBullish = iSarPrevState > 0; - bool isIPSarPrevBullish = iPSarPrevState > 0; - - // - bool isISarBearish = iSarState < 0; - bool isIPSarBearish = iPSarState < 0; - bool isISarPrevBearish = iSarPrevState < 0; - bool isIPSarPrevBearish = iPSarPrevState < 0; - - // - bool isISarSwitchedToBullish = isISarBullish && - !isISarPrevBullish; - bool isISarSwitchedToBearish = isISarBearish && - !isISarPrevBearish; - - // - bool isIPSarSwitchedToBullish = isIPSarBullish && - !isIPSarPrevBullish; - bool isIPSarSwitchedToBearish = isIPSarBearish && - !isIPSarPrevBearish; - - // - // Check iPBar (Gap Bar which Breaks Edge and is a Momentum Bar) is Sar Change Bar ... - - // - bool isBullishSarFiltered = - isBullish && - (isISarSwitchedToBullish || - isIPSarSwitchedToBullish); - - // - bool isBearishSarFiltered = - isBearish && - (isISarSwitchedToBearish || - isIPSarSwitchedToBearish); - - // - has = isBullishSarFiltered || - isBearishSarFiltered; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - } - - // - // Apply Using RSI ... - if (filterBasedOnRSI) - { - // - double iBarRSI = rsiBuffer[iBarIndex]; - double iBarPrevRSI = rsiBuffer[iBarPrevIndex]; - - // - bool isIBarRSICrossedOverOS = - iBarRSI > rsiOSLevel && - iBarPrevRSI < rsiOSLevel; - bool isIBarRSICrossedUnderOB = - iBarRSI < rsiOBLevel && - iBarPrevRSI > rsiOBLevel; - - // - double iPBarRSI = rsiBuffer[ipBarIndex]; - double iPBarPrevRSI = rsiBuffer[ipBarPrevIndex]; - - // - bool isIPBarRSICrossedOverOS = - iPBarRSI > rsiOSLevel && - iPBarPrevRSI < rsiOSLevel; - bool isIPBarRSICrossedUnderOB = - iPBarRSI < rsiOBLevel && - iPBarPrevRSI > rsiOBLevel; - - // - bool isBullishRSIFiltered = - isBullish && - (isIBarRSICrossedOverOS || - isIPBarRSICrossedOverOS); - - // - bool isBearishRSIFiltered = - isBearish && - (isIBarRSICrossedUnderOB || - isIPBarRSICrossedUnderOB); - - // - has = isBullishRSIFiltered || - isBearishRSIFiltered; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - } - - // - // Apply Using ADX ... - if (filterBasedOnADX) - { - // - // Reading Required Values ... - - // - double iBarADX = adxBuffer[iBarIndex]; - double iBarPrevADX = adxBuffer[iBarPrevIndex]; - - // - bool iBarADXP = adxpBuffer[iBarIndex]; - bool iBarPrevADXP = adxpBuffer[iBarPrevIndex]; - - // - bool iBarADXN = adxnBuffer[iBarIndex]; - bool iBarPrevADXN = adxnBuffer[iBarPrevIndex]; - - // - // Creating Some Conditions ... - - // - bool isIADXBullish = iBarADXP > iBarADXN; - bool isIADXBullishPrev = iBarPrevADXP > iBarPrevADXN; - - // - bool isIADXBearish = iBarADXN > iBarADXP; - bool isIADXBearishPrev = iBarPrevADXN > iBarPrevADXP; - - // - bool isIADXUp = - adxThreshold > 0 - ? iBarADX > adxThreshold - : true; - bool isIADXUpPrev = - adxThreshold > 0 - ? iBarPrevADX > adxThreshold - : true; - - // - bool isIADXDown = - adxThreshold > 0 - ? iBarADX < adxThreshold - : true; - bool isIADXDownPrev = - adxThreshold > 0 - ? iBarPrevADX < adxThreshold - : true; - - // - bool isIADXSwitchedToBullish = isIADXBullish && - !isIADXBullishPrev; - - // - bool isIADXSwitchedToBearish = isIADXBearish && - !isIADXBearishPrev; - - // - bool isIADXSwitchedUp = isIADXUp && - !isIADXUpPrev; - - // - bool isIADXSwitchedDown = isIADXDown && - !isIADXDownPrev; - - // - // Summarize Filtering ... - - // - bool isBullishADXFiltered = - isBullish && - // (isIADXUp || - // isIADXSwitchedUp) && - (isIADXBullish || - isIADXSwitchedToBullish); - - // - bool isBearishADXFiltered = - isBearish && - // (isIADXDown || - // isIADXSwitchedDown) && - (isIADXBearish || - isIADXSwitchedToBearish); - - // - has = isBullishADXFiltered || - isBearishADXFiltered; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - } - - // - // Apply Using Trend ... - if (filterBasedOnTrend) - { - // - // Check and Validate Box using Trend ... - // bearish boxs high must above trend - // bullish box low must below trend - - // - double iTrend = 0; - bool isBullishTrendPassed = true; - bool isBearishTrendPassed = true; - for (int i = fromIDX; i >= toIDX; i--) - { - // - iTrend = trendBuffer[i]; - - // - if (isBullishTrendPassed) - { - // - isBullishTrendPassed = - isBullishTrendPassed && - iZone.lower < iTrend; - } - - // - if (isBearishTrendPassed) - { - // - isBearishTrendPassed = - isBearishTrendPassed && - iZone.upper > iTrend; - } - - // - if (!isBullishTrendPassed && - !isBearishTrendPassed) - { - break; - } - } - - // - bool isBullishTrendFiltered = - isBullish && - isBullishTrendPassed; - - // - bool isBearishTrendFiltered = - isBearish && - isBearishTrendPassed; - - // - has = isBullishTrendFiltered || - isBearishTrendFiltered; - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - } - - // - // Apply Using Analyse Pivots ... - // IsValid(analysePeriod) && - // HasChild(analyseOBs) && - if (analysePivot.IsValid() && - filterBasedOnAnalysePivots) - { - // - has = false; - // for (int i = 0; i < ArraySize(analyseOBs); i++) - // { - // // - // has = - // iZone.dir == analyseOBs[i].dir && - // ( - // // - // (iZone.upper < analyseOBs[i].upper && - // iZone.lower > analyseOBs[i].lower) || - // (iZone.lower < analyseOBs[i].upper && - // iZone.lower > analyseOBs[i].lower) || - // (iZone.upper > analyseOBs[i].lower && - // iZone.upper < analyseOBs[i].upper) - // // - // ); - // if (has) - // { - // break; - // } - // } - - // - has = - iZone.dir == analysePivot.dir && - ( - // - (iZone.upper < analysePivot.upper && - iZone.lower > analysePivot.lower) || - (iZone.lower < analysePivot.upper && - iZone.lower > analysePivot.lower) || - (iZone.upper > analysePivot.lower && - iZone.upper < analysePivot.upper) - // - ); - - // - if (!has) - { - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); - fromBar.Clean(); - - // - return; - } - } - } - - // - fromIDX = iZone.FromIndex(); - - // - // Find Base of Movement ... - if (rayLeft) - { - // - XOHCL tmpBar; - int start = fromIDX + 1; - bool isBaseValid = true; - while (isBaseValid) - { - // - has = tmpBar.Init( - _Symbol, - _Period, - start // - ); - if (!has) - { - // - tmpBar.Clean(); - break; - } - - // - bool isBullishPassed = - isBullish && - tmpBar.low >= iZone.lower; - - // - bool isBearishPassed = - isBearish && - tmpBar.high <= iZone.upper; - - // - has = - isBullishPassed || - isBearishPassed; - if (!has) - { - break; - } - - // - start++; - } - has = tmpBar.IsValid(); - if (has) - { - iZone.from = tmpBar.time; - } - tmpBar.Clean(); - } - - // - // Draw Object ... - XCBoxObject *iZoneObj; - has = drawer.DrawBox( - iZone, - iZoneObj // - ); - if (has) - { - // - ApplyStyle(iZoneObj, iZone.dir); - - // - mObjects.Add(iZoneObj); - } - ZeroMemory(iZoneObj); - - // - // Cleanup Resources ... - - // - iBar.Clean(); - iPBar.Clean(); - iZone.Clean(); } // @@ -1709,6 +1050,42 @@ void DetectTriggerZone( } } + // + // Validate Gap Endup with PinBar ... + has = forceHasPinBarEntry; + if (has) + { + // + bool isBullishRejected = + isBullish && + cBar.IsBullish() && + cBar.GetLowShadow() > cBar.GetHighShadow(); + + // + bool isBearishRejected = + isBearish && + cBar.IsBearish() && + cBar.GetLowShadow() < cBar.GetHighShadow(); + + // + has = isBullishRejected || + isBearishRejected; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + // // Validating Gap Bar must a Momentum Bar and // Breakes out Zone's Directional Edge ... @@ -1899,6 +1276,34 @@ void DetectTriggerZone( fromBar.Clean(); } + // + // Validate Max Allowed Entry Distance ... + has = maxAllowedEntryDistance > 0; + if (has) + { + // + double base = + isBullish + ? zone.upper + : zone.lower; + double entryDistance = MathAbs(zBar.open - base); + has = entryDistance <= maxAllowedEntryDistance * mPoints; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + // // Here we Ensure which have a Valid Zone using Different Applied Validations ... // from now we are Going to Filtered Validate Zones ... @@ -1908,8 +1313,7 @@ void DetectTriggerZone( has = filterBasedOnSar || filterBasedOnRSI || filterBasedOnADX || - filterBasedOnTrend || - filterBasedOnAnalysePivots; + filterBasedOnTrend; if (has) { // @@ -2730,25 +2134,114 @@ void DetectTriggerZone( // // Draw Detected Zone ... - XCBoxObject *iZoneObj; - has = drawer.DrawBox( - zone, - iZoneObj // - ); - if (has) + if (drawZones) { // - ApplyStyle(iZoneObj, zone.dir); + XCBoxObject *iZoneObj; + has = drawer.DrawBox( + zone, + iZoneObj // + ); + if (has) + { + // + ApplyStyle(iZoneObj, zone.dir); - // - mObjects.Add(iZoneObj); + // + mObjects.Add(iZoneObj); + // + // TODO: Enable This for Debugging ... + // string message = ToString(zone.dir) + " Zone Detected (" + cBar.time + ") ..."; + // Print(message); + } + ZeroMemory(iZoneObj); + } + + // + // Draw RR Tool ... + if (drawRRofZones) + { // - // TODO: Enable This for Debugging ... - // string message = ToString(zone.dir) + " Zone Detected (" + cBar.time + ") ..."; - // Print(message); + double rr[]{ + 1, + 1.5, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 // + }; + XCRRObject *iRRObj; + iRRObj = new XCRRObject(); + has = iRRObj.CreateBoxRR( + drawer.ChartIdentification(), + drawer.SubWindowIdentification(), + zone, + rr, + rrZoneLength // + ); + if (has) + { + // + int iWidth = 2; + ENUM_LINE_STYLE iStyle = STYLE_SOLID; + + // + iRRObj.TPWidth(iWidth); + iRRObj.SLWidth(iWidth); + iRRObj.EntryWidth(iWidth); + iRRObj.TargetWidth(iWidth); + + // + iRRObj.TPStyle(iStyle); + iRRObj.SLStyle(iStyle); + iRRObj.EntryStyle(iStyle); + iRRObj.TargetStyle(iStyle); + + // + iRRObj.TPColor(clrLime); + iRRObj.SLColor(clrRed); + iRRObj.EntryColor(clrYellow); + iRRObj.TargetColor(clrLightBlue); + + // + mObjects.Add(iRRObj); + } + ZeroMemory(iRRObj); + } + + // + // Handle Alerst ... + bool canAlert = + mEnableAlerts && + prevCalculated > 0; + bool canLogOnly = + mEnableAlerts && + prevCalculated == 0; + if (canAlert || canLogOnly) + { + // + string message = + zone.symbol + "," + + ToString(zone.period) + "> " + + ToString(zone.dir) + + " Zone Detected at: " + ToString(zone.to); + + // + if (canLogOnly) + { + alert.LogAlert(message); + } + else if (canAlert) + { + alert.Alert(message); + } } - ZeroMemory(iZoneObj); // // Cleanup Resources ... diff --git a/Libraries/x-saherelm.common.extensions.lib.mq5 b/Libraries/x-saherelm.common.extensions.lib.mq5 index 716c54e0..ae9507b8 100644 --- a/Libraries/x-saherelm.common.extensions.lib.mq5 +++ b/Libraries/x-saherelm.common.extensions.lib.mq5 @@ -4339,7 +4339,7 @@ T GetMax( return result; } template -T GetMax( +T GetMaxWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index @@ -4407,14 +4407,14 @@ T GetSpecifiedMax( ); } template -T GetSpecifiedMax( +T GetSpecifiedMaxWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index int count = 0 // Count for Search ) { - return GetMax( + return GetMaxWidthIndex( buffer, index, start, @@ -4477,7 +4477,7 @@ T GetMin( return result; } template -T GetMin( +T GetMinWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index @@ -4545,14 +4545,14 @@ T GetSpecifiedMin( ); } template -T GetSpecifiedMin( +T GetSpecifiedMinWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index int count = 0 // Count for Search ) { - return GetMin( + return GetMinWidthIndex( buffer, index, start,