# 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:

```python
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ßlich `positions_get(ticket=self.ticket)`
- ist `self.ticket is None`, ist der Manager flat — er sucht sich **nichts**
- `_refresh_locked` adoptiert nicht per magic-match

---

## Schritte (in dieser Reihenfolge)

1. **`TradeManager` um `nur_ticket` erweitern.** Default `False` → der
   bestehende Manager verhält sich **bitgenau** wie heute. Test, der das
   festnagelt (Muster `tests/test_room_info.py`: alte Fassung eingefroren, über
   Zufallslagen gegengerechnet).
2. **`engine.trader_brk` + `engine.trail_brk` anlegen.** Noch ohne Nutzung.
3. **BRK-Pfad umhängen:** `_manage_squeeze_pending`, `_check_pending_fill`,
   `_check_auto_squeeze` benutzen `trader_brk`. Die FLAT-Bedingung wird zu
   `trader_brk.ticket is None` — BRK sieht die andere Position nicht mehr.
4. **Schutz-Stack für BRK zweimal aufrufen:** `trail_brk.tick()` im `_pos_loop`,
   dazu `_check_sr_close` / `_check_auto_close` / `_check_adverse15` mit dem
   jeweiligen Trader parametrisieren (sie lesen heute `self.trader` fest).
5. **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.
6. **Circuit-Breaker und Tages-P&L** müssen **beide** Positionen summieren,
   sonst greift die Notbremse zu spät.
7. **Margin:** `calc_lots` rechnet auf `margin_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_HEDGING` ist 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_brk` nachweislich 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_count` steigt 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).
