Das Dashboard blieb bei "lädt ..." stehen und zeigte weder Kacheln noch die
Steuerungs-Abschnitte.
Ursache: _DASHBOARD ist ein Python-String. Der in d081edf ergänzte
prompt()-Dialog für die Live-Bestätigung enthält \n, das Python zu echten
Zeilenumbrüchen aufgelöst hat. Das dadurch offene JavaScript-String-Literal ist
ein Syntaxfehler, der den gesamten <script>-Block mitreißt - im Browser waren
refresh und $ schlicht undefined, es lief kein einziger Ausdruck. Behoben durch
ein r-Präfix am Template, mit Kommentar an Ort und Stelle.
Warum das durchgerutscht ist: Die bisherige Prüfung hat nur kontrolliert, ob die
Bedienelemente im HTML stehen und ob die HTTP-Endpunkte antworten. Beides war
grün, während die Seite tot war. Markup-Präsenz ersetzt nicht das Ausführen der
Seite.
Neu: tests/test_dashboard.py
- Mini-Lexer über das ausgelieferte Skript, der String-Literale findet, die vor
dem Zeilenende nicht geschlossen werden (Backtick-Template-Literale dürfen
mehrzeilig sein). Gegenprobe im Test enthalten; gegen den echten Defekt
geprüft, er wird erkannt.
- Ausgeglichene Klammern, jede im Skript referenzierte Element-ID existiert im
HTML, und \n kommt als zwei Zeichen beim Browser an.
186 Tests (12 neue), ruff sauber. Im Browser durchgeklickt: Skript lädt, 10
Kacheln, Handel pausieren/starten und der Lernschalter ändern den Serverzustand
und die Anzeige, historisches Training läuft durch bis "Fertig in 0.8s: +146
Beobachtungen, gespeichert", null Loop-Fehler.
Neuer Abschnitt "Automatisierter Handel" im Dashboard mit Zustandsanzeige und
Start/Pause-Knopf, dazu GET und POST /control/trading. Funktioniert in beiden
Modi, simuliert wie echt.
Pausiert unterbindet ausschließlich neue Einstiege
- Marktdaten, Signalauswertung, Labeling und Training laufen weiter, damit der
Datenstrom ins Modell nie abreißt. Auf identischen Daten: aktiv 99
Beobachtungen bei 9 Trades, pausiert 90 Beobachtungen bei 0 Trades - der
Unterschied sind genau die Trade-Labels, die ohne Handel nicht entstehen.
- Offene Positionen bleiben unter Stop- und Ziel-Überwachung. Ein pausierter Bot
lässt niemanden ungeschützt im Markt stehen.
- Neu: trading.autostart (Standard true, bisheriges Verhalten) und
trading.require_confirmation_for_live.
Nebenbei behoben
- Bei aktiver Notbremse (Tagesverlust, Drawdown) wurden bisher gar keine Signale
mehr ausgewertet. Der Bot hörte damit ausgerechnet in der interessantesten
Phase auf zu lernen. Jetzt läuft die Auswertung durch, nur der Kauf unterbleibt.
- describe_config meldete "Steuerung möglich", während sie eine Zeile später
abgeschaltet wurde. Übersicht und Schutzlogik teilen sich jetzt dieselbe
Prüffunktion (control_effective / control_is_unsafe).
Absicherung für Echtgeld
- Starten im Live-Modus verlangt die Bestätigung START_LIVE_TRADING im Body
(HTTP 428 ohne sie); das Dashboard fragt sie per Dialog ab. Pausieren geht
immer ohne Bestätigung - anhalten muss schnell gehen.
- Live-Modus mit offenem Port und ohne control_token wird nicht bedient: Die
Steuerung wird beim Start abgeschaltet, der Bot läuft normal weiter. Sonst
könnte jeder im Netz echten Handel starten.
Bewusst nicht enthalten: ein Umschalter zwischen Paper und Live zur Laufzeit.
Der bräuchte einen neuen Broker, andere Zugangsdaten und eine neue Kapitalbasis -
und würde bedeuten, dass ein Web-Klick aus einer Simulation echten Handel macht.
174 Tests (21 neue), ruff sauber. Im gebauten Container geprüft: 401 ohne Token,
200 mit, idempotentes Pausieren, 400 bei kaputtem Payload, und im Live-Start mit
ungültigen Dummy-Schlüsseln greift die Abschaltung der Steuerung.
Neuer Abschnitt "Training" im Dashboard mit zwei Bedienelementen und den
zugehörigen Endpunkten /control/train/history, /control/train/live und
/control/training.
Historisches Nachtraining
- Kerzenanzahl je Symbol wählbar (500 bis 50 000), Fortschritt und Ergebnis
werden im Dashboard angezeigt.
- Läuft mit derselben Logik wie ein Backtest, aber ohne zu handeln, und
speichert das Modell anschließend.
- Handelsdurchlauf und Nachtraining teilen sich einen Mutex, damit sie nicht
gleichzeitig auf Modell und Portfolio zugreifen. Die rechenintensive Schleife
läuft in einem Worker-Thread, damit der Status-Server antwortbereit bleibt.
- Ein zweiter Start wird abgelehnt, solange einer eingereiht ist oder läuft.
Kontinuierliches Lernen
- Schalter für das Online-Lernen im laufenden Betrieb. Ausgeschaltet handelt der
Bot weiter, verändert das Modell aber nicht mehr.
Label-Trennung
- Vorgemerkte Labels tragen jetzt ein Tag. Ein Nachtraining darf die offenen
Labels des Live-Betriebs weder auflösen noch verwerfen; ohne die Trennung
würden sie gegen historische Kurse ausgewertet und das Modell mit falschen
Ergebnissen gefüttert.
- score() liest die Gewichte unter dem Lock, damit ein parallel laufendes
Training keinen halb aktualisierten Vektor sichtbar macht.
Absicherung
- server.control_token (TRADEMIND_CONTROL_TOKEN) schützt alle Steuerbefehle über
den Header X-TradeMind-Token; lesende Endpunkte bleiben offen. Ohne Token warnt
der Bot beim Start, wenn der Port nicht nur lokal erreichbar ist.
- server.enable_control: false entfernt die Routen vollständig.
153 Tests (25 neue), ruff sauber. Im gebauten Container geprüft: 202/409 beim
Anstoßen, 401 ohne und mit falschem Token, +1099 Beobachtungen in 4,3 s bei
weiterlaufendem Handels-Loop ohne Fehler.
Port 8080 wird in podman-compose.yml und in der Quadlet-Einheit auf allen
Interfaces veröffentlicht statt nur auf dem Loopback.
Die Endpunkte sind ausschließlich lesend – über HTTP lässt sich weder handeln
noch etwas konfigurieren –, aber sie sind nicht authentifiziert: Kontostand,
offene Positionen und die Trade-Historie sieht jeder, der den Port erreicht.
Das README nennt deshalb jetzt Reverse Proxy und Firewall als Absicherung, den
einzeiligen Weg zurück zu rein lokalem Zugriff sowie server.enabled: false zum
vollständigen Abschalten.
Geprüft im laufenden Container über die Nicht-Loopback-Adresse des Hosts:
/health, / , /status und /metrics antworten.
Per Podman deploybarer Bot, der Käufe und Verkäufe simuliert ausführt und sich
aus den Ergebnissen weiter antrainiert.
Aufbau
- Einheitliche Bar-Verarbeitung für paper, backtest und live; ausgetauscht werden
nur Datenquelle und Broker.
- Börsenanbindung über ccxt: rund 100 Börsen allein über exchange.id erreichbar.
Zugangsdaten kommen über ENV-Platzhalter, der Live-Modus ist doppelt abgesichert.
- Paper-Broker mit Gebühren, Slippage, Börsenpräzision und Volumengrenzen.
- Online trainierte logistische Regression bewertet jedes Einstiegssignal. Sie lernt
aus realen Trade-Ergebnissen, aus Shadow-Labels aller Kandidaten – auch der
abgelehnten – und aus Hintergrund-Stichproben; beim Kaltstart wird sie aus der
Kurshistorie vorgelernt.
- Risikomanagement: Positions- und Exposure-Grenzen, ATR-Stops, Cooldown sowie
Tagesverlust- und Drawdown-Notbremsen.
- SQLite-Persistenz, HTTP-Status mit Prometheus-Metriken und Dashboard, Webhooks.
Deployment
- Containerfile (zweistufig, non-root UID 10001), podman-compose, systemd-Quadlet.
- Modell und Datenbank liegen im Volume /data und überleben Neustarts.
128 Tests, ruff sauber. Verifiziert gegen echte Marktdaten sowie im gebauten
Container inklusive Healthcheck und Zustandswiederherstellung.