From bfeff05fd54ffe1f99ac441a4ec5cdd81f0ebee5 Mon Sep 17 00:00:00 2001 From: Bell Date: Sat, 13 Dec 2025 18:13:26 +0700 Subject: [PATCH] Cancel exprired limit orders --- Experts/EA_ICT.txt | 29 +++++++++++++--- Experts/EA_ICT_v2.mq5 | 81 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 99 insertions(+), 11 deletions(-) diff --git a/Experts/EA_ICT.txt b/Experts/EA_ICT.txt index de3fb76..42ee8e1 100644 --- a/Experts/EA_ICT.txt +++ b/Experts/EA_ICT.txt @@ -40,7 +40,28 @@ ltfSwingRange = 5; - R:R = 1:3 -> Profit 13.8% | Drawdown 16% - R:R = 1:4 -> Profit 41.1% | Drawdown 5% -- R:R = 1:5 -> Profit 56.7% | Drawdow 17% -- R:R = 1:6 -> Profit 59.4% | Drawdow 20% -- R:R = 1:7 -> Profit 64.6% | Drawdow 23% -- R:R = 1:8 -> Profit 14.7% | Drawdow 32% \ No newline at end of file +- R:R = 1:5 -> Profit 56.7% | Drawdown 20% +- R:R = 1:6 -> Profit 59.4% | Drawdown 20% +- R:R = 1:7 -> Profit 64.6% | Drawdown 23% +- R:R = 1:8 -> Profit 14.7% | Drawdown 32% + +====== + +Result test 12/12/25 (Data 2025): + +1. Cấu hình 2: + +--- + +htfSwingRange = 1; +mtfSwingRange = 3; +ltfSwingRange = 5; + +--- + +- R:R = 1:3 -> Profit 11% | Drawdown 16% +- R:R = 1:4 -> Profit 37% | Drawdown 5% +- R:R = 1:5 -> Profit 53% | Drawdown 22% +- R:R = 1:6 -> Profit 55% | Drawdown 22% +- R:R = 1:7 -> Profit % | Drawdown % +- R:R = 1:8 -> Profit % | Drawdown % \ No newline at end of file diff --git a/Experts/EA_ICT_v2.mq5 b/Experts/EA_ICT_v2.mq5 index 9a5e1a7..d978559 100644 --- a/Experts/EA_ICT_v2.mq5 +++ b/Experts/EA_ICT_v2.mq5 @@ -12,7 +12,15 @@ bool PrintEntryLog = true; // nếu true -> in log chỉ liên quan tới entr input double RishPercent = 1.0; // % vốn rủi ro cho mỗi lệnh // --- Cấu hình Risk:Reward --- -input double RiskRewardRatio = 3.0; // tỉ lệ R:R mặc định (TP = entry ± RiskRewardRatio * |entry - SL|) +input double RiskRewardRatio = 6.0; // tỉ lệ R:R mặc định (TP = entry ± RiskRewardRatio * |entry - SL|) + +// Cấu hình Swing +input int htfSwingRange = 2; // X: số nến trước và sau để xác định 1 đỉnh/đáy +input int mtfSwingRange = 3; // X: số nến trước và sau để xác định 1 đỉnh/đáy +input int ltfSwingRange = 5; // X: số nến trước và sau để xác định 1 đỉnh/đáy +input int MaxSwingKeep = 2; // Số đỉnh/đáy gần nhất cần lưu (bạn yêu cầu 2) + +input int MaxLimitOrderTime = 60; // Struct pending entry (single slot) struct PendingEntry @@ -48,12 +56,6 @@ input bool DetectMSS_HTF = false; input bool DetectMSS_MTF = false; input bool DetectMSS_LTF = true; -// Cấu hình Swing -input int htfSwingRange = 2; // X: số nến trước và sau để xác định 1 đỉnh/đáy -input int mtfSwingRange = 3; // X: số nến trước và sau để xác định 1 đỉnh/đáy -input int ltfSwingRange = 5; // X: số nến trước và sau để xác định 1 đỉnh/đáy -input int MaxSwingKeep = 2; // Số đỉnh/đáy gần nhất cần lưu (bạn yêu cầu 2) - // Cấu hình vẽ Swing trên chart input bool ShowSwingMarkers = true; // Hiển thị các marker swing trên chart input string SwingObjPrefix = "Swing_"; // Tiền tố tên object (dễ xóa/điều chỉnh) @@ -2284,10 +2286,75 @@ void SetUpPendingEntryForMSS(const MSSInfo &mss, int slot) if(PrintEntryLog) Print("==> SetUpPendingEntryForMSS (NEW) END"); } +void CancelExpiredLimitOrder() +{ + if(!pendingEntry.active) return; + if(pendingEntry.orderTicket == 0) return; + if(pendingEntry.created_time == 0) return; + + ulong ticket = pendingEntry.orderTicket; + + // Nếu order không còn tồn tại → đã khớp hoặc bị xóa + if(!OrderSelect(ticket)) + { + if(PrintEntryLog) + Print("Pending LIMIT no longer exists → cleared"); + + ClearPendingEntry(); + return; + } + + ENUM_ORDER_TYPE type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); + + // Chỉ xử lý LIMIT + if(type != ORDER_TYPE_BUY_LIMIT && type != ORDER_TYPE_SELL_LIMIT) + return; + + datetime now = TimeCurrent(); + int aliveSec = (int)(now - pendingEntry.created_time); + int maxSec = MaxLimitOrderTime * 60; + + if(aliveSec < maxSec) + return; // chưa quá hạn + + // ---- HỦY LỆNH LIMIT ---- + MqlTradeRequest req; + MqlTradeResult res; + ZeroMemory(req); + ZeroMemory(res); + + req.action = TRADE_ACTION_REMOVE; + req.order = ticket; + + if(!OrderSend(req, res)) + { + if(PrintEntryLog) + PrintFormat("Cancel LIMIT failed (OrderSend=false), ticket=%I64u", ticket); + return; + } + + if(res.retcode == TRADE_RETCODE_DONE) + { + if(PrintEntryLog) + PrintFormat("LIMIT cancelled after %d minutes, ticket=%I64u", + MaxLimitOrderTime, ticket); + + ClearPendingEntry(); + } + else + { + if(PrintEntryLog) + PrintFormat("Cancel LIMIT failed retcode=%d ticket=%I64u", + res.retcode, ticket); + } +} + void OnTick() { string sym = Symbol(); + CancelExpiredLimitOrder(); + if(IsNewClosedBar(sym, HighTF, 0)) { HandleLogicForTimeframe(sym, HighTF, 0, DetectMSS_HTF, htfSwingRange, false, 10.0, 2, 50, FVGLookback); }