From d33d695db523e4da9fe8f9dfd44fcaf023984211 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Sep 2026 13:51:24 +0200 Subject: [PATCH] WebUI: Trading beenden, ohne die Anwendung zu beenden Umsetzung von #563. Entscheidung Richard, 13.09.2026: Beenden soll ueber das WebUI gehen, aber beschraenkt auf das Trading. Ein Ende der ganzen Anwendung naehme den Webserver mit; danach waere das WebUI nicht mehr erreichbar. POST /api/dashboard/stop-trading setzt Live- und Demo-Modus auf Inaktiv und schaltet die Pause ein. Damit halten CopyTrading und ResolutionFarming (#569) an, wie beim Ende der Anwendung. Offene Orders an der Boerse werden bewusst nicht storniert: Das tut auch das Beenden der App nicht, und ein Eingriff in die CLOB-Integration gehoert nicht in einen Notschalter. Der Dialog sagt das ausdruecklich. Die Route verlangt {"confirmed": true}. Ein Aufruf ohne Absicht, etwa aus einem alten Skript, beendet nichts. Der Vorgang wird als Warnung protokolliert, mit den Modi vorher. Im Dashboard steht unter der Notfall-Pause jetzt "Trading beenden ...". Der Dialog ist wie im Desktop 10 Sekunden gesperrt, Abbrechen und Esc gehen jederzeit. Wieder aufgenommen wird nur ueber die Modus-Schalter. Die Pause aufzuheben genuegt nicht, das haelt ein Test fest. Offen bis #570: Laufende Verkaufsleitern und der REST-Pre-Redeem pruefen die Pause nicht. Der Inaktiv-Modus, den dieser Knopf setzt, sperrt den Pre-Redeem bereits; die Leitern friert erst #570 ein. Co-Authored-By: Claude Opus 5 --- .../Endpoints/DashboardEndpoints.cs | 41 +++++++++ src/PolyTrader.Web/wwwroot/index.html | 37 ++++++++ src/PolyTrader.Web/wwwroot/js/app.js | 61 +++++++++++++ .../WebUi/StopTradingEndpointTests.cs | 89 +++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 tests/PolyTrader.Tests/WebUi/StopTradingEndpointTests.cs diff --git a/src/PolyTrader.Web/Endpoints/DashboardEndpoints.cs b/src/PolyTrader.Web/Endpoints/DashboardEndpoints.cs index 9296338..cd0fc4d 100644 --- a/src/PolyTrader.Web/Endpoints/DashboardEndpoints.cs +++ b/src/PolyTrader.Web/Endpoints/DashboardEndpoints.cs @@ -78,6 +78,45 @@ namespace PolyTrader.Web.Endpoints return Results.BadRequest(new { error = "Ungültiger Modus oder Parametertyp." }); }); + // Trading beenden (#563) - das WebUI-Gegenstueck zu "Beenden" im Desktop, beschraenkt auf das + // Trading. Ein Ende der ganzen Anwendung naehme den Webserver mit; danach waere das WebUI nicht + // mehr erreichbar, und nur ein Zugang zur Maschine braechte es zurueck. + // + // Beide Modi auf Inaktiv und die Pause an: Damit halten CopyTrading (Engine, Monitor, + // Verkaufsleitern) und ResolutionFarming (#569) an, wie beim Ende der Anwendung. Offene Orders + // an der Boerse werden bewusst NICHT storniert. Das tut auch das Beenden der App nicht, und + // ein Eingriff in die CLOB-Integration gehoert nicht in einen Notschalter. Wieder + // aufgenommen wird nur ausdruecklich ueber die Modus-Schalter. + // + // "confirmed" ist Pflicht: Ein Aufruf ohne Absicht, etwa aus einem alten Skript oder einem + // doppelt abgeschickten Formular, soll das Trading nicht beenden. + group.MapPost("/stop-trading", (StopTradingRequest? req, TradingState state, TerminalLogger logger) => + { + if (req?.Confirmed != true) + return Results.BadRequest(new { error = "Bestätigung fehlt – das Trading wurde nicht beendet." }); + + string liveBefore = state.LiveTradingMode.ToString(); + string demoBefore = state.DemoTradingMode.ToString(); + bool pausedBefore = state.GlobalTradingPaused; + + state.LiveTradingMode = TradingMode.Inactive; + state.DemoTradingMode = TradingMode.Inactive; + state.GlobalTradingPaused = true; + + logger.Warning($"🛑 WebUI: Trading beendet (Live {liveBefore} → Inactive, Demo {demoBefore} → Inactive, " + + $"Pause {(pausedBefore ? "war schon an" : "an")}). Anwendung und WebUI laufen weiter; " + + "offene Orders an der Börse bleiben stehen."); + + return Results.Ok(new + { + success = true, + liveTradingMode = state.LiveTradingMode.ToString(), + demoTradingMode = state.DemoTradingMode.ToString(), + globalTradingPaused = state.GlobalTradingPaused, + stoppedAt = DateTime.UtcNow + }); + }); + group.MapGet("/overview-widgets", (IServiceProvider sp) => { var tradeLog = sp.GetService(); @@ -251,5 +290,7 @@ namespace PolyTrader.Web.Endpoints return routes; } + + public record StopTradingRequest(bool Confirmed); } } diff --git a/src/PolyTrader.Web/wwwroot/index.html b/src/PolyTrader.Web/wwwroot/index.html index e31700f..b0c8db6 100644 --- a/src/PolyTrader.Web/wwwroot/index.html +++ b/src/PolyTrader.Web/wwwroot/index.html @@ -104,6 +104,11 @@ + + @@ -1176,6 +1181,38 @@ Wähle ein Profil und stelle mir eine Frage zu deinen Positionen, Risiken oder d + + + +