From b3be1b4596c7fdd77bc4bc5beafe1c397218c4f5 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 9 May 2025 04:58:24 +0330 Subject: [PATCH] last ... --- .vscode/vscode-kanban.json | 36 +- Experts/x-saherelm.xcaea.ea.mq5 | 23 +- XCAEA/Classes/xcaea.x-trade.manager.class.mq5 | 387 ++++++++++++++++-- 3 files changed, 399 insertions(+), 47 deletions(-) diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index cfdc2ca5..ca94494d 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -10,24 +10,6 @@ "references": [], "title": "add support for OB in XCAEA POI Detector" }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2025-05-08T10:51:12.522Z", - "id": "5", - "references": [], - "title": "add Trade Session Support and Multi Symbol Structure" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2025-05-08T10:52:04.074Z", - "id": "6", - "references": [], - "title": "Complete Perday Trade Management based on SL(s) and TP(s)" - }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -36,6 +18,15 @@ "id": "7", "references": [], "title": "add support for Swings on Block Detection ..." + }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2025-05-08T10:51:12.522Z", + "id": "5", + "references": [], + "title": "add Trade Session Support and Multi Symbol Structure" } ], "testing": [ @@ -80,6 +71,15 @@ "id": "2", "references": [], "title": "Add Support for Daily Max Volume and Ticks Box in XCAEA POI Detector ..." + }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2025-05-08T10:52:04.074Z", + "id": "6", + "references": [], + "title": "Complete Perday Trade Management based on SL(s) and TP(s)" } ], "done": [] diff --git a/Experts/x-saherelm.xcaea.ea.mq5 b/Experts/x-saherelm.xcaea.ea.mq5 index bb2402e0..67b18e09 100644 --- a/Experts/x-saherelm.xcaea.ea.mq5 +++ b/Experts/x-saherelm.xcaea.ea.mq5 @@ -665,12 +665,23 @@ void InitRequirements() // // Setting Trade Restrictions ... - eaTradeManager.SetTradeRestrictions( - eaRestrictionsPeriod, - eaMaxAllowedTPs, - eaMaxAllowedSLs, - eaMaxAllowedTrades // - ); + eaTradeManager + .SetTradeRestrictions( + eaRestrictionsPeriod, + eaMaxAllowedTPs, + eaMaxAllowedSLs, + eaMaxAllowedTrades // + ); + + // + // Setting Sessions ... + eaTradeManager + .SetTradeSession( + _Symbol, + "03:00", // Start ... + "20:00", // End ... + "XSaherSession" // Name ... + ); // // EA Signaller ... diff --git a/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 b/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 index 39079e52..695c21b0 100644 --- a/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 +++ b/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 @@ -79,23 +79,26 @@ string ToString(ENUM_XCAEA_TRADE_FINALIZATION value) struct XCAEASymbolInfo { // - string symbol; + // Properties ... // - int longs; - int shorts; + string symbol; // Trading Symbol // - int trades; + int longs; // All Long Trades + int shorts; // All Short Trades // - int losses; - int profits; + int trades; // All Trades // - int managedSLs; - int managedTPs; - int managedTrades; + int losses; // All Loosing Trades + int profits; // All Winning Trades + + // + int managedSLs; // Managed SL(s) + int managedTPs; // Managed TP(s) + int managedTrades; // Managed Trades // // Constructor ... @@ -164,6 +167,179 @@ struct XCAEASymbolInfo } }; +// +struct XCAEATradeSession +{ + // + // Properties ... + string start; // Session Start Time (hh:mm) + string end; // Session End Time (hh:mm) + string name; // Session Name + + // + // Constructor ... + XCAEATradeSession() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + end = NULL; + name = NULL; + start = NULL; + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid(start) && + IsValid(end); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Check Session is Active or Not ... + bool IsActive(datetime time = NULL) + { + // + bool result = false; + + // + time = NormalizeTime(time); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = IsTimeInRange( + time, + start, + end // + ); + + // + return result; + } +}; + +struct XCAEASymbolSession +{ + // + // Propeties ... + + // + string symbol; // Trading Symbol + XCAEATradeSession sessions[]; // Trading Sessions + + // + // Constructor ... + XCAEASymbolSession() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + Clean(sessions); + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid(symbol); + + // + return result; + } + + // + // Check Allow Trade in Active Sessions ... + bool CanTrade(datetime time = NULL) + { + // + bool result = false; + + // + // Normalize Args ... + time = NormalizeTime(time); + + // + // Validating ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // if there is not any defined sessions for Symbol ... + // it's allow Trading in all times ... + result = !HasChild(sessions); + if (result) + { + return result; + } + + // + // Detect an Active Session ... + int count = ArraySize(sessions); + for (int i = 0; i < count; i++) + { + // + result = sessions[i].IsActive(time); + if (result) + { + break; + } + } + + // + return result; + } + + // +}; + // struct XCAEATrade { @@ -496,21 +672,79 @@ class XCXCAEATradeManager : public XCBaseAlert } // - // TODO: Implement this ... void SetTradeSession( + string symbol, string start, - string end // + string end, + string name = NULL // ) { // - bool has = IsValid(start) || - IsValid(end); + // Validate Args ... + bool has = IsValid(end) && + IsValid(start) && + IsValid(symbol); if (!has) { return; } // + // Create Session ... + + // + XCAEATradeSession session; + + // + session.end = end; + session.name = name; + session.start = start; + + // + int sessionIDX = -1; + has = FindSymbolSession( + sessionIDX, + symbol // + ); + + // + if (!has) + { + // + // Add New Symbol Session ... + + // + XCAEASymbolSession iSymbolSession; + iSymbolSession.symbol = symbol; + + // + AddTradingSession( + session, + iSymbolSession // + ); + + // + AddRef( + iSymbolSession, + sessions // + ); + + // + iSymbolSession.Clean(); + } + else + { + // + // Update Trading Sessions of Exists Symbol Session ... + AddTradingSession( + session, + sessions[sessionIDX] // + ); + } + + // + // Cleanup Resources ... + session.Clean(); } // @@ -974,36 +1208,54 @@ class XCXCAEATradeManager : public XCBaseAlert // // Check Symbol Info Exists or not ... - int symbolIDX = -1; - bool isSymbolExists = FindSymbolIndex( - symbolIDX, + int symbolInfoIDX = -1; + bool isSymbolInfoExists = FindSymbolIndex( + symbolInfoIDX, signal.symbol // ); // - // TODO: Complete this ... - // Implementing Trade Session Validating ... + // Check Symbol Session Exists or not ... + int symbolSessionIDX = -1; + bool isSymbolSessionExists = FindSymbolSession( + symbolSessionIDX, + signal.symbol // + ); // - // Implementing Trade Permissions Based on SL(s) Count ... + // Chack Trade Session Validating ... + if (isSymbolSessionExists) { + // + result = sessions[symbolSessionIDX].CanTrade(); + if (!result) { + // + executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED; + + // + return result; + } + } + + // + // Check Trade Permissions Based on SL(s) Count ... bool hasRestrictions = restrictionsPeriod != XCAEA_TRADE_RESTRICATION_NONE; if (hasRestrictions) { // // Only Can Check Restrictions when // Symbol Info Exists ... - if (isSymbolExists) + if (isSymbolInfoExists) { // bool isTPAllowed = maxAllowedTPs == 0 ? true - : symbols[symbolIDX].managedTPs < maxAllowedTPs; + : symbols[symbolInfoIDX].managedTPs < maxAllowedTPs; bool isSLAllowed = maxAllowedSLs == 0 ? true - : symbols[symbolIDX].managedSLs < maxAllowedSLs; + : symbols[symbolInfoIDX].managedSLs < maxAllowedSLs; bool isTradeAllowed = maxAllowedTrades == 0 ? true - : symbols[symbolIDX].managedTrades < maxAllowedTrades; + : symbols[symbolInfoIDX].managedTrades < maxAllowedTrades; // result = isTPAllowed && @@ -1823,6 +2075,94 @@ class XCXCAEATradeManager : public XCBaseAlert } } + // + // Symbol Session ... + + // + bool FindSymbolSession( + int &index, + string symbol // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = IsValid(symbol) && + HasChild(sessions); + if (!result) + { + return result; + } + + // + int count = ArraySize(sessions); + for (int i = 0; i < count; i++) + { + // + result = sessions[i].symbol == symbol; + if (result) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + // + void AddTradingSession( + XCAEATradeSession &session, + XCAEASymbolSession &symbolSession // + ) + { + // + bool has = session.IsValid() && + symbolSession.IsValid(); + if (!has) + { + return; + } + + // + // Check Session Exists in Symbol Session ... + bool isExists = false; + if (HasChild(symbolSession.sessions)) + { + // + int count = ArraySize(symbolSession.sessions); + for (int i = 0; i < count; i++) + { + // + isExists = symbolSession.sessions[i].end == session.end && + symbolSession.sessions[i].start == session.start; + if (isExists) + { + break; + } + } + } + + // + if (!isExists) + { + // + AddRef( + session, + symbolSession.sessions // + ); + } + } + // // Private ... private: @@ -1855,6 +2195,7 @@ class XCXCAEATradeManager : public XCBaseAlert // XCAEATrade trades[]; XCAEASymbolInfo symbols[]; + XCAEASymbolSession sessions[]; }; //