From cfba2b3e3ab6023e491740a49fd1cb8da59797aa Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 1 Oct 2025 00:26:07 +0330 Subject: [PATCH] last ... --- Experts/x-saherelm.xfima.backtester.ea.mq5 | 2 + Helpers/x-saherelm.xfima.helper.mq5 | 150 ++++++++++++-- .../x-saherelm.common.extensions.lib.mq5 | 5 + .../x-saherelm.xfima.signaller.class.mq5 | 186 ++++++++++-------- .../x-saherelm.xfima.x-poi.detector.class.mq5 | 22 +++ XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 | 28 ++- 6 files changed, 285 insertions(+), 108 deletions(-) diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index 7cf55686..d336bf3a 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -639,6 +639,8 @@ void OnSignalTriggered(XSignal &signal) signal, result // ); + + // Print("Signal Issued: ", signal.GetObjectID()); } diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index 89dad5d8..b08d4fc4 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -1254,13 +1254,128 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + /** + * Check Specified Bar has MA Cross or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ... + * + * @return ( bool ) + */ + bool HasMACross( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + double validCrossDiffMultiplier = 1 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0); + + // + double fast[]; + double slow[]; + double upper[]; + double lower[]; + int count = ReadMAValues( + fast, + slow, + upper, + lower, + barIndex, + 2 // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + bool notEmpty = + NotEmptyZero(fast[0]) && + NotEmptyZero(fast[1]) && + NotEmptyZero(slow[0]) && + NotEmptyZero(slow[1]); + + // + isBullish = + notEmpty && + fast[0] > slow[0] && + fast[1] < slow[1]; + + // + isBearish = + notEmpty && + fast[0] < slow[0] && + fast[1] > slow[1]; + + // + result = + isBullish || + isBearish; + + // + // Validate Direction Change ... + if (result && + validCrossDiffMultiplier > 0) + { + // + double _points = GetPoints(GetSymbol()); + double diff = MathAbs(fast[0] - slow[0]); + + // + result = diff >= (validCrossDiffMultiplier * _points); + } + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(fast); + XClean(slow); + XClean(upper); + XClean(lower); + + // + return result; + } + /** * Extract Specified Kind of Pivots ... * * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... - * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ... * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... * * @return ( int ) @@ -1269,7 +1384,7 @@ class XCXFIMAHelper : public XCBaseHelper XPivot &pivots[], int barIndex = 0, int requiredNumberOFPivots = 50, - int validationLength = 0, + double validCrossDiffMultiplier = 1, int maxAllowedLoopbackLength = 1500 // ) { @@ -1283,9 +1398,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Normalize ... barIndex = NormalizeInt(barIndex, 0); - validationLength = NormalizeInt(validationLength, 0); requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0); // // Validate ... @@ -1362,18 +1477,22 @@ class XCXFIMAHelper : public XCBaseHelper // // Validate Value ... - has = NotEmptyZero(iFValue) && - NotEmptyZero(iSValue) && - NotEmptyZero(pFValue) && - NotEmptyZero(pSValue); + has = + HasMACross( + iDir, + idx, + validCrossDiffMultiplier // + ) && + NotEmptyZero(iFValue) && + NotEmptyZero(iSValue) && + NotEmptyZero(pFValue) && + NotEmptyZero(pSValue); if (has) { // // Check Direction Changed ... - isSwitchedToBullish = iFValue > iSValue && - pFValue < pSValue; - isSwitchedToBearish = iFValue < iSValue && - pFValue > pSValue; + isSwitchedToBullish = IsXBullish(iDir); + isSwitchedToBearish = IsXBearish(iDir); has = isSwitchedToBullish || isSwitchedToBearish; @@ -1400,15 +1519,6 @@ class XCXFIMAHelper : public XCBaseHelper has = has && HasDirection(iDir); - // - // Check Validation ... - if (has && - validationLength > 0) - { - // - // Validate ... - } - // if (has) { diff --git a/Libraries/x-saherelm.common.extensions.lib.mq5 b/Libraries/x-saherelm.common.extensions.lib.mq5 index 97b5a565..1a3e7c5f 100644 --- a/Libraries/x-saherelm.common.extensions.lib.mq5 +++ b/Libraries/x-saherelm.common.extensions.lib.mq5 @@ -4096,6 +4096,11 @@ void SpecifiedClean(T &buffer[]) { Clean(buffer); } +template +void XClean(T &buffer[]) +{ + Clean(buffer); +} // // Copy Whole Content of Source to Dest array ... diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index f9d8b021..e4bdd121 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -569,7 +569,11 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller { // // Configure Detector ... + // analyserConfig.Default(); + analyserConfig.validMACrossDiffMultiplier = 4; + + // analyserConfig.FullDetect(); } @@ -1165,94 +1169,101 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller // // Testing Bar Zones ... - XBoxZone barZones[]; - int barCounts = fima2Signaller.fimaHelper.ExtractBarZones( - barZones, - 1, // Bar Index ... - 50, // Number of Zones ... - 3, // Break Validation Length ... - true, // Validate Fake Breakes ... - 5, // Shadow Multiplier ... - 1, // Strength ... - 14 // Validation Length ... - ); - if (IsValidSize(barCounts)) - { - // - XCBoxObject *iObj; - for (int i = 0; i < barCounts; i++) - { - // - iObj = NULL; - bool isCreated = fima2Signaller.poiDrawer.DrawBox( - barZones[i], - iObj, - true, // Ignore At ... - barZones[i].type // Name ... - ); + // XBoxZone barZones[]; + // int barCounts = fima2Signaller.fimaHelper.ExtractBarZones( + // barZones, + // 1, // Bar Index ... + // 50, // Number of Zones ... + // 3, // Break Validation Length ... + // true, // Validate Fake Breakes ... + // 5, // Shadow Multiplier ... + // 1, // Strength ... + // 14 // Validation Length ... + // ); + // if (IsValidSize(barCounts)) + // { + // // + // // XCBoxObject *iObj; + // // for (int i = 0; i < barCounts; i++) + // // { + // // // + // // iObj = NULL; + // // bool isCreated = fima2Signaller.poiDrawer.DrawBox( + // // barZones[i], + // // iObj, + // // true, // Ignore At ... + // // barZones[i].type // Name ... + // // ); - // - ZeroMemory(iObj); - } + // // // + // // ZeroMemory(iObj); + // // } - // // - // Print("Bar Zones Detected ..."); - } + // // // + // // Print("Bar Zones Detected ..."); + // } // // Testing HK Zones ... - XBoxZone hkZones[]; - int hkCounts = fima2Signaller.fimaHelper.ExtractHKZones( - hkZones, - 1, // Bar Index ... - 50, // Number of Zones ... - 5, // Shadow Multiplier ... - 1, // Strength ... - 14 // Validation Length ... - ); - if (IsValidSize(hkCounts)) - { - // // - // XCBoxObject *iObj; - // for (int i = 0; i < hkCounts; i++) - // { - // // - // iObj = NULL; - // bool isCreated = fima2Signaller.poiDrawer.DrawBox( - // hkZones[i], - // iObj, - // true, // Ignore At ... - // hkZones[i].type // Name ... - // ); + // XBoxZone hkZones[]; + // int hkCounts = fima2Signaller.fimaHelper.ExtractHKZones( + // hkZones, + // 1, // Bar Index ... + // 50, // Number of Zones ... + // 5, // Shadow Multiplier ... + // 1, // Strength ... + // 14 // Validation Length ... + // ); + // if (IsValidSize(hkCounts)) + // { + // // // + // // XCBoxObject *iObj; + // // for (int i = 0; i < hkCounts; i++) + // // { + // // // + // // iObj = NULL; + // // bool isCreated = fima2Signaller.poiDrawer.DrawBox( + // // hkZones[i], + // // iObj, + // // true, // Ignore At ... + // // hkZones[i].type // Name ... + // // ); - // // - // ZeroMemory(iObj); - // } + // // // + // // ZeroMemory(iObj); + // // } - // // - // Print("HK Zones Detected ..."); - } + // // // + // // Print("HK Zones Detected ..."); + // } // // Testing XFIMA MA Pivots ... - XPivot maPivots[]; - int maPivotsCount = fimaHelper.ExtractMAPivots( - maPivots, - 1, // Bar Index ... - 50, // Number of Pivots ... - 0 // Validation Length ... - ); - if (IsValidSize(maPivotsCount)) - { - // - CArrayObj *iPivotsObj; - maPivotsCount = poiDrawer.DrawPivots( - maPivots, - iPivotsObj // - ); + // XPivot maPivots[]; + // int maPivotsCount = fimaHelper.ExtractMAPivots( + // maPivots, + // 1, // Bar Index ... + // 50, // Number of Pivots ... + // 1 // Validation Diff ... + // ); + // if (IsValidSize(maPivotsCount)) + // { + // // + // // CArrayObj *iPivotsObj; + // // maPivotsCount = poiDrawer.DrawPivots( + // // maPivots, + // // iPivotsObj // + // // ); - // - Print("MA Pivots Detected ..."); + // // + // // Print("MA Pivots Detected ..."); + // } + + // + bool hasMACross = HasDirection(structure.maCrossDir); + if (hasMACross) + { + Print(ToXString(structure.maCrossDir), " MaCross Detected ..."); } // @@ -1357,16 +1368,17 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller // // Strategy 1 ... - has = Strategy1HasSignal( - bar, - iZone, - iName, - supports, - resistances, - iDir, - structure, - fimaConditions // - ); + has = false; + // has = Strategy1HasSignal( + // bar, + // iZone, + // iName, + // supports, + // resistances, + // iDir, + // structure, + // fimaConditions // + // ); // // Do all Draws Here ... diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 index 17521980..0929257b 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -916,6 +916,28 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector resistance.Clean(); } + // + // Detecting MA Crosses ... + if (config.detectMACrosses) + { + // + idx = forBar.Index(); + has = fimaHelper.HasMACross( + structure.maCrossDir, + idx, + config.validMACrossDiffMultiplier // + ); + + // + fimaHelper.ExtractMAPivots( + structure.maCrosses, + idx, + config.recentlyPatternsMaxAllowedCollecting, + config.validMACrossDiffMultiplier, + config.recentlyPatternsMaxLookupLength // + ); + } + // // Analysers ... diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index 3d2ea6de..30765ece 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -69,6 +69,10 @@ struct XFIMAPatternDetectorConfig bool analyseFIMASARPivots; bool analyseFIMAZigZagPivots; + // + bool detectMACrosses; + double validMACrossDiffMultiplier; + // // Configs ... @@ -159,6 +163,10 @@ struct XFIMAPatternDetectorConfig analyseFIMASARPivots = false; analyseFIMAZigZagPivots = false; + // + detectMACrosses = false; + validMACrossDiffMultiplier = 0; + // obLoopback = 0; fvgLoopback = 0; @@ -226,6 +234,10 @@ struct XFIMAPatternDetectorConfig analyseFIMASARPivots = false; analyseFIMAZigZagPivots = false; + // + detectMACrosses = true; + validMACrossDiffMultiplier = 1; + // // OB / FVg ... obLoopback = 5; @@ -314,6 +326,9 @@ struct XFIMAPatternDetectorConfig analyseFIMAPVPivots = true; analyseFIMASARPivots = true; analyseFIMAZigZagPivots = true; + + // + detectMACrosses = true; } /** @@ -352,6 +367,9 @@ struct XFIMAPatternDetectorConfig analyseFIMAPVPivots = false; analyseFIMASARPivots = false; analyseFIMAZigZagPivots = false; + + // + detectMACrosses = false; } // @@ -428,6 +446,10 @@ struct XFIMAMarketStructure ENUM_X_DIRECTION piercingPatternDir; ENUM_X_DIRECTION signalKeyBarPatternDir; + // + ENUM_X_DIRECTION maCrossDir; + XPivot maCrosses[]; + // // Constructor ... XFIMAMarketStructure() @@ -473,6 +495,10 @@ struct XFIMAMarketStructure piercingPatternDir = X_DIRECTION_NONE; signalKeyBarPatternDir = X_DIRECTION_NONE; + // + maCrossDir = X_DIRECTION_NONE; + SpecifiedClean(maCrosses); + // SpecifiedClean(obs); SpecifiedClean(fvgs); @@ -516,7 +542,7 @@ struct XFIMAMarketStructureDrawerConfig bool drawFVG; // Current Fair Value Gap ... // - bool drawSupport; // Detected Supports ... + bool drawSupport; // Detected Supports ... bool drawResistance; // Detected Resistances ... //