From 47fb4a474daf8e9166e4ea907d0605567b29bc97 Mon Sep 17 00:00:00 2001 From: Bell Date: Wed, 11 Mar 2026 18:25:18 +0700 Subject: [PATCH] Draw trade state --- Experts/SimpleFVG/Drawing.mqh | 22 ++++++++++++ Experts/SimpleFVG/Trade.mqh | 66 +++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/Experts/SimpleFVG/Drawing.mqh b/Experts/SimpleFVG/Drawing.mqh index a053eee..1e1623f 100644 --- a/Experts/SimpleFVG/Drawing.mqh +++ b/Experts/SimpleFVG/Drawing.mqh @@ -76,6 +76,27 @@ void DrawTextOnChart(string name, datetime t, double price, ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); } +void DrawTradeStatsPanel() +{ + int totalTrades, tpTrades, slTrades; + GetTradeStats(totalTrades, tpTrades, slTrades); + + string name = EA_PREFIX + "PNL_STATS"; + if(ObjectFind(0, name) < 0) + ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0); + + ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER); + ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 12); + ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 22); + ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9); + ObjectSetInteger(0, name, OBJPROP_COLOR, clrSilver); + ObjectSetString (0, name, OBJPROP_FONT, "Consolas"); + ObjectSetString (0, name, OBJPROP_TEXT, + StringFormat("Trades: %d | TP: %d | SL: %d", + totalTrades, tpTrades, slTrades)); + ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); +} + //+------------------------------------------------------------------+ //| Draw limit orders (TradingView-style lines) | //+------------------------------------------------------------------+ @@ -273,6 +294,7 @@ void DrawAll() DrawFVGZones(); DrawInfoPanel(); DrawLimitOrders(); + DrawTradeStatsPanel(); ChartRedraw(0); } diff --git a/Experts/SimpleFVG/Trade.mqh b/Experts/SimpleFVG/Trade.mqh index 930aa80..c8d16ed 100644 --- a/Experts/SimpleFVG/Trade.mqh +++ b/Experts/SimpleFVG/Trade.mqh @@ -157,6 +157,47 @@ void CancelStaleLimitOrders() } } +void GetTradeStats(int &totalTrades, int &tpTrades, int &slTrades) +{ + totalTrades = 0; + tpTrades = 0; + slTrades = 0; + + datetime now = TimeCurrent(); + if(now == 0) + return; + + if(!HistorySelect(0, now)) + return; + + int deals = HistoryDealsTotal(); + string symbol = GetTradeSymbol(); + + for(int i = 0; i < deals; i++) + { + ulong dealTicket = HistoryDealGetTicket(i); + if(dealTicket == 0) + continue; + + string dealSymbol = (string)HistoryDealGetString(dealTicket, DEAL_SYMBOL); + long dealMagic = (long)HistoryDealGetInteger(dealTicket, DEAL_MAGIC); + if(dealSymbol != symbol || dealMagic != InpEAMagic) + continue; + + ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(dealTicket, DEAL_ENTRY); + if(entry != DEAL_ENTRY_OUT && entry != DEAL_ENTRY_INOUT) + continue; + + totalTrades++; + + ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger(dealTicket, DEAL_REASON); + if(reason == DEAL_REASON_TP) + tpTrades++; + else if(reason == DEAL_REASON_SL) + slTrades++; + } +} + // Tính khối lượng lot sao cho 1R = InpRiskPercentPerR % balance double CalculateRiskLotSize(double entryPrice, double slPrice) { @@ -292,13 +333,16 @@ void ManageFVGTrades() if(currentLimits >= InpMaxLimitOrders) return; - // Chỉ đặt lệnh limit khi giá đã chạm FVG (TOUCHED), không đặt khi mới ACTIVE + // Đặt lệnh limit khi giá vừa chạm cạnh ngoài FVG (trước khi fill đủ 40%) ENUM_TREND_DIRECTION trend = g_CurrentTrend; + string symbol = GetTradeSymbol(); + double lastHigh = iHigh(symbol, InpTimeframe, 1); + double lastLow = iLow (symbol, InpTimeframe, 1); for(int i = g_FVGCount - 1; i >= 0 && currentLimits < InpMaxLimitOrders; i--) { FVGZone zone = g_FVGZones[i]; - if(!IsZoneTouched(zone)) + if(!IsZoneActive(zone) || IsZoneMitigated(zone)) continue; if(zone.type == FVG_BULLISH && trend != TREND_BULLISH) @@ -306,6 +350,24 @@ void ManageFVGTrades() if(zone.type == FVG_BEARISH && trend != TREND_BEARISH) continue; + bool touchedEdge = false; + + if(zone.type == FVG_BULLISH) + { + // giá chạm cạnh trên (upperEdge) của bullish FVG + if(lastLow <= zone.upperEdge && lastHigh >= zone.upperEdge) + touchedEdge = true; + } + else // FVG_BEARISH + { + // giá chạm cạnh dưới (lowerEdge) của bearish FVG + if(lastHigh >= zone.lowerEdge && lastLow <= zone.lowerEdge) + touchedEdge = true; + } + + if(!touchedEdge) + continue; + if(PlaceLimitForZone(zone)) currentLimits++; }