From 21fe832447145e8ff51840a39829b90cd2fe6673 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 16 Sep 2025 23:48:52 +0330 Subject: [PATCH] last ... --- .../x-saherelm.x-backtester.expert.class.mq5 | 112 ++++---- Classes/x-saherelm.x-market.pattern.class.mq5 | 230 ++++++++++++++- Documents/BKP/tmp.backtester.codes.mq5 | 101 +++++++ Experts/x-saherelm.xfima.backtester.ea.mq5 | 266 ++++++++++++------ .../x-saherelm.common.extensions.lib.mq5 | 18 ++ 5 files changed, 583 insertions(+), 144 deletions(-) diff --git a/Classes/x-saherelm.x-backtester.expert.class.mq5 b/Classes/x-saherelm.x-backtester.expert.class.mq5 index 506b6fed..eb1fbb8f 100644 --- a/Classes/x-saherelm.x-backtester.expert.class.mq5 +++ b/Classes/x-saherelm.x-backtester.expert.class.mq5 @@ -79,6 +79,11 @@ class XCBackTesterEA : public XCBase double riskToRewardRatio; // Risk To Reward per Trades ... double volume; // Default volume Per Trade ... + // + XCAlert *eaAlert; // EA Scope Alert Handler ... + XCTrade *eaTrader; // EA Scope Trade Handler ... + XCChartHelper *eaChartHelper; // Chart Helper Class ... + // // Constructor ... XCBackTesterEA() @@ -656,10 +661,6 @@ class XCBackTesterEA : public XCBase // // Props ... - // - XCAlert *eaAlert; // EA Scope Alert Handler ... - XCTrade *eaTrader; // EA Scope Trade Handler ... - // // Trade Event Listeners ... TOnModify mOnModifyEventHandlers[]; @@ -672,9 +673,6 @@ class XCBackTesterEA : public XCBase TOnPositionsChanged mPositionsChangedEventHandlers[]; TOnTradeStateChanged mTradeStateChangedEventHandlers[]; - // - XCChartHelper *mChartHelper; // Chart Helper Class ... - // // Object Props ... @@ -729,7 +727,7 @@ class XCBackTesterEA : public XCBase // // Initial Chart Class Instance ... - mChartHelper = new XCChartHelper(chartId); + eaChartHelper = new XCChartHelper(chartId); // int startX = 5; @@ -742,19 +740,19 @@ class XCBackTesterEA : public XCBase // // Buy ... - int btnBuyStartX = startX; - int btnBuySizeX = startX + defaultWidth; - int btnBuyStartY = startY; - int btnBuySizeY = startY + defaultHeight; + int btnBuyX1 = startX; + int btnBuyX2 = startX + defaultWidth; + int btnBuyY1 = startY; + int btnBuyY2 = startY + defaultHeight; string btnBuyName = objSuffix + "BTN_BUY"; result = btnBuy.Create( chartId, btnBuyName, subWindow, - btnBuyStartX, - btnBuyStartY, - btnBuySizeX, - btnBuySizeY // + btnBuyX1, + btnBuyY1, + btnBuyX2, + btnBuyY2 // ); if (result) { @@ -769,19 +767,19 @@ class XCBackTesterEA : public XCBase // // Sell ... - int btnSellStartX = btnBuyStartX + btnBuySizeX; - int btnSellSizeX = btnSellStartX + defaultWidth; - int btnSellStartY = btnBuyStartY; - int btnSellSizeY = btnBuySizeY; + int btnSellX1 = btnBuyX1 + btnBuyX2; + int btnSellX2 = btnSellX1 + defaultWidth; + int btnSellY1 = btnBuyY1; + int btnSellY2 = btnBuyY2; string btnSellName = objSuffix + "BTN_SELL"; result = btnSell.Create( chartId, btnSellName, subWindow, - btnSellStartX, - btnSellStartY, - btnSellSizeX, - btnSellSizeY // + btnSellX1, + btnSellY1, + btnSellX2, + btnSellY2 // ); if (result) { @@ -796,19 +794,19 @@ class XCBackTesterEA : public XCBase // // LABEL Position ID ... - int lblPositionIdStartX = btnBuyStartX; - int lblPositionIdSizeX = lblPositionIdStartX + defaultWidth; - int lblPositionIdStartY = btnSellSizeY + defaultGap; - int lblPositionIdSizeY = lblPositionIdStartY + defaultHeight; + int lblPositionIdX1 = btnBuyX1; + int lblPositionIdX2 = lblPositionIdX1 + defaultWidth; + int lblPositionIdY1 = btnSellY2 + defaultGap; + int lblPositionIdY2 = lblPositionIdY1 + defaultHeight; string lblPositionIdName = objSuffix + "LBL_POS_ID"; result = lblPositionId.Create( chartId, lblPositionIdName, subWindow, - lblPositionIdStartX, - lblPositionIdStartY, - lblPositionIdSizeX, - lblPositionIdSizeY // + lblPositionIdX1, + lblPositionIdY1, + lblPositionIdX2, + lblPositionIdY2 // ); if (result) { @@ -822,19 +820,19 @@ class XCBackTesterEA : public XCBase // // Close ... - int btnCloseStartX = startX; - int btnCloseSizeX = btnCloseStartX + defaultWidth; - int btnCloseStartY = lblPositionIdSizeY + defaultGap; - int btnCloseSizeY = lblPositionIdSizeY + defaultHeight; + int btnCloseX1 = startX; + int btnCloseX2 = btnCloseX1 + defaultWidth; + int btnCloseY1 = lblPositionIdY2 + defaultGap; + int btnCloseY2 = btnCloseY1 + defaultHeight; string btnCloseName = objSuffix + "BTN_CLOSE"; result = btnClose.Create( chartId, btnCloseName, subWindow, - btnCloseStartX, - btnCloseStartY, - btnCloseSizeX, - btnCloseSizeY // + btnCloseX1, + btnCloseY1, + btnCloseX2, + btnCloseY2 // ); if (result) { @@ -849,19 +847,19 @@ class XCBackTesterEA : public XCBase // // Close All ... - int btnCloseAllStartX = btnCloseSizeX + defaultGap; - int btnCloseAllSizeX = btnCloseAllStartX + defaultWidth; - int btnCloseAllStartY = lblPositionIdSizeY + defaultGap; - int btnCloseAllSizeY = lblPositionIdSizeY + defaultHeight; + int btnCloseAllX1 = btnCloseX2 + defaultGap; + int btnCloseAllX2 = btnCloseAllX1 + defaultWidth; + int btnCloseAllY1 = lblPositionIdY2 + defaultGap; + int btnCloseAllY2 = btnCloseAllY1 + defaultHeight; string btnCloseAllName = objSuffix + "BTN_CLOSE_ALL"; result = btnCloseAll.Create( chartId, btnCloseAllName, subWindow, - btnCloseAllStartX, - btnCloseAllStartY, - btnCloseAllSizeX, - btnCloseAllSizeY // + btnCloseAllX1, + btnCloseAllY1, + btnCloseAllX2, + btnCloseAllY2 // ); if (result) { @@ -879,9 +877,9 @@ class XCBackTesterEA : public XCBase // // TP Label ... - int lblTPX1 = btnCloseStartX; + int lblTPX1 = btnCloseX1; int lblTPX2 = lblTPX1 + defaultWidth; - int lblTPY1 = btnCloseSizeY + defaultGap; + int lblTPY1 = btnCloseY2 + defaultGap; int lblTPY2 = lblTPY1 + defaultHeight; string lblTPName = objSuffix + "LBL_TP"; result = lblTP.Create( @@ -1005,9 +1003,9 @@ class XCBackTesterEA : public XCBase // // SL Label ... - int lblSLX1 = btnCloseAllStartX; + int lblSLX1 = btnCloseAllX1; int lblSLX2 = lblSLX1 + defaultWidth; - int lblSLY1 = btnCloseAllSizeY + defaultGap; + int lblSLY1 = btnCloseAllY2 + defaultGap; int lblSLY2 = lblTPY1 + defaultHeight; string lblSLName = objSuffix + "LBL_SL"; result = lblSL.Create( @@ -1409,8 +1407,8 @@ class XCBackTesterEA : public XCBase void DestroyGUI() { // - delete mChartHelper; - ZeroMemory(mChartHelper); + delete eaChartHelper; + ZeroMemory(eaChartHelper); // delete btnSelectedPosInfo; @@ -1499,8 +1497,8 @@ class XCBackTesterEA : public XCBase // // Reading Global Chart Info ... int subWindow = 0; - int chartWidth = mChartHelper.Width(); - ulong chartId = mChartHelper.ChartId(); + int chartWidth = eaChartHelper.Width(); + ulong chartId = eaChartHelper.ChartId(); // // Read Selected Position ... @@ -1964,7 +1962,7 @@ class XCBackTesterEA : public XCBase // int subWindow = 0; - ulong chartId = mChartHelper.ChartId(); + ulong chartId = eaChartHelper.ChartId(); // int btnWidth = 25; diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index 17a2cf85..4ed7fef9 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -908,7 +908,112 @@ class XCMarketPatternDetector : public XCBase return result; } - bool HasTrend( + /** + * Check Specified Bar has SignalKey Bar Pattern or not ... + * + * @param bar: XOHCL, Specified Bar ... + * @param dir: ENUM_X_DIRECTION a reference for Direction ... + * @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ... + * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... + * @param forceDirection: bool, Apply Force Bar Type ... + * + * @return ( bool ) + */ + bool IsSignalKeyBarPattern( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + int shadowApprovedMultiplier = 3, + double minimumPinBarRangeMultiplier = 4, + bool forceDirection = false // + ) + { + // + bool result = false; + + // + // Prepare ... + CleanDirection(dir); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Get Requirements ... + XOHCL pBar; + result = bar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Chck Previous Bar must Pinned ... + result = IsPinnedBar( + pBar, + dir, + shadowApprovedMultiplier, + minimumPinBarRangeMultiplier, + forceDirection // + ); + if (!result) + { + // + pBar.Clean(); + return result; + } + + // + // Check Direction ... + bool isBullish = + bar.IsBullish() && + IsSpecifiedBullish(dir) && + bar.close > pBar.high; + bool isBearish = + bar.IsBearish() && + IsSpecifiedBearish(dir) && + bar.close < pBar.low; + result = isBullish || isBearish; + if (!result) + { + // + pBar.Clean(); + return result; + } + + // + dir = bar.GetDirection(); + + // + result = HasDirection(dir); + + // + // Cleanup Resources ... + pBar.Clean(); + + // + return result; + } + + // + // Trending ... + + /** + * Check Trend Exists Based on Swings ... + * + * @param bar: XOHCL, Specified Bar ... + * @param dir: ENUM_X_DIRECTION a reference for Direction ... + * @param swings: XOHCL Array, Holds Swings ... + * @param numberOfSwings: int, Number of Swing Points for Detect Trend ... + * @param swingShoulders: int, Swing Shoulders Approvement Length ... + * + * @return ( bool ) + */ + bool HasSwingTrend( XOHCL &bar, ENUM_X_DIRECTION &dir, XOHCL &swings[], @@ -1031,7 +1136,128 @@ class XCMarketPatternDetector : public XCBase // // Check Trend Based On Swings ... - + + // + // Check Directions ... + + // + bool isBullish = false; + bool isBearish = false; + + // + datetime oldestSwingLow = NULL; + datetime oldestSwingHigh = NULL; + + // + // Checking Bullish Trend based on Swing Lows ... + int count = ArraySize(swingLows); + for (int i = 0; i < count - 1; i++) + { + // + has = swingLows[i].low > swingLows[i + 1].low; + isBullish = + !isBullish + ? has + : isBullish && has; + if (!isBullish) + { + break; + } + + // + datetime oldeTime = MathMin(swingLows[i].time, swingLows[i + 1].time); + oldestSwingLow = + !IsSpecifiedValid(oldestSwingLow) + ? oldeTime + : MathMin(oldestSwingLow, oldeTime); + } + + // + // Checking Bearish Trend based on Swing Highs ... + count = ArraySize(swingHighs); + for (int i = 0; i < count - 1; i++) + { + // + has = swingHighs[i].high < swingHighs[i + 1].high; + isBearish = + !isBearish + ? has + : isBearish && has; + if (!isBearish) + { + break; + } + + // + datetime oldeTime = MathMin(swingHighs[i].time, swingHighs[i + 1].time); + oldestSwingHigh = + !IsSpecifiedValid(oldestSwingHigh) + ? oldeTime + : MathMin(oldestSwingHigh, oldeTime); + } + + // + result = isBullish || isBearish; + if (!result) + { + // + iSwing.Clean(); + SpecifiedClean(swingLows); + SpecifiedClean(swingHighs); + + // + return result; + } + + // + if (isBullish && + isBearish && + IsSpecifiedValid(oldestSwingLow) && + IsSpecifiedValid(oldestSwingHigh)) + { + // + // Here we Have to Detect Newest Trend or Oldest Trend ... + isBullish = oldestSwingLow < oldestSwingHigh; + isBearish = oldestSwingHigh < oldestSwingLow; + } + + // + result = (isBullish && !isBearish) || + (isBearish && !isBullish); + if (!result) + { + // + iSwing.Clean(); + SpecifiedClean(swingLows); + SpecifiedClean(swingHighs); + + // + return result; + } + + // + if (isBullish) + { + // + Copy( + swingLows, + swings // + ); + + // + dir = X_DIRECTION_BULLISH; + } + else + { + // + Copy( + swingHighs, + swings // + ); + + // + dir = X_DIRECTION_BEARISH; + } // iSwing.Clean(); diff --git a/Documents/BKP/tmp.backtester.codes.mq5 b/Documents/BKP/tmp.backtester.codes.mq5 index 5a330f4b..47bd1e6e 100644 --- a/Documents/BKP/tmp.backtester.codes.mq5 +++ b/Documents/BKP/tmp.backtester.codes.mq5 @@ -644,3 +644,104 @@ bool CreateMainPanel() // edtPositionId.Text(ToXString(selectedPositionID)); // edtPositionId.TextAlign(ALIGN_LEFT); // } + + +////////////////////////////////////////////////////////////////// + + +// +CButton btnPauseReplay; +bool isVisualTesterPaused = false; + + // + // Initial Btn Pause Play ... + int subWindow = 0; + int defaultGap = 5; + int defaultWidth = 100; + int defaultHeight = 30; + ulong chartId = eaExpert.eaChartHelper.ChartId(); + + // + int btnPauseReplayX1 = defaultGap; + int btnPauseReplayX2 = btnPauseReplayX1 + defaultWidth; + int btnPauseReplayY1 = eaExpert.eaChartHelper.Height() - defaultHeight - defaultGap; + int btnPauseReplayY2 = btnPauseReplayY1 + defaultHeight; + + // + string btnPauseReplayName = ShortName + "BTN_PAUSE_REPLAY"; + + // + isInited = btnPauseReplay.Create( + chartId, + btnPauseReplayName, + subWindow, + btnPauseReplayX1, + btnPauseReplayY1, + btnPauseReplayX2, + btnPauseReplayY2 // + ); + if (isInited) + { + // + // Apply Style ... + string btnPauseReplayText = + isVisualTesterPaused + ? "Play" + : "Pause"; + btnPauseReplay.Text(btnPauseReplayText); + btnPauseReplay.Color(clrAzure); + btnPauseReplay.ColorBackground(clrBlack); + } + +// + // + // Update btn Pause Replay ... + string btnPauseReplayText = + isVisualTesterPaused + ? "Play" + : "Pause"; + btnPauseReplay.Text(btnPauseReplayText); + if (IsRunningeOnTestVisualMode()) + { + // + btnPauseReplay.Show(); + btnPauseReplay.Enable(); + } + else + { + // + btnPauseReplay.Hide(); + btnPauseReplay.Enable(); + } + if (btnPauseReplay.Pressed()) + { + // + if (btnPauseReplay.IsEnabled()) + { + // + HandlePauseStrategyTester(); + + // + btnPauseReplayText = + isVisualTesterPaused + ? "Play" + : "Pause"; + btnPauseReplay.Text(btnPauseReplayText); + } + + // + btnPauseReplay.Pressed(false); + } + + +void HandlePauseStrategyTester() +{ + // + isVisualTesterPaused = !isVisualTesterPaused; + + // + // DebugBreak(); + + keybd_event(VK_SPACE, 0, 0, 0); + keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0); +} diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index 2febc5af..77444eda 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -27,6 +27,14 @@ #include "../Classes/x-saherelm.x-market.pattern.class.mq5" #include "../Helpers/x-saherelm.xom1.helper.mq5" +// +#import "user32.dll" +void keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo); +#import +#define VK_SPACE 0x20 // Space +#define VK_RETURN 0x0D // Return - Enter Key +#define KEYEVENTF_KEYUP 0x0002 // Key up + // // Definitions ... @@ -374,128 +382,218 @@ void OnTick() // ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + // + // Define Detection Flags ... + + // + bool detectPinned = false; + bool detectMomentum = false; + bool detectEngulfed = false; + bool detectTrueGaped = false; + + // + bool detectStarPattern = false; + bool detectFlagPattern = false; + bool detectRisingPattern = false; + bool detectPiercingPattern = false; + bool detectSignalKeyBarPattern = true; + + // + bool detectSwingTrend = false; + // // Checking Momentum Bar ... - bool isMomentum = eaPatternDetector.IsMomentumBar( - cBar, - iDir // - ); - bool isBullishMomentum = isMomentum && - IsSpecifiedBullish(iDir); - bool isBearishMomentum = isMomentum && - IsSpecifiedBearish(iDir); - if (isMomentum) + if (detectMomentum) { - Print(ToXString(iDir), " Momentum Bar: ", cBar.time); + // + bool isMomentum = eaPatternDetector.IsMomentumBar( + cBar, + iDir // + ); + bool isBullishMomentum = isMomentum && + IsSpecifiedBullish(iDir); + bool isBearishMomentum = isMomentum && + IsSpecifiedBearish(iDir); + if (isMomentum) + { + Print(ToXString(iDir), " Momentum Bar: ", cBar.time); + } } // // Checking Engulfed Bar ... - bool isEngulfed = eaPatternDetector.IsEngulfedBar( - cBar, - iDir // - ); - bool isBullishEngulfed = isEngulfed && - IsSpecifiedBullish(iDir); - bool isBearishEngulfed = isEngulfed && - IsSpecifiedBearish(iDir); - if (isEngulfed) + if (detectEngulfed) { - Print(ToXString(iDir), " Engulfed Bar: ", cBar.time); + // + bool isEngulfed = eaPatternDetector.IsEngulfedBar( + cBar, + iDir // + ); + bool isBullishEngulfed = isEngulfed && + IsSpecifiedBullish(iDir); + bool isBearishEngulfed = isEngulfed && + IsSpecifiedBearish(iDir); + if (isEngulfed) + { + Print(ToXString(iDir), " Engulfed Bar: ", cBar.time); + } } // // Checking TruGaped Bar ... - bool isTrueGaped = eaPatternDetector.IsTrueGapedBar( - cBar, - iDir // - ); - bool isBullishTrueGaped = isTrueGaped && - IsSpecifiedBullish(iDir); - bool isBearishTrueGaped = isTrueGaped && - IsSpecifiedBearish(iDir); - if (isTrueGaped) + if (detectTrueGaped) { - Print(ToXString(iDir), " TrueGapped Bar: ", cBar.time); + // + bool isTrueGaped = eaPatternDetector.IsTrueGapedBar( + cBar, + iDir // + ); + bool isBullishTrueGaped = isTrueGaped && + IsSpecifiedBullish(iDir); + bool isBearishTrueGaped = isTrueGaped && + IsSpecifiedBearish(iDir); + if (isTrueGaped) + { + Print(ToXString(iDir), " TrueGapped Bar: ", cBar.time); + } } // // Checking Pinned Bar ... - bool isPinned = eaPatternDetector.IsPinnedBar( - cBar, - iDir // - ); - bool isBullishPinned = isPinned && - IsSpecifiedBullish(iDir); - bool isBearishPinned = isPinned && - IsSpecifiedBearish(iDir); - if (isPinned) + if (detectPinned) { - Print(ToXString(iDir), " Pinned Bar: ", cBar.time); + bool isPinned = eaPatternDetector.IsPinnedBar( + cBar, + iDir // + ); + bool isBullishPinned = isPinned && + IsSpecifiedBullish(iDir); + bool isBearishPinned = isPinned && + IsSpecifiedBearish(iDir); + if (isPinned) + { + Print(ToXString(iDir), " Pinned Bar: ", cBar.time); + } } // // Checking Star Pattern ... - bool isStarPattern = eaPatternDetector.IsStartPattern( - cBar, - iDir // - ); - bool isBullishStarPattern = isStarPattern && - IsSpecifiedBullish(iDir); - bool isBearishStarPattern = isStarPattern && - IsSpecifiedBearish(iDir); - if (isStarPattern) + if (detectStarPattern) { - Print(ToXString(iDir), " Star Pattern: ", cBar.time); + bool isStarPattern = eaPatternDetector.IsStartPattern( + cBar, + iDir // + ); + bool isBullishStarPattern = isStarPattern && + IsSpecifiedBullish(iDir); + bool isBearishStarPattern = isStarPattern && + IsSpecifiedBearish(iDir); + if (isStarPattern) + { + Print(ToXString(iDir), " Star Pattern: ", cBar.time); + } } // // Checking Piercing Pattern ... - bool isPiercingPattern = eaPatternDetector.IsPiercingPattern( - cBar, - iDir // - ); - bool isBullishPiercingPattern = isPiercingPattern && - IsSpecifiedBullish(iDir); - bool isBearishPiercingPattern = isPiercingPattern && - IsSpecifiedBearish(iDir); - if (isPiercingPattern) + if (detectPiercingPattern) { - Print(ToXString(iDir), " Piercing Pattern: ", cBar.time); + // + bool isPiercingPattern = eaPatternDetector.IsPiercingPattern( + cBar, + iDir // + ); + bool isBullishPiercingPattern = isPiercingPattern && + IsSpecifiedBullish(iDir); + bool isBearishPiercingPattern = isPiercingPattern && + IsSpecifiedBearish(iDir); + if (isPiercingPattern) + { + Print(ToXString(iDir), " Piercing Pattern: ", cBar.time); + } } // // Checking Rising Pattern ... - bool isRisingPattern = eaPatternDetector.IsRisingPattern( - cBar, - iDir // - ); - bool isBullishRisingPattern = isRisingPattern && - IsSpecifiedBullish(iDir); - bool isBearishRisingPattern = isRisingPattern && - IsSpecifiedBearish(iDir); - if (isRisingPattern) + if (detectRisingPattern) { - Print(ToXString(iDir), " Rising Pattern: ", cBar.time); + // + bool isRisingPattern = eaPatternDetector.IsRisingPattern( + cBar, + iDir // + ); + bool isBullishRisingPattern = isRisingPattern && + IsSpecifiedBullish(iDir); + bool isBearishRisingPattern = isRisingPattern && + IsSpecifiedBearish(iDir); + if (isRisingPattern) + { + Print(ToXString(iDir), " Rising Pattern: ", cBar.time); + } } // // Checking Flag Pattern ... - XOHCL swingBar; - bool isFlagPattern = eaPatternDetector.IsFlagPattern( - cBar, - iDir, - swingBar // - ); - bool isBullishFlagPattern = isFlagPattern && - IsSpecifiedBullish(iDir); - bool isBearishFlagPattern = isFlagPattern && - IsSpecifiedBearish(iDir); - if (isFlagPattern) + if (detectFlagPattern) { - Print(ToXString(iDir), " Flag Pattern: ", cBar.time, ", Swing: ", swingBar.time); + // + XOHCL swingBar; + bool isFlagPattern = eaPatternDetector.IsFlagPattern( + cBar, + iDir, + swingBar // + ); + bool isBullishFlagPattern = isFlagPattern && + IsSpecifiedBullish(iDir); + bool isBearishFlagPattern = isFlagPattern && + IsSpecifiedBearish(iDir); + if (isFlagPattern) + { + Print(ToXString(iDir), " Flag Pattern: ", cBar.time, ", Swing: ", swingBar.time); + } + swingBar.Clean(); + } + + // + // Detect Swing Trend ... + if (detectSwingTrend) + { + // + XOHCL swings[]; + bool hasSwingTrend = eaPatternDetector.HasSwingTrend( + cBar, + iDir, + swings // + ); + bool hasBullishSwingTrend = hasSwingTrend && + IsSpecifiedBullish(iDir); + bool hasBearishSwingTrend = hasSwingTrend && + IsSpecifiedBearish(iDir); + if (hasSwingTrend) + { + Print(ToXString(iDir), " Swing Trend: ", cBar.time); + } + SpecifiedClean(swings); + } + + // + // Detect SignalKey Bar Pattern ... + if (detectSignalKeyBarPattern) + { + // + bool isSignalKeyBar = eaPatternDetector.IsSignalKeyBarPattern( + cBar, + iDir // + ); + bool isBullishSignalKeyBar = isSignalKeyBar && + IsSpecifiedBullish(iDir); + bool isBearishSignalKeyBar = isSignalKeyBar && + IsSpecifiedBearish(iDir); + if (isSignalKeyBar) + { + Print(ToXString(iDir), " SignalKey Bar Pattern: ", cBar.time); + } } - swingBar.Clean(); } // @@ -754,5 +852,3 @@ void OnTradeStateChanged(const XOnTradeHandlerState &state) { eaExpert.HandleOnTradeStateChanged(state); } - -// \ No newline at end of file diff --git a/Libraries/x-saherelm.common.extensions.lib.mq5 b/Libraries/x-saherelm.common.extensions.lib.mq5 index 021cc8d7..1a4429be 100644 --- a/Libraries/x-saherelm.common.extensions.lib.mq5 +++ b/Libraries/x-saherelm.common.extensions.lib.mq5 @@ -1246,6 +1246,24 @@ bool IsRunningOnTestMode() return result; } +/** + * Check Expert Running in Visual Testing Mode ... + * + * @return ( bool ) + */ +bool IsRunningeOnTestVisualMode() +{ + // + bool result = false; + + // + result = IsRunningOnTestMode() && + MQLInfoInteger(MQL_VISUAL_MODE); + + // + return result; +} + /** * Find Chart ID ... *