/////////////////////////////////////////////////////// // // 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; } // }; //