User: "der brk trade soll komplett unabhaengig von m15 oder manuellen trades laufen". Der Entwurf ist am echten Code verifiziert, aber NICHT gebaut - Umsetzung gehoert in eine eigene Sitzung mit flachem Konto. DER ENTSCHEIDENDE BEFUND macht den Umbau viel kleiner als gedacht: TrailingManager.__init__ nimmt BEREITS einen Trader entgegen (trailing.py:146) und liest ausschliesslich ueber self.trader.snapshot(). Es haengt also nicht an einer globalen Position, sondern an SEINEM Trader. Damit ist die Loesung ein ZWEITER, ticket-gebundener TradeManager fuer BRK samt eigenem Trailing - statt 29 Stellen in engine.py umzubauen. Der validierte Pfad (manuell + M15) bleibt dabei vollstaendig unangetastet, also kein Regressionsrisiko auf der gemessen besseren Population. DER KRITISCHE PUNKT ist die Adoption: TradeManager.refresh() greift heute jede Position auf dem Symbol (positions_get(symbol=sym) mit Fallback auf alle). Mit zwei Managern wuerden sich beide dieselbe Position schnappen. Der BRK-Manager muss deshalb STRIKT ticket-gebunden sein - das ist die eine Aenderung, an der der ganze Entwurf haengt. Dokumentiert sind ausserdem die sieben Bauschritte in Reihenfolge, vier Vorbedingungen (flaches Konto, RETAIL_HEDGING bestaetigt, doppeltes Risiko und damit die Breaker-Frage, Margin-Semantik des Feldes "Einsatz je Pfad") und die Erfolgskontrolle. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5.5 KiB
BRK mit eigenem Positions-Slot — Entwurf
Auftrag (User, 2026-08-19): „der brk trade soll komplett unabhängig von m15 oder manuellen trades laufen".
Status: Entwurf, am echten Code verifiziert. Nicht gebaut. Umsetzung gehört in eine eigene Sitzung mit flachem Konto.
Warum der naheliegende Weg falsch ist
Die erste Idee wäre, die beiden Sperren zu entfernen:
| Stelle | heutiges Verhalten |
|---|---|
trader.open_long/short (Z. 320/333) |
lehnt ab, wenn self.ticket gesetzt ist |
engine._manage_squeeze_pending |
storniert die Pendings, sobald irgendeine Position offen ist |
Das wäre an einem Abend gemacht — und falsch. trader hält EIN Ticket
(self.ticket), und trailing, Notfall-Stop, S/R-Close und Time-Stop hängen
alle daran (29 Stellen in engine.py). Der zweite Trade hätte nur den
Broker-SL.
⚠⚠ Und das ist gemessen nicht tragfähig (backtest_brk_slonly.py,
2026-08-19, 80k M5, 2 Halbjahre): keine der fünf Exit-Varianten erfüllt die
vorab fixierte Regel, alle zehn Konfidenzintervalle enthalten die Null. SL-only
sieht im ØR zwar nicht schlechter aus, aber die Trefferquote fällt 40 → 21 %
und die KI-Breite vervierfacht sich — ein Varianz-Befund, kein Edge.
Der Entwurf: ein ZWEITER, ticket-gebundener Trader
Der entscheidende Befund aus der Code-Sichtung: TrailingManager.__init__
nimmt bereits einen Trader entgegen (core/trailing.py:146, self.trader = trader) und liest ausschließlich über self.trader.snapshot(). Es ist also
nicht an eine globale Position gebunden, sondern an seinen Trader.
Damit entfällt der 29-Stellen-Umbau:
engine.trader ─ TradeManager (wie heute) ─ trail ─ manuell + M15
engine.trader_brk ─ TradeManager (NEU) ─ trail_brk ─ nur BRK
✅ Der validierte Pfad bleibt unangetastet. Manuelle Trades und der
Schutz-Stack laufen unverändert über self.trader — kein Regressionsrisiko auf
der Population, die gemessen die bessere ist (+1,56 gegen −4,71 €/Lot).
⚠⚠ Der kritische Punkt: Adoption abschalten
TradeManager.refresh() (core/trader.py:511) macht heute:
on_sym = mt5.positions_get(symbol=sym) or []
all_pos = on_sym if on_sym else (mt5.positions_get() or [])
Es adoptiert also jede Position auf dem Symbol. Mit zwei Managern würden sich beide dieselbe Position greifen und gegeneinander arbeiten — Trailing zweimal auf demselben Ticket, oder beide auf dem falschen.
➜ Der BRK-Manager muss STRIKT ticket-gebunden sein: positions_get(ticket=…),
keine Adoption, kein Symbol-Fallback. Das ist die eine Änderung, an der der
ganze Entwurf hängt.
Umsetzung: TradeManager(..., nur_ticket: bool = False). Bei True:
refresh()fragt ausschließlichpositions_get(ticket=self.ticket)- ist
self.ticket is None, ist der Manager flat — er sucht sich nichts _refresh_lockedadoptiert nicht per magic-match
Schritte (in dieser Reihenfolge)
TradeManagerumnur_ticketerweitern. DefaultFalse→ der bestehende Manager verhält sich bitgenau wie heute. Test, der das festnagelt (Mustertests/test_room_info.py: alte Fassung eingefroren, über Zufallslagen gegengerechnet).engine.trader_brk+engine.trail_brkanlegen. Noch ohne Nutzung.- BRK-Pfad umhängen:
_manage_squeeze_pending,_check_pending_fill,_check_auto_squeezebenutzentrader_brk. Die FLAT-Bedingung wird zutrader_brk.ticket is None— BRK sieht die andere Position nicht mehr. - Schutz-Stack für BRK zweimal aufrufen:
trail_brk.tick()im_pos_loop, dazu_check_sr_close/_check_auto_close/_check_adverse15mit dem jeweiligen Trader parametrisieren (sie lesen heuteself.traderfest). - Snapshot: zweites Positionsobjekt (
position_brk) + Dashboard-Zeile. ⚠ Ohne Anzeige wäre eine offene Position unsichtbar — das ist die Buchführungs-Lücke von Deployment-Drift Fall 8 in neuer Form. - Circuit-Breaker und Tages-P&L müssen beide Positionen summieren, sonst greift die Notbremse zu spät.
- Margin:
calc_lotsrechnet aufmargin_free. Läuft schon eine Position, ist die frei verfügbare Margin kleiner — BRK würde automatisch kleiner sizen. Das ist gewollt, aber das Feld „Einsatz je Pfad" muss dann als Anteil der GESAMT-Margin gelesen werden, nicht der freien. Vor dem Bau entscheiden.
Was vorher geklärt sein muss
- ⚠ Konto muss FLAT sein. Ein halb umgebauter Schutz-Stack hängt an der falschen Position.
- ⚠
RETAIL_HEDGINGist bestätigt (Broker erlaubt mehrere Positionen) — geprüft 2026-08-19. - ⚠ Zwei Positionen = zweimal Risiko. Bei 40 % Einsatz je Position sind 80 % gebunden. Der Circuit-Breaker (aktuell aus) wäre dann kein Luxus mehr — das gehört mitentschieden.
- ⚠ Die Squeeze-Zahlen gelten weiter nur mit dem kanonischen Exit. Nach dem
Umbau muss
trail_brknachweislich laufen (Log + Snapshot), sonst ist man ungewollt in der gemessen durchgefallenen SL-only-Variante.
Erfolgskontrolle nach dem Bau
- Ein BRK-Trade läuft, während eine manuelle Position offen ist — beide mit eigenem SL und beide mit aktivem Trailing (im Log sichtbar).
squeeze_entry_countsteigt wieder (heute: 0 bei fünf stornierten Fenstern).analyze_squeeze_entry_gap.py: der Abstand Einstieg↔Level bleibt bei ~0.- Die B5-Zählung läuft auf einer NEU vorab fixierten Latte weiter (die alte ist am 2026-08-17 gefallen und rechnerisch unerreichbar).