From bc89de0b5e94c06ee624169b9ee78c9ace42edac Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 19 Oct 2025 17:07:31 +0330 Subject: [PATCH] last ... --- .../x-saherelm.xfima.signaller.class.mq5 | 2 +- .../x-saherelm.xfima.signaller.class_@!!@.mq5 | 986 ++++++++++++++++++ 2 files changed, 987 insertions(+), 1 deletion(-) create mode 100644 XFIMAEA/Classes/x-saherelm.xfima.signaller.class_@!!@.mq5 diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index 70390086..4bf7dab9 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -381,7 +381,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // // TODO: Provided SL ... double _point = GetPoints(iBar.symbol); - double slAddition = 5 * _point; + double slAddition = 10 * _point; double atrAddition = GetAverageTrueRange( iZone.symbol, iZone.period, diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class_@!!@.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class_@!!@.mq5 new file mode 100644 index 00000000..4bf7dab9 --- /dev/null +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class_@!!@.mq5 @@ -0,0 +1,986 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class +// ------------------------------------------------- +// Name: XCXFIMASignaller ... +// Description: XFIMA Signaller Class ... +// +// +// 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 XFIMA Signaller Class" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.x-signaller.class.mq5" +#include "../../Helpers/x-saherelm.xfima.helper.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.drawer.class.mq5" + +// +// Implementation ... + +// +// Base XFIMA base Signaller ... +class XCXFIMABaseSignaller : public XCBaseSignaller +{ + // + // Public ... + public: + // + // Props ... + + // + bool ignoreTargets; // Ignore Signal Targets ... + CArrayObj drawnObjects; // Drawing Objects Holder ... + XFIMAInputs fimaInputs; // XFIMA Inputs ... + XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... + XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... + XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ... + XFIMAMarketStructureConfig structureConfig; // XFIMA Market Structure Detector Config ... + XFIMAMarketStructureDrawerConfig structureDrawConfig; // XFIMA Market Structure Draw Config ... + + // + // Constructor ... + XCXFIMABaseSignaller( + string _name, // Name ... + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCBaseSignaller(_name, + _symbol, + _period, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + // Instantiating XFIMA Indicator Helper Class ... + if (_fimaInputs.IsValid()) + { + // + fimaHelper = new XCXFIMAHelper(); + bool isInited = fimaHelper.Init( + _symbol, + _period, + _fimaInputs // + ); + if (isInited) + { + fimaInputs = _fimaInputs; + } + else + { + // + delete fimaHelper; + ZeroMemory(fimaHelper); + } + } + + // + poiDrawer = new XCXFIMAPOIDrawer(); + poiDetector = new XCXFIMAPOIDetector(fimaHelper); + + // + // Configure ... + structureConfig.Default(); + structureDrawConfig.Default(); + } + + // + // Deconstructor ... + ~XCXFIMABaseSignaller() + { + Destroy(); + } + + // + // Overrides ... + + // + // Actions ... + + /** + * Destroy ... + */ + void Destroy() + { + // + BeforeDestroy(); + + // + fimaInputs.Clean(); + + // + delete fimaHelper; + ZeroMemory(fimaHelper); + + // + delete poiDrawer; + ZeroMemory(poiDrawer); + + // + delete poiDetector; + ZeroMemory(poiDetector); + + // + structureConfig.Clean(); + structureDrawConfig.Clean(); + } + + // + // Virtuals ... + + /** + * Before Destroy ... + */ + void virtual BeforeDestroy() + { + } + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard, reference collection to holds result ... + * @param positions: XPosition, reference collection to provides positions ... + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + XPosition &positions[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + /** + * Check Additional Validations on Childs Instances ... + * + * @return ( bool virtual ) + */ + bool virtual CheckAdditionslSignallerValidations() + { + // + bool result = false; + + // + // Validate Fima Helper Requirements ... + result = fimaInputs.IsValid() && + fimaHelper != NULL && + poiDetector != NULL; + + // + return result; + } + + /** + * Normalizing Signal by Signaller Custom Props ... + * + * @param signal: XSignal ... + */ + void virtual NormalizeSignal(XSignal &signal) + { + } + + // + // Protected ... + protected: + // + + // + // Protected Actions ... + + // + // Private ... + private: + // +}; + +// +// XFIMA Strategy 2 Signaller Class ... +class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller +{ + // + // Public ... + public: + // + // Props ... + XFIMAConditions conditions; // XFIMA Conditions ... + XFIMAMarketStructure structure; // XFIMA Market Structure ... + + // + // Constructor ... + XCXFIMAStrategy1Signaller( + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCXFIMABaseSignaller("XFIMA1", + _symbol, + _period, + _fimaInputs, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + // Configure ... + structureConfig.Default(); + structureDrawConfig.Default(); + + // + structure.Clean(); + + // + // Ignore Signal Targets ... + ignoreTargets = false; + } + + // + // Deconstructor ... + ~XCXFIMAStrategy1Signaller() + { + // + Destroy(); + + // + structure.Clean(); + } + + // + // Overrides ... + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + XOHCL iBar; + int count = 0; + XBoxZone iZone; + XSignal iSignal; + bool has = false; + XTarget iTargets[]; + string iName = NULL; + bool isBullish = false; + bool isBearish = false; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Initialize Bar as CBar ... + has = iBar.Init( + symbol, + period, + barIndex // + ); + if (!has) + { + // + iBar.Clean(); + return; + } + + // + // Strategy 1 ... + has = Strategy1HasSignal( + iBar, + iZone, + iTargets, + iDir // + ); + + // + has = HasDirection(iDir) && + iZone.IsValid(); + if (has) + { + // + // Draw Zone ... + + // + // has = false; + // iZone.Clean(); + // iDir = X_DIRECTION_NONE; + } + + // + if (has) + { + // + isBullish = IsXBullish(iDir); + isBearish = IsXBearish(iDir); + + // + // TODO: Provided SL ... + double _point = GetPoints(iBar.symbol); + double slAddition = 10 * _point; + double atrAddition = GetAverageTrueRange( + iZone.symbol, + iZone.period, + 0 // + ); + double slPrice = + isBullish + ? iZone.lower - slAddition + : iZone.upper + slAddition; + + // + // Prepare Founded Signal ... + + // + // Handle Signal Targets ... + if (ignoreTargets) + { + XClean(iTargets); + } + + // + has = PrepareSignal( + iSignal, + iDir, + iTargets, + 0, // Use Default R2R ... + slPrice, // Provided Price for SL ... + 0 // Specified Risk in Point .... + ); + if (has) + { + // + // Notify On Signal Event ... + NotifySignalEventListeners(iSignal); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + iZone.Clean(); + iSignal.Clean(); + SpecifiedClean(iTargets); + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard, reference collection to holds result ... + * @param positions: XPosition, reference collection to provides positions ... + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + XPosition &positions[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + // + // Private ... + private: + // + // Props ... + + // + // Implementing Strategies ... + + /** + * Check Bar Has Signal Based on Strategy 1 ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool Strategy1HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Define Requirements ... + + // + XOHCL pBar; + XOHCL p2Bar; + bool isBullish = false; + bool isBearish = false; + + // + // Read PBar ... + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + + // + return result; + } + + // + // Reading pBar Patterns ... + XPatternAnalysis pBarAnalysis; + poiDetector.AnalyseBarPatterns( + pBar, + pBarAnalysis, + structureConfig.barsAnalysisConfig // + ); + + // + // Check Bar Patterns ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + double pPeak = fimaHelper.GetPeak(pBar.Index()); + double pVale = fimaHelper.GetVale(pBar.Index()); + bool isPPeakOverLast = fimaHelper.IsPeakOverLast(pBar.Index()); + bool isPValeUnderLast = fimaHelper.IsValeUnderLast(pBar.Index()); + bool isP2PeakOverLast = fimaHelper.IsPeakOverLast(p2Bar.Index()); + bool isP2ValeUnderLast = fimaHelper.IsValeUnderLast(p2Bar.Index()); + bool isPeakOverLast = isPPeakOverLast || + isP2PeakOverLast; + bool isValeUnderLast = isPValeUnderLast || + isP2ValeUnderLast; + + // + // Check PBar Close Over Under Fast Ma ... + bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index()); + bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index()); + bool isFastOverLast = fimaHelper.GetMAFast(pBar.Index()) > fimaHelper.GetMAFast(p2Bar.Index()); + bool isFastUnderLast = fimaHelper.GetMAFast(pBar.Index()) < fimaHelper.GetMAFast(p2Bar.Index()); + + // + // Force P2Bar is Pin Bar ... + ENUM_X_DIRECTION p2Dir; + bool isP2BarPinned = poiDetector.IsPinnedBar( + p2Bar, + p2Dir // + ); + bool isP2BarBullishPinned = + isP2BarPinned && + IsXBullish(p2Dir); + bool isP2BarBearishPinned = + isP2BarPinned && + IsXBearish(p2Dir); + + // + // Do ... + + // + isBullish = + // + isFastOverLast && + isValeUnderLast && + isPBarCloseOverFast && + isP2BarBullishPinned && + isPBarHasBullishPatterns + // + ; + + // + isBearish = + // + isPeakOverLast && + isFastUnderLast && + isPBarCloseUnderFast && + isP2BarBearishPinned && + isPBarHasBearishPatterns + // + ; + + // + // Validate ... + result = isBullish || + isBearish; + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = HasDirection(dir); + } + + // + // Prepare Zone ... + if (result) + { + // + zone.Clean(); + result = ToBox( + p2Bar, + zone, + dir, + X_BAR_PATTERN_PINNED // + ); + + // + if (result) + { + // + zone.to = bar.time; + + // + poiDrawer.DrawZone( + zone, + structureDrawConfig.drawConfig // + ); + } + + // + result = zone.IsValid(); + } + + // + // Prepare Targets ... + if (result) + { + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + p2Bar.Clean(); + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 1 ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool Strategy2HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Define Requirements ... + + // + XOHCL pBar; + bool isBullish = false; + bool isBearish = false; + + // + // Read PBar ... + result = bar.GetPreviousBar(pBar); + if (!result) + { + // + pBar.Clean(); + return result; + } + + // + // Reading Conditions ... + int pullBackStartBar = -1; + bool isPullBack = result && + poiDetector.IsPullbackPattern( + pBar, + zone, + dir, + 2, + false // Force Break ... + ); + bool isPullbackBullish = isPullBack && + IsXBullish(dir); + bool isPullbackBearish = isPullBack && + IsXBearish(dir); + if (isPullBack) + { + pullBackStartBar = zone.FromIndex(); + } + + // + // Reading HK Bond ... + + // + double pHKBondUpper = fimaHelper.GetHKBondUpper(pBar.Index()); + double pHKBondLower = fimaHelper.GetHKBondLower(pBar.Index()); + int overHKBondUpperCount = fimaHelper.CountOverHKBondUpper(pullBackStartBar, X_PRICE_LOW); + int underHKBondLowerCount = fimaHelper.CountUnderHKBondLower(pullBackStartBar, X_PRICE_HIGH); + + // + // Reading PV Requirements ... + + // + int lastPeakOverLastIDX = -1; + int lastValeUnderLastIDX = -1; + double pPeak = fimaHelper.GetPeak(pBar.Index()); + double pVale = fimaHelper.GetVale(pBar.Index()); + int samePeaks = fimaHelper.CountSamePeaks(pBar.Index()); + int sameVales = fimaHelper.CountSameVales(pBar.Index()); + fimaHelper.FindLastPeakOverLast(lastPeakOverLastIDX, pBar.Index()); + fimaHelper.FindLastValeUnderLast(lastValeUnderLastIDX, pBar.Index()); + + // + // Reading pBar Patterns ... + XPatternAnalysis pBarAnalysis; + poiDetector.AnalyseBarPatterns( + pBar, + pBarAnalysis, + structureConfig.barsAnalysisConfig // + ); + + // + // Check Bar Patterns ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + // Check PBar Close Over Under Fast Ma ... + bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index()); + bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index()); + + // + // Try To Find Affected Zone ... + + // + // Collecting Zones ... + XBoxZone zones[]; + XBoxZone affectedZones[]; + XBoxZone affectedZonesBullish[]; + XBoxZone affectedZonesBearish[]; + int zonesCount = poiDetector.CollectZones( + pBar, + zones, // + 5, // Zones Loopback ... + 3 // Zones Validation Length ... + // Required Zones ... + // Loopback ... + ); + int affectedZonesCount = ExtractAffectedZones( + pBar, + zones, + affectedZones // + ); + int affectedZonesBullishCount = ExtractByDirection( + affectedZonesBullish, + affectedZones, + X_DIRECTION_BULLISH // + ); + int affectedZonesBearishCount = ExtractByDirection( + affectedZonesBearish, + affectedZones, + X_DIRECTION_BEARISH // + ); + + // + int insideBullishIDX = -1; + int insideBearishIDX = -1; + bool hasBullishInside = + pBar.IsBullish() && + HasInside( + insideBullishIDX, + pBar, + affectedZonesBullish // + ); + bool hasBearishInside = + pBar.IsBearish() && + HasInside( + insideBearishIDX, + pBar, + affectedZonesBearish // + ); + + // + // Do ... + + // + isBullish = + // + hasBullishInside && + isPullbackBullish && + isPBarHasBullishPatterns && + fimaHelper.IsSarBullish(pBar.Index()) && + (pVale >= affectedZonesBullish[insideBullishIDX].lower && + pVale <= affectedZonesBullish[insideBullishIDX].upper) + // + ; + + // + isBearish = + // + hasBearishInside && + isPullbackBearish && + isPBarHasBearishPatterns && + fimaHelper.IsSarBearish(pBar.Index()) && + (pPeak >= affectedZonesBearish[insideBearishIDX].lower && + pPeak <= affectedZonesBearish[insideBearishIDX].upper) + // + ; + + // + // Validate ... + result = isBullish || + isBearish; + if (result) + { + // + if (isBullish) + { + // + poiDrawer.DrawZone( + affectedZonesBullish[insideBullishIDX], + structureDrawConfig.drawConfig // + ); + } + else + { + // + poiDrawer.DrawZone( + affectedZonesBearish[insideBearishIDX], + structureDrawConfig.drawConfig // + ); + } + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = HasDirection(dir); + } + + // + // Prepare Zone ... + if (result) + { + // + zone.Clean(); + if (isBullish) + { + zone = affectedZonesBullish[insideBullishIDX]; + } + else + { + zone = affectedZonesBearish[insideBearishIDX]; + } + + // + result = zone.IsValid(); + } + + // + // Prepare Targets ... + if (result) + { + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + XClean(zones); + pBarAnalysis.Clean(); + XClean(affectedZones); + XClean(affectedZonesBullish); + XClean(affectedZonesBearish); + + // + return result; + } + + // +}; + +// \ No newline at end of file