diff --git a/IntelliTrader.Web/Views/Home/Dashboard.cshtml b/IntelliTrader.Web/Views/Home/Dashboard.cshtml index ce9e3fe..27bc10d 100644 --- a/IntelliTrader.Web/Views/Home/Dashboard.cshtml +++ b/IntelliTrader.Web/Views/Home/Dashboard.cshtml @@ -27,25 +27,27 @@ - +
-
+
Громкость: 50%
-
+
- Профиль звука: + Профиль:
-
- Настройки звука +
+ + Мин. сумма ($): +
@@ -59,6 +61,7 @@ const soundVolumeSlider = document.getElementById("soundVolumeSlider"); const soundVolumeValue = document.getElementById("soundVolumeValue"); const soundProfileSelect = document.getElementById("soundProfileSelect"); + const minTradeSizeInput = document.getElementById("minTradeSizeInput"); const notificationContainer = document.getElementById("notificationContainer"); let isSoundEnabled = localStorage.getItem("realtime_sound_enabled") !== "false"; @@ -74,10 +77,22 @@ // Load sound profile with fallback to 'chime' let soundProfile = localStorage.getItem("realtime_sound_profile") || "chime"; + // Load min trade size threshold with fallback to 0 + let realtimeMinTradeSize = parseFloat(localStorage.getItem("realtime_min_trade_size") || "0"); + if (isNaN(realtimeMinTradeSize) || realtimeMinTradeSize < 0) realtimeMinTradeSize = 0; + // Sync UI controls with values soundVolumeSlider.value = soundVolume; soundVolumeValue.textContent = Math.round(soundVolume * 100) + "%"; soundProfileSelect.value = soundProfile; + if (minTradeSizeInput) { + minTradeSizeInput.value = realtimeMinTradeSize > 0 ? realtimeMinTradeSize : ""; + minTradeSizeInput.addEventListener("input", function () { + const val = parseFloat(minTradeSizeInput.value) || 0; + realtimeMinTradeSize = val < 0 ? 0 : val; + localStorage.setItem("realtime_min_trade_size", realtimeMinTradeSize); + }); + } updateSoundButtonUI(); @@ -332,8 +347,11 @@ knownTrades.add(tradeId); if (!isFirstLoad) { - hasNewTrade = true; - showToastNotification(trade); + const tradeCost = trade.Cost ? parseFloat(trade.Cost) : (parseFloat(trade.Amount || 0) * parseFloat(trade.SellPrice || trade.AveragePrice || 0)); + if (tradeCost >= realtimeMinTradeSize) { + hasNewTrade = true; + showToastNotification(trade); + } } } }); diff --git a/IntelliTrader.Web/Views/Home/Settings.cshtml b/IntelliTrader.Web/Views/Home/Settings.cshtml index 88c654d..e4f6860 100644 --- a/IntelliTrader.Web/Views/Home/Settings.cshtml +++ b/IntelliTrader.Web/Views/Home/Settings.cshtml @@ -49,6 +49,35 @@
+
+

Уведомления и Звук

+
+ + +
+
+ + + 50% +
+
+ + +
+
+ + + Уведомления и звук сработают только для сделок, стоимость которых равна или превышает указанный порог. +
+
+ diff --git a/magda_agent_system/agent_tasks.json b/magda_agent_system/agent_tasks.json index 7d53bc6..e8f861b 100644 --- a/magda_agent_system/agent_tasks.json +++ b/magda_agent_system/agent_tasks.json @@ -446,7 +446,7 @@ }, { "id": "web-dashboard-custom-alerts", - "status": "todo", + "status": "done", "area": "web", "risk": "low", "title": "Add custom notification threshold settings on Dashboard", @@ -473,6 +473,53 @@ "acceptance": [ "Order caching mechanism is integrated and avoids frequent disk reads for historical trade logs." ] + }, + { + "id": "trading-trailing-stop-loss-guard", + "status": "todo", + "area": "trading", + "risk": "medium", + "title": "Implement trailing stop loss boundary protection in SellProcessor", + "description": "Add configurable stop loss limits in SellProcessor to limit losses during sudden flash crashes when trailing sell is active.", + "allowed_paths": [ + "IntelliTrader.Trading/Processors/SellProcessor.cs", + "magda_agent_system/agent_tasks.json" + ], + "acceptance": [ + "SellProcessor enforces stop-loss boundaries during crash scenarios", + "Unit tests verify stop loss execution" + ] + }, + { + "id": "web-dashboard-csv-export", + "status": "todo", + "area": "web", + "risk": "low", + "title": "Add CSV export button for active trading pairs table on Dashboard", + "description": "Add a button on the Web Dashboard to export current active trading pairs and positions into a CSV file.", + "allowed_paths": [ + "IntelliTrader.Web/Views/**", + "IntelliTrader.Web/Static/**", + "magda_agent_system/agent_tasks.json" + ], + "acceptance": [ + "Users can click a button to download the active positions table as a CSV file" + ] + }, + { + "id": "exchange-websocket-reconnect-backoff", + "status": "todo", + "area": "exchange", + "risk": "medium", + "title": "Implement exponential backoff reconnect policy in BinanceExchangeService", + "description": "Improve exchange connection resilience by adding exponential backoff and jitter to WebSocket re-connection logic.", + "allowed_paths": [ + "IntelliTrader.Exchange.Binance/**", + "magda_agent_system/agent_tasks.json" + ], + "acceptance": [ + "BinanceExchangeService handles WebSocket disconnects gracefully with exponential backoff" + ] } ] }