From 46fda23346dc0a0633cd7113057d5daa5c968fcf Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 5 Jun 2024 08:48:31 +0330 Subject: [PATCH] last works ... must Fix Refactoring X_POSITION_TYPE side affects ... --- Classes/x-saherelm.x121.provider.class.mq5 | 10 ++ Classes/x-saherelm.x121.xea.class.mq5 | 132 +++++++++++++++++- Classes/x-saherelm.x121.xmcycle.class.mq5 | 34 +++++ Classes/x-saherelm.xea.class.mq5 | 2 +- Classes/x-saherelm.xtrade.class.mq5 | 40 +++--- Libraries/x-saherelm.xtrade.lib.mq5 | 32 ++++- .../x-saherelm.x110.signaller.class.mq5 | 34 ----- .../x-saherelm.x121.signaller.class.mq5 | 34 ----- .../x-saherelm.x786.signaller.class.mq5 | 34 ----- 9 files changed, 225 insertions(+), 127 deletions(-) diff --git a/Classes/x-saherelm.x121.provider.class.mq5 b/Classes/x-saherelm.x121.provider.class.mq5 index 34e2d289..08264fcc 100644 --- a/Classes/x-saherelm.x121.provider.class.mq5 +++ b/Classes/x-saherelm.x121.provider.class.mq5 @@ -1739,6 +1739,9 @@ struct X121ProviderDescriptor slPrice, tpPrice // ); + if (mSL == 0 && mTP == 0) { + Print("Zero TP/SL ..."); + } // result = this.signal.Prepare( @@ -1779,6 +1782,13 @@ struct X121ProviderDescriptor return result; } + // + // Count Signallers ... + int CountSignallers() + { + return ArraySize(signallers); + } + // // Find Specific Signaller Index ... int FindSignallerIndex(ENUM_XSIGNAL_PROVIDERS name) diff --git a/Classes/x-saherelm.x121.xea.class.mq5 b/Classes/x-saherelm.x121.xea.class.mq5 index 9b5c0273..7e2df881 100644 --- a/Classes/x-saherelm.x121.xea.class.mq5 +++ b/Classes/x-saherelm.x121.xea.class.mq5 @@ -48,6 +48,9 @@ public: int slippage, // Specify Slippage ulong magicNumber, // Specify Magic Number // + // Time Management ... + // TODO: ... + // // XSCTrade Event Handlers ... TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler @@ -278,7 +281,7 @@ public: // - Check Same Time Open Positions ... // - Check Signal Age for new Trade ... // and etc ... - int HandleSignalManagement(XSignal &signals[]) + int HandleSignalManagement(XSignal &signals[]) override { // int result = 0; @@ -502,6 +505,133 @@ public: return result; } + // + // Handle State Management .... + // here we can manage current state ... + // - Check for Long Positions for each Signaller to Close ... + // - Handle Hedging Signaller's Positions if it's enabled ... + // - Force Closing Position when Specified Time reached ... + // - Check Start and End time or Trading Dates ... + // - handle Trailing or Risk free Signals based on several conditions ... + // and etc ... + bool HandleStateManagement(XSignal &signals[]) override + { + // + const bool result = false; + + // + // Check Descriptor ... + int descriptorsCount = CountDescriptors(); + if (!IsValidSize(descriptorsCount)) + { + return result; + } + + // + // Loop Through Descriptors ... + for (int i = 0; i < descriptorsCount; i++) + { + // + // Check Signallers ... + int signallersCount = mDescriptors[i].CountSignallers(); + if (!IsValidSize(signallersCount)) + { + continue; + } + + // + // Loop Through Signallers ... + for (int j = 0; j < signallersCount; j++) + { + // + // Retrieve Specified Signaller's Position ... + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, + mDescriptors[i].symbol, + mDescriptors[i].signallers[j].GetName(), + mDescriptors[i].period); + if (!IsValidSize(positionsCount)) + { + continue; + } + + // + // Check Signaller Enable Hedge or not and Handle it if enabled ... + if (mDescriptors[i].signallers[j].AllowHedge()) + { + // + // Check Profits Enough for Hedge or not ... + double profit = SpecifiedCalculatePositionsProfit(positions); + bool isReadyForHedge = SpecifiedIsPositionsReadyForHedge( + positions, + mDescriptors[i].signallers[j].minRequiredProfitPerTrade, + mDescriptors[i].signallers[j].minRequiredProfitPerTradeVolumeFactor // + ); + if (isReadyForHedge) + { + // + string comment = "Close due Hedge ..."; + int closeds = mTrader.Close( + positions, + comment // + ); + + // + if (closeds > 0) + { + // + string message = "Hedge (" + ToString(closeds) + ") Positions In Profit: " + ToString(profit); + + // + Alert(message); + + // + break; + } + } + } + + // + // Check Closing Long Age Position's Enabled or not ... + if (mDescriptors[i].signallers[j].maxAllowedOpenPositionAge > 0) + { + // + // Handle Close Long Time Trades ... + + // + // Find Oldest ... + XPosition oldest; + int oldestAge = GetOldest( + oldest, + positions // + ); + if (oldestAge >= mDescriptors[i].signallers[j].maxAllowedOpenPositionAge) + { + // + string comment = "Close due Long Age ..."; + bool isClosed = mTrader.Close( + oldest.ticket, + comment // + ); + + // + if (isClosed) + { + // + string message = "Position (" + ToString(oldest.ticket) + ") Closed due Long Age Policy ..."; + Alert(message); + } + } + } + } + } + + // + // if Returns true, Signal Execution failed ... + return result; + } + // // Tools ... diff --git a/Classes/x-saherelm.x121.xmcycle.class.mq5 b/Classes/x-saherelm.x121.xmcycle.class.mq5 index 4cc721eb..bfc3ada8 100644 --- a/Classes/x-saherelm.x121.xmcycle.class.mq5 +++ b/Classes/x-saherelm.x121.xmcycle.class.mq5 @@ -2610,6 +2610,40 @@ public: ignoreProfitForOppositeSignals = false; } + // + // Enable Default Configurations ... + virtual void Default() + { + // + allowLong = true; + allowShort = true; + + // + r2r = 1; + + // + maxAllowedLong = 3; + maxAllowedShort = 3; + + // + staticVolumeLong = 0.01; + staticVolumeShort = 0.01; + + // + maxAllowedOpenPositionAge = 576; // Two Days on 5 Min + delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min + + // + // Set 10 $ Per each Trade on 0.01 Volume + // is Enough for Hedging ... + minRequiredProfitPerTrade = 5; + minRequiredProfitPerTradeVolumeFactor = 0.01; + + // + openNextPositionOnProfit = true; + ignoreProfitForOppositeSignals = true; + } + // // Validate ... bool IsValid() diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index 6bd3fae8..1a448379 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -2466,7 +2466,7 @@ public: // // Handle Position(s)/ Order(s) or EQM Supporting Action ... - // if returns false, prevent for process Tick ... + // if returns true, prevent for process Tick ... virtual bool HandleStateManagement(XSignal &signals[]) { return false; diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index 6274b659..7fdf8c18 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -1813,12 +1813,12 @@ public: // // Close Specified Positions ... int Close( - string comment = NULL, // Close Position By Specific Comment - string symbol = NULL, // Trading Symbol - string provider = NULL, // Signal Provider - ENUM_TIMEFRAMES period = NULL, // Trading Period - ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) - bool filterByMagic = true // Get Only Self Open Positions + string comment = NULL, // Close Position By Specific Comment + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true // Get Only Self Open Positions ) { // @@ -1990,11 +1990,11 @@ public: // // Calculate Positions Profit ... double Profit( - string symbol = NULL, // Trading Symbol - string provider = NULL, // Signal Provider - ENUM_TIMEFRAMES period = NULL, // Trading Period - ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) - bool filterByMagic = true // Get Only Self Open Positions + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true // Get Only Self Open Positions ) { // @@ -2054,13 +2054,13 @@ public: // // Retrieve Positions ... int GetPositions( - XPosition &result[], // Hold's Result - string symbol = NULL, // Trading Symbol - string provider = NULL, // Signal Provider - ENUM_TIMEFRAMES period = NULL, // Trading Period - ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) - bool filterByMagic = true, // Get Only Self Open Positions - bool forceClean = true // Clean Result Array + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array ) { // @@ -2149,7 +2149,7 @@ public: symbol, provider, period, - POSITION_TYPE_BUY, + X_POSITION_TYPE_LONG, filterByMagic, forceClean // ); @@ -2161,7 +2161,7 @@ public: symbol, provider, period, - POSITION_TYPE_SELL, + X_POSITION_TYPE_SHORT, filterByMagic, forceClean // ); diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index 0ed75682..38456ebd 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -111,6 +111,15 @@ enum ENUM_X_GUARD_ACTIONS X_GUARD_ACTION_CANCEL_PENDING_ORDERS, // Cancel Pending Orders }; +// +enum ENUM_X_POSITION_TYPE +{ + X_POSITION_TYPE_NONE = 0, + X_POSITION_TYPE_ALL = 1, + X_POSITION_TYPE_LONG = 2, + X_POSITION_TYPE_SHORT = 3, +}; + // // Structs ... @@ -3523,9 +3532,26 @@ bool IsTypeFilterPassed( ) { // - return type == NULL - ? true - : type == item.type; + bool result = type == item.type; + + // + return result; +} +template +bool IsTypeFilterPassed( + ENUM_X_POSITION_TYPE type, + T &item + // +) +{ + // + bool result = type == NULL || type == X_POSITION_TYPE_ALL + ? true + : ((type == X_POSITION_TYPE_LONG && item.type == POSITION_TYPE_BUY) || + (type == X_POSITION_TYPE_SHORT && item.type == POSITION_TYPE_SELL)); + + // + return result; } template bool IsTypeFilterPassed( diff --git a/Signallers/x-saherelm.x110.signaller.class.mq5 b/Signallers/x-saherelm.x110.signaller.class.mq5 index 14c97d50..92f2f280 100644 --- a/Signallers/x-saherelm.x110.signaller.class.mq5 +++ b/Signallers/x-saherelm.x110.signaller.class.mq5 @@ -295,38 +295,4 @@ public: // return result; } - - // - // Tools ... - void Default() - { - // - allowLong = true; - allowShort = true; - - // - r2r = 1; - - // - maxAllowedLong = 3; - maxAllowedShort = 3; - - // - staticVolumeLong = 0.01; - staticVolumeShort = 0.01; - - // - maxAllowedOpenPositionAge = 576; // Two Days on 5 Min - delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min - - // - // Set 10 $ Per each Trade on 0.01 Volume - // is Enough for Hedging ... - minRequiredProfitPerTrade = 10; - minRequiredProfitPerTradeVolumeFactor = 0.01; - - // - openNextPositionOnProfit = true; - ignoreProfitForOppositeSignals = true; - } }; \ No newline at end of file diff --git a/Signallers/x-saherelm.x121.signaller.class.mq5 b/Signallers/x-saherelm.x121.signaller.class.mq5 index 95e7fce4..e772e2ee 100644 --- a/Signallers/x-saherelm.x121.signaller.class.mq5 +++ b/Signallers/x-saherelm.x121.signaller.class.mq5 @@ -169,38 +169,4 @@ public: // return result; } - - // - // Tools ... - void Default() - { - // - allowLong = true; - allowShort = true; - - // - r2r = 1; - - // - maxAllowedLong = 3; - maxAllowedShort = 3; - - // - staticVolumeLong = 0.01; - staticVolumeShort = 0.01; - - // - maxAllowedOpenPositionAge = 576; // Two Days on 5 Min - delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min - - // - // Set 10 $ Per each Trade on 0.01 Volume - // is Enough for Hedging ... - minRequiredProfitPerTrade = 10; - minRequiredProfitPerTradeVolumeFactor = 0.01; - - // - openNextPositionOnProfit = true; - ignoreProfitForOppositeSignals = true; - } }; \ No newline at end of file diff --git a/Signallers/x-saherelm.x786.signaller.class.mq5 b/Signallers/x-saherelm.x786.signaller.class.mq5 index 23f043ba..514d7231 100644 --- a/Signallers/x-saherelm.x786.signaller.class.mq5 +++ b/Signallers/x-saherelm.x786.signaller.class.mq5 @@ -176,38 +176,4 @@ public: // return result; } - - // - // Tools ... - void Default() - { - // - allowLong = true; - allowShort = true; - - // - r2r = 1; - - // - maxAllowedLong = 3; - maxAllowedShort = 3; - - // - staticVolumeLong = 0.01; - staticVolumeShort = 0.01; - - // - maxAllowedOpenPositionAge = 576; // Two Days on 5 Min - delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min - - // - // Set 10 $ Per each Trade on 0.01 Volume - // is Enough for Hedging ... - minRequiredProfitPerTrade = 10; - minRequiredProfitPerTradeVolumeFactor = 0.01; - - // - openNextPositionOnProfit = true; - ignoreProfitForOppositeSignals = true; - } }; \ No newline at end of file