Dashboard-Zeile fuer Slot 2 + Doku des Zwei-Slot-Umbaus

Die vom Breakout-Trader gehaltene Position ist jetzt sichtbar (#brk-pos in der
Breakout-Karte): Richtung, Lots, Einstieg, P&L - und vor allem der
Trailing-Zustand.

⚠ Der Trailing-Hinweis ist der wichtigste Teil der Zeile: steht er auf
"⚠ TRAILING AUS - nur Broker-SL!", laeuft der Trade in der gemessen
DURCHGEFALLENEN SL-only-Variante (backtest_brk_slonly.py: alle zehn
Konfidenzintervalle enthalten die Null, Trefferquote faellt 40 -> 21 %). Ohne
diese Anzeige waere das im Betrieb nicht bemerkbar - genau Deployment-Drift
Fall 8 (nicht die Strategie driftet, sondern ihre Beobachtbarkeit).

Richtung wird aus SL/TP abgeleitet statt ein weiteres Snapshot-Feld zu bauen -
place_stop setzt immer einen SL. Damit bleibt es eine reine Frontend-Aenderung
(v=185), kein Neustart noetig, die offene Position unberuehrt.

Verifiziert: v=185 wird ausgeliefert, div 85/85 ausgeglichen, keine doppelten
IDs, keine verwaisten JS-Referenzen, node --check gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-19 20:12:26 +02:00
co-authored by Claude Opus 5
parent a9a6c487d2
commit 5593f270cc
3 changed files with 85 additions and 3 deletions
+58 -1
View File
@@ -4328,7 +4328,7 @@ Trader wäre sie nie abgelaufen. Latte unverändert: Verhältnis < 1,0 ODER PF <
(„⚠ die Welle (steuert die Order) schweigt").
Live gegengerechnet, beide Zeilen erscheinen wie beabsichtigt.
⚠ Reine Anzeige — an Gewichten, Gates und Order-Logik ist nichts geändert.
- Asset-Version aktuell **v=183** (in `web/index.html` hochzählen, siehe Workflows).
- Asset-Version aktuell **v=185** (in `web/index.html` hochzählen, siehe Workflows).
- **✅ SCHRIFT SKALIERT MIT DEM FENSTER (2026-08-13, v=167).** User: „die Größe der
Schriftarten im Dashboard auf em einstellen, damit auf jedem Gerät oder je nach
Fenstergröße die Schriftgröße automatisch angepasst wird."
@@ -8756,3 +8756,60 @@ Exit-Modell gewesen.
**Offen: der ticket-basierte Umbau** (Trailing je Position) — eigene Sitzung
mit **flachem Konto**. Ein halb fertiger Umbau lässt den Schutz-Stack an der
falschen der beiden Positionen hängen.
## ✅✅ BRK HAT EINEN EIGENEN POSITIONS-SLOT (2026-08-19, v=185)
User-Vorgabe: *„der brk trade soll komplett unabhängig von m15 oder manuellen
trades laufen“*. Entwurf: `docs/brk-eigener-slot.md`.
**Anlass war eine Messung, keine Vermutung:** BRK setzte am 19.08. **fünfmal**
ruhende Orders und wurde jedes Mal binnen Sekunden storniert, weil eine Position
offen war (16 s · 1 s · 20 s · 81 s · 9 s = zusammen **~2 Minuten am Markt** an
einem Tag mit 24 Trades). **Drei der fünf** löste der M15-Trader aus — einmal in
**derselben Sekunde**. Der SELL_STOP von 19:02 lag bei 86,080, das Tief danach
bei **86,012**: die Order hätte gefüllt.
```
engine.trader ─ TradeManager() ─ trail ─ manuell + M15
engine.trader_brk ─ TradeManager(nur_ticket=True) ─ trail_brk ─ nur BRK
```
**Der Umbau blieb klein**, weil `TrailingManager.__init__` bereits SEINEN
Trader nimmt und nur über dessen `snapshot()` liest — es hängt nicht an einer
globalen Position. Der validierte Pfad bleibt damit **unangetastet** (kein
Regressionsrisiko auf der gemessen besseren Population, +1,56 gegen 4,71 €/Lot).
⚠⚠ **DIE ZWEI KRITISCHEN STELLEN:**
**(1) Adoption.** `TradeManager.refresh()` greift per Default jede Position auf
dem Symbol (gewollt: ein von Hand eröffneter Trade bekommt so den Schutz-Stack).
Mit zwei Managern würden sich **beide dieselbe** Position schnappen. Neu:
`nur_ticket=True` sucht sich nichts, und der adoptierende Manager bekommt über
**`fremde_tickets`** eine Sperrliste (BRK-Ticket + liegende Pendings).
**(2) Der Fill.** Eine ruhende Order füllt **im Broker**; der ticket-gebundene
Slot kann sie nicht finden. Neu **`TradeManager.bind(ticket, sym)`**, gerufen aus
`_check_pending_fill` — es sieht direkt am Broker nach, welches der liegenden
Tickets zu einer Position geworden ist.
**Weiter:** `_check_auto_squeeze`/`_manage_squeeze_pending` lesen den EIGENEN
Slot · `trail_brk` wird in `_price_loop` mit Preisen versorgt · Snapshot
**`position_brk`** · Dashboard-Zeile **`#brk-pos`** in der Breakout-Karte ·
**Circuit-Breaker und Tages-P&L summieren BEIDE Slots**, und der Breaker
schließt beide (eine Notbremse, die nur die Hälfte schließt, ist keine).
⚠ Die Dashboard-Zeile warnt ausdrücklich **„⚠ TRAILING AUS — nur Broker-SL!“**:
ohne `trail_brk` liefe BRK in der gemessen **durchgefallenen** SL-only-Variante
(`backtest_brk_slonly.py`: alle zehn KI enthalten die Null; WR fällt 40 → 21 %).
⚠⚠ **REIHENFOLGE-FEHLER, real passiert:** die Defaults für `_margin_brk`/
`_margin_m15` standen in Zeile 631, `_load_runtime_state()` läuft in Zeile 553 —
der geladene Wert wurde also sofort mit 0 überschrieben. Die Eingabe WIRKTE, war
aber nach jedem Neustart weg (User: „die Eingabe bleibt wirkungslos, in den
Feldern erscheint global“). **Regel: erst Default setzen, dann `runtime_state`
darüber laden.**
⚠ Beim Verifizieren dazu ein **eigener Fehlalarm**: mein Test setzte 55/30, nach
dem Neustart standen 85/10 — ich las das als „verloren“ und sogar als
Vertauschung. Die Logspur zeigte, dass der Browser des Users währenddessen zwei
weitere POSTs geschickt hatte. **Bei einer Live-Verifikation gegen ein System,
das der Nutzer gleichzeitig bedient, gehört die Logspur mitgelesen.**
**NOCH NICHT BEOBACHTET:** der erste echte Parallelbetrieb. Beweis beim
nächsten Squeeze mit offener Position — Log `🧷 BRK-Slot uebernimmt
Pending-Fill` und `position_brk.trail == true`.