Slot-Pruefung 5. Durchgang: drei Luecken, eine davon gravierend
Diesmal systematisch statt punktuell: alle Methoden von TradingEngine per AST
klassifiziert, welche Slot-Objekte sie beruehren. 36 Funktionen fassen einen
Slot an, 20 davon NUR Slot 1.
⚠⚠⚠ LUECKE 1 (gravierend): EINE FRISCH GEFUELLTE BRK-POSITION HATTE KEIN
TRAILING. trail_brk.toggle() wurde an genau ZWEI Stellen gerufen - _rebind_brk
(nach Neustart) und toggle_trail (der Knopf). Der frische Pending-Fill kam in
keiner davon vor, und das ist der haeufigste Weg, auf dem eine BRK-Position
entsteht (7 von 8 Trades seit dem Pending-Umbau). Sie lief damit nur mit dem
Broker-SL - exakt die Variante, die backtest_brk_slonly.py verworfen hat (alle
zehn KI enthalten die Null, Trefferquote 40 -> 21 %).
Von aussen unsichtbar: die Position sieht in jeder Anzeige normal aus, ihr
fehlt nur der Schutz. Ironie: _rebind_brk loggt "Trailing wiederhergestellt" -
wiederhergestellt wurde etwas, das fuer einen frischen Fill nie an war.
⚠⚠ LUECKE 2: der Market-Fallback schaltete das FALSCHE Trailing ein. _open rief
pauschal self.trail.toggle(). Zwei Schaeden auf einmal: die BRK-Position bleibt
ungeschuetzt UND auf der manuellen Position wird das Trailing wieder
eingeschaltet, auch wenn der Nutzer es dort bewusst abgeschaltet hatte (nach
einer SL-Handeingabe). Sein handgesetzter Stop waere weitergezogen worden.
Noch nicht eingetreten, weil alle acht Fallback-Versuche des 20.08. schon an
der Order scheiterten.
⚠⚠ LUECKE 3: ein geschlossener BRK-Trade loeste KEINE Telegram-Meldung aus.
_close_notify_pending wird in _check_auto_close armiert, das self.trader liest.
Wiegt schwer, weil seit dem 19.08. NUR NOCH "Trade geschlossen" durch den
Telegram-Filter kommt - der autonome Pfad haette vollstaendig still gehandelt.
Behoben in _check_brk_close_cooldown, das den BRK-Flat-Uebergang ohnehin kennt.
Dazu die Reichweiten-Warnung korrigiert: sie sagte "Broker-SL, Trailing und
Circuit-Breaker greifen weiter" - das Trailing tat es eben NICHT.
ABGESICHERT auf zwei Ebenen, beide mutationsgeprueft:
tests/test_pending_fill.py +2: der Fill MUSS trail_brk einschalten und DARF
das Trailing von Slot 1 nicht anfassen. Mutation -> Test faellt.
Pipeline-Stufe E, Regel E: jeder Pfad, der eine BRK-Position eroeffnet
(_check_pending_fill, _open), MUSS trail_brk erwaehnen. Mutation -> Exit 1.
Die Test-Fixture bekam dafuer erstmals BEIDE Trailing-Attrappen - ohne die war
der gefaehrlichste Slot-Fehler ueberhaupt nicht pruefbar.
GEPRUEFT UND SAUBER: Circuit-Breaker, close(), _check_open_notify, _price_loop,
_write_levels_file, snapshot, die Fill-Bindung, die _pos_loop-Reihenfolge.
BEWUSST NICHT GEAENDERT (Slot-1-only, aber alle Features AUS): _check_auto_close,
_check_sr_close, _check_adverse15, _check_flip_close, _check_auto_m15, set_sltp,
_check_close_alert. _check_slot_reichweite meldet es, sobald eines eingeschaltet
wird. Zweislot-faehig waere ein Umbau der Notfall-Zustandsmaschine - offen.
⚠⚠ ZWEI CONFIG-WERTE SIND AUF 0 ZURUECKGEDRIFTET (nur berichtet):
close_notify_min_eur dokumentiert 50 -> ist 0 (Telegram ganz still)
auto_emergency_margin_pct dokumentiert 8 -> ist 0
Bei close_notify_min_eur = 0 nuetzt auch Luecke 3 nichts - die Vormerkung haengt
an _close_notify_min > 0. Der Bot meldet derzeit gar keinen Trade-Abschluss.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
437ab56598
commit
0386497a79
@@ -9106,6 +9106,84 @@ drosselt, ist schlimmer als keine — sie verdeckt genau die Meldung, die zählt
|
|||||||
| offene Position kleiner halten | die einzige Variante, die BRK sofort Luft gibt |
|
| offene Position kleiner halten | die einzige Variante, die BRK sofort Luft gibt |
|
||||||
⚠ **Nichts davon wurde eigenmächtig gesetzt.**
|
⚠ **Nichts davon wurde eigenmächtig gesetzt.**
|
||||||
|
|
||||||
|
## ⚠⚠⚠ SLOT-PRÜFUNG, FÜNFTER DURCHGANG — drei Lücken, eine davon gravierend (2026-08-20)
|
||||||
|
|
||||||
|
User-Auftrag (zum fünften Mal). Diesmal **systematisch statt punktuell**: alle
|
||||||
|
Methoden von `TradingEngine` per AST danach klassifiziert, welche Slot-Objekte
|
||||||
|
sie berühren. **36 Funktionen** fassen einen Slot an; 20 davon **nur Slot 1**.
|
||||||
|
|
||||||
|
⚠⚠⚠ **LÜCKE 1 — DIE GRAVIERENDSTE: EINE FRISCH GEFÜLLTE BRK-POSITION HATTE
|
||||||
|
KEIN TRAILING.** `trail_brk.toggle()` wurde an genau **zwei** Stellen gerufen —
|
||||||
|
`_rebind_brk` (nach einem Neustart) und `toggle_trail` (der TRAIL-Knopf). Der
|
||||||
|
**frische Pending-Fill kam in keiner davon vor** — und das ist der häufigste
|
||||||
|
Weg, auf dem eine BRK-Position überhaupt entsteht (**7 von 8** Trades seit dem
|
||||||
|
Pending-Umbau vom 05.08.).
|
||||||
|
Eine so gefüllte Position lief damit **nur mit dem Broker-SL**, also exakt in
|
||||||
|
der Variante, die `backtest_brk_slonly.py` am 19.08. **verworfen** hat: alle
|
||||||
|
zehn Konfidenzintervalle enthalten die Null, die Trefferquote fällt **40 →
|
||||||
|
21 %**, vier von fünf Trades laufen in den vollen −2R-Stop.
|
||||||
|
⚠ **Von aussen unsichtbar** — die Position sieht in jeder Anzeige normal aus,
|
||||||
|
ihr fehlt nur der Schutz. ⚠ Ironie: `_rebind_brk` loggt „Trailing des BRK-Slots
|
||||||
|
wiederhergestellt"; wiederhergestellt wurde etwas, das für einen frischen Fill
|
||||||
|
**nie an war**.
|
||||||
|
|
||||||
|
⚠⚠ **LÜCKE 2 — der Market-Fallback schaltete das FALSCHE Trailing ein.** `_open`
|
||||||
|
rief pauschal `self.trail.toggle(sym)`. Bei `source == "auto_squeeze"` heisst
|
||||||
|
das: **zwei Schäden auf einmal** — (a) die BRK-Position bleibt ungeschützt und
|
||||||
|
(b) auf der **manuellen** Position wird das Trailing wieder **eingeschaltet**,
|
||||||
|
auch wenn der Nutzer es dort gerade bewusst abgeschaltet hatte (etwa nach einer
|
||||||
|
SL-Handeingabe, die `deactivate()` auslöst). Sein handgesetzter Stop wäre danach
|
||||||
|
vom Trailing weitergezogen worden.
|
||||||
|
⚠ Noch nicht eingetreten, weil alle acht Market-Fallback-Versuche des 20.08.
|
||||||
|
schon an der Order scheiterten (`Lot-Fehler`) — der Pfad bricht davor ab.
|
||||||
|
|
||||||
|
⚠⚠ **LÜCKE 3 — ein geschlossener BRK-Trade löste KEINE Telegram-Meldung aus.**
|
||||||
|
`_close_notify_pending` wird in `_check_auto_close` armiert, und das liest
|
||||||
|
`self.trader.snapshot()`. Das wiegt schwer, weil seit dem 19.08. **nur noch
|
||||||
|
„Trade geschlossen"** durch den Telegram-Filter kommt: der autonome Pfad hätte
|
||||||
|
also **vollständig still** gehandelt — genau der Zustand, den der Befund vom
|
||||||
|
11.08. („alle neun Auslöser waren aus") beseitigen sollte.
|
||||||
|
✅ Behoben in `_check_brk_close_cooldown`, das den BRK-Flat-Übergang ohnehin
|
||||||
|
schon erkennt.
|
||||||
|
|
||||||
|
✅ **ALLE DREI BEHOBEN**, dazu die **Reichweiten-Warnung korrigiert**: sie sagte
|
||||||
|
„Broker-SL, **Trailing** und Circuit-Breaker greifen weiter" — das Trailing tat
|
||||||
|
es eben NICHT. Die Warnung selbst war also irreführend.
|
||||||
|
|
||||||
|
**ABGESICHERT — zwei Ebenen, beide mutationsgeprüft:**
|
||||||
|
· **`tests/test_pending_fill.py`** + 2 Tests: der Fill **muss** `trail_brk`
|
||||||
|
einschalten, und er **darf** das Trailing von Slot 1 **nicht** anfassen.
|
||||||
|
Mutation (Fix zurückgebaut) → Test fällt.
|
||||||
|
· **Pipeline-Stufe E** (`tools/check_slots.py`, Regel **E**): jeder Pfad, der
|
||||||
|
eine BRK-Position eröffnet (`_check_pending_fill`, `_open`), **muss**
|
||||||
|
`trail_brk` erwähnen. Mutation → **Exit 1**.
|
||||||
|
⚠ Dafür bekam die Test-Fixture erstmals **beide** Trailing-Attrappen — ohne die
|
||||||
|
war der gefährlichste Slot-Fehler überhaupt nicht prüfbar.
|
||||||
|
|
||||||
|
✅ **GEPRÜFT UND SAUBER:** Circuit-Breaker (schliesst beide), `close()` (beide),
|
||||||
|
`_check_open_notify` (beide), `_price_loop` (füttert beide), `_write_levels_file`
|
||||||
|
(Marker beider Slots), `snapshot` (beide), `_check_pending_fill` (Bindung
|
||||||
|
korrekt), `_pos_loop`-Reihenfolge (Fill **vor** Pending-Manager).
|
||||||
|
|
||||||
|
⚠ **BEWUSST NICHT GEÄNDERT — Slot-1-only, aber alle Features AUS:**
|
||||||
|
`_check_auto_close` (Notfall-Stop · Gewinn-Ziel · Trail-Restore),
|
||||||
|
`_check_sr_close`, `_check_adverse15`, `_check_flip_close`, `_check_auto_m15`,
|
||||||
|
`set_sltp` (die SL/TP-Felder der Trade-Leiste wirken nur auf Slot 1),
|
||||||
|
`_check_close_alert`. `_check_slot_reichweite` meldet das im Log, sobald eines
|
||||||
|
davon eingeschaltet wird und gleichzeitig eine BRK-Position läuft. Sie
|
||||||
|
zweislot-fähig zu machen ist ein Umbau der Notfall-Zustandsmaschine
|
||||||
|
(`_emergency_*_ticket`), kein Einzeiler — **offen, benannt**.
|
||||||
|
|
||||||
|
⚠⚠ **ZWEI CONFIG-WERTE SIND AUF 0 ZURÜCKGEDRIFTET** (nur berichtet, nicht
|
||||||
|
geändert — Sizing/Alarm sind User-Entscheidungen):
|
||||||
|
| Schlüssel | dokumentiert | ist |
|
||||||
|
|---|---|---|
|
||||||
|
| `close_notify_min_eur` | **50** (11.08.) | **0 = Telegram ganz still** |
|
||||||
|
| `auto_emergency_margin_pct` | **8** (07.08.) | **0** |
|
||||||
|
⚠ Bei `close_notify_min_eur = 0` nützt auch die soeben geschlossene Lücke 3
|
||||||
|
nichts: die Vormerkung hängt an `_close_notify_min > 0`. **Der Bot meldet
|
||||||
|
derzeit gar keinen Trade-Abschluss.**
|
||||||
|
|
||||||
## ⚠⚠⚠ P(break) IST LIVE **INVERTIERT** — und es steuert echtes Geld (2026-08-19)
|
## ⚠⚠⚠ P(break) IST LIVE **INVERTIERT** — und es steuert echtes Geld (2026-08-19)
|
||||||
|
|
||||||
Die fällige Messung ist entscheidbar geworden: **n=530 entkoppelt** gegen die
|
Die fällige Messung ist entscheidbar geworden: **n=530 entkoppelt** gegen die
|
||||||
|
|||||||
+43
-5
@@ -1031,6 +1031,16 @@ class TradingEngine:
|
|||||||
self._brk_letzte = None
|
self._brk_letzte = None
|
||||||
self._pos_close_ts = time.time()
|
self._pos_close_ts = time.time()
|
||||||
self._pos_close_dir = "LONG" if vorher[1] == 0 else "SHORT"
|
self._pos_close_dir = "LONG" if vorher[1] == 0 else "SHORT"
|
||||||
|
# ⚠⚠ AUCH die Close-Benachrichtigung vormerken (Fix 2026-08-20).
|
||||||
|
# `_check_auto_close` armiert sie aus `self.trader.snapshot()`,
|
||||||
|
# sieht den BRK-Slot also nicht — ein geschlossener BRK-Trade
|
||||||
|
# loeste KEINE Telegram-Meldung aus. Das wiegt schwer, weil seit
|
||||||
|
# dem 19.08. NUR NOCH "Trade geschlossen" durch den
|
||||||
|
# Telegram-Filter kommt: der autonome Pfad haette also voellig
|
||||||
|
# still gehandelt — genau der Zustand, den der Befund vom 11.08.
|
||||||
|
# ("alle neun Ausloeser waren aus") beseitigen sollte.
|
||||||
|
if self._close_notify_min > 0:
|
||||||
|
self._close_notify_pending = [vorher[0], 0]
|
||||||
log.info("BRK-Slot geschlossen (T=%s) — Wiedereinstiegs-Sperre "
|
log.info("BRK-Slot geschlossen (T=%s) — Wiedereinstiegs-Sperre "
|
||||||
"%s armiert.", vorher[0], self._pos_close_dir)
|
"%s armiert.", vorher[0], self._pos_close_dir)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1150,8 +1160,9 @@ class TradingEngine:
|
|||||||
if getattr(self, "_reichweite_gemeldet", None) != tk:
|
if getattr(self, "_reichweite_gemeldet", None) != tk:
|
||||||
self._reichweite_gemeldet = tk
|
self._reichweite_gemeldet = tk
|
||||||
log.warning("⚠ REICHWEITE: %s aktiv, gilt aber NUR für Slot 1 — "
|
log.warning("⚠ REICHWEITE: %s aktiv, gilt aber NUR für Slot 1 — "
|
||||||
"die BRK-Position T=%s läuft ohne (Broker-SL, "
|
"die BRK-Position T=%s läuft ohne. Es greifen: "
|
||||||
"Trailing und Circuit-Breaker greifen weiter).",
|
"Broker-SL, Circuit-Breaker und — seit dem Fix vom "
|
||||||
|
"20.08. — das eigene Trailing (`trail_brk`).",
|
||||||
", ".join(offen), tk)
|
", ".join(offen), tk)
|
||||||
return offen
|
return offen
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1636,6 +1647,21 @@ class TradingEngine:
|
|||||||
# Dieselbe Buchfuehrung wie beim Market-Pfad, damit B4/B5 zaehlen
|
# Dieselbe Buchfuehrung wie beim Market-Pfad, damit B4/B5 zaehlen
|
||||||
self._bot_open_ticket = tk
|
self._bot_open_ticket = tk
|
||||||
self._bot_open_source = "auto_squeeze"
|
self._bot_open_source = "auto_squeeze"
|
||||||
|
# ⚠⚠ TRAILING EINSCHALTEN — ohne das lief der HAEUFIGSTE BRK-Pfad
|
||||||
|
# voellig ungeschuetzt (Fix 2026-08-20). `trail_brk.toggle()` wurde
|
||||||
|
# bis dahin an genau ZWEI Stellen gerufen: beim Rueckbinden nach
|
||||||
|
# einem Neustart und ueber den TRAIL-Knopf. Der frische Fill — und
|
||||||
|
# das sind 7 von 8 BRK-Trades, seit der Pending-Umbau laeuft —
|
||||||
|
# kam in keiner davon vor. Eine so gefuellte Position hatte nur
|
||||||
|
# den Broker-SL, also exakt die Variante, die
|
||||||
|
# `backtest_brk_slonly.py` verworfen hat.
|
||||||
|
# ⚠ Ironie am Rande: `_rebind_brk` loggt "Trailing des BRK-Slots
|
||||||
|
# wiederhergestellt" — wiederhergestellt wurde etwas, das fuer
|
||||||
|
# einen frischen Fill nie an war.
|
||||||
|
if not self.trail_brk.enabled and self.data.symbol:
|
||||||
|
self.trail_brk.set_setup(setup)
|
||||||
|
self.trail_brk.toggle(self.data.symbol)
|
||||||
|
log.info(f"Trailing des BRK-Slots aktiviert (T={tk})")
|
||||||
self._squeeze_entry_count += 1
|
self._squeeze_entry_count += 1
|
||||||
log.info(f"🎯 PENDING-FILL ({quelle}): {d} @ {ps.get('entry_price')} "
|
log.info(f"🎯 PENDING-FILL ({quelle}): {d} @ {ps.get('entry_price')} "
|
||||||
f"— Position {tk} als {setup} getaggt"
|
f"— Position {tk} als {setup} getaggt"
|
||||||
@@ -2995,9 +3021,21 @@ class TradingEngine:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
# Trailing automatisch aktivieren (wie _after_trade im Widget)
|
# Trailing automatisch aktivieren (wie _after_trade im Widget)
|
||||||
if not self.trail.enabled:
|
# ⚠⚠ DAS TRAILING DES *SLOTS*, nicht pauschal `self.trail` (Fix 2026-08-20).
|
||||||
self.trail.set_setup(self._last_rec.get("setup"))
|
# Vorher lief hier IMMER Slot 1 — mit zwei Schaeden auf einmal:
|
||||||
self.trail.toggle(sym)
|
# (a) die BRK-Position bekam KEIN Trailing und lief damit in die
|
||||||
|
# gemessen DURCHGEFALLENE SL-only-Variante
|
||||||
|
# (`backtest_brk_slonly.py`: alle zehn KI enthalten die Null,
|
||||||
|
# Trefferquote faellt 40 -> 21 %);
|
||||||
|
# (b) schlimmer noch: ein BRK-Entry schaltete das Trailing auf der
|
||||||
|
# MANUELLEN Position wieder EIN — auch wenn der Nutzer es dort
|
||||||
|
# gerade bewusst abgeschaltet hatte (etwa nach einer SL-Handeingabe,
|
||||||
|
# die `deactivate()` ausloest). Sein Stop waere danach vom Trailing
|
||||||
|
# weitergezogen worden.
|
||||||
|
_tr = self.trail_brk if source == "auto_squeeze" else self.trail
|
||||||
|
if not _tr.enabled:
|
||||||
|
_tr.set_setup(self._last_rec.get("setup"))
|
||||||
|
_tr.toggle(sym)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def close(self, slot: str | None = None) -> str | None:
|
def close(self, slot: str | None = None) -> str | None:
|
||||||
|
|||||||
@@ -103,6 +103,26 @@ def engine(history):
|
|||||||
e.trader = FakeTrader()
|
e.trader = FakeTrader()
|
||||||
# Zweiter, strikt ticket-gebundener Slot fuer BRK (Umbau 2026-08-19).
|
# Zweiter, strikt ticket-gebundener Slot fuer BRK (Umbau 2026-08-19).
|
||||||
e.trader_brk = FakeTrader()
|
e.trader_brk = FakeTrader()
|
||||||
|
# ⚠⚠ BEIDE Trailing-Manager — sonst ist der gefaehrlichste Slot-Fehler
|
||||||
|
# ueberhaupt nicht pruefbar: bis zum 2026-08-20 hat der Pending-Fill das
|
||||||
|
# BRK-Trailing NICHT eingeschaltet, die Position lief nur mit dem
|
||||||
|
# Broker-SL (gemessen durchgefallen, `backtest_brk_slonly.py`). Die
|
||||||
|
# Attrappe merkt sich lediglich, OB `toggle()` gerufen wurde — die
|
||||||
|
# Trailing-Mechanik selbst gehoert nicht in diesen Test.
|
||||||
|
class _FakeTrail:
|
||||||
|
def __init__(self):
|
||||||
|
self.enabled = False
|
||||||
|
self.setup = None
|
||||||
|
def set_setup(self, s):
|
||||||
|
self.setup = s
|
||||||
|
def toggle(self, sym):
|
||||||
|
self.enabled = not self.enabled
|
||||||
|
return self.enabled
|
||||||
|
def deactivate(self):
|
||||||
|
was, self.enabled = self.enabled, False
|
||||||
|
return was
|
||||||
|
e.trail = _FakeTrail()
|
||||||
|
e.trail_brk = _FakeTrail()
|
||||||
e.data = types.SimpleNamespace(symbol="XTIUSD")
|
e.data = types.SimpleNamespace(symbol="XTIUSD")
|
||||||
e.cfg = {"telegram": {"enabled": "false"}}
|
e.cfg = {"telegram": {"enabled": "false"}}
|
||||||
# Zustand der geprüften Pfade
|
# Zustand der geprüften Pfade
|
||||||
|
|||||||
@@ -88,3 +88,48 @@ def test_ohne_pending_merker_sofort_raus(engine):
|
|||||||
engine._check_pending_fill()
|
engine._check_pending_fill()
|
||||||
|
|
||||||
assert engine._bot_open_ticket is None
|
assert engine._bot_open_ticket is None
|
||||||
|
|
||||||
|
|
||||||
|
# ── Trailing am BRK-Slot (Fix 2026-08-20) ───────────────────────────────────
|
||||||
|
def test_fill_schaltet_das_BRK_TRAILING_ein(engine):
|
||||||
|
"""⚠⚠ DER GEFAEHRLICHSTE FUND DER SLOT-PRUEFUNG.
|
||||||
|
|
||||||
|
`trail_brk.toggle()` wurde bis zum 20.08. an genau ZWEI Stellen gerufen:
|
||||||
|
beim Rueckbinden nach einem Neustart und ueber den TRAIL-Knopf. Der
|
||||||
|
FRISCHE Pending-Fill kam in keiner davon vor - und das ist der haeufigste
|
||||||
|
Weg, auf dem eine BRK-Position entsteht (7 von 8 Trades seit dem
|
||||||
|
Pending-Umbau). Eine so gefuellte Position hatte damit nur den Broker-SL:
|
||||||
|
exakt die SL-only-Variante, die `backtest_brk_slonly.py` verworfen hat
|
||||||
|
(alle zehn KI enthalten die Null, Trefferquote faellt 40 -> 21 %).
|
||||||
|
|
||||||
|
Ohne diesen Test faellt ein Rueckbau nicht auf - die Position sieht in
|
||||||
|
jeder Anzeige normal aus, ihr fehlt nur der Schutz.
|
||||||
|
"""
|
||||||
|
engine._pending_tickets = {49483982: "squeeze"}
|
||||||
|
engine.trader_brk.snap = {"ticket": 49483982, "order_type": 0,
|
||||||
|
"entry_price": 75.5}
|
||||||
|
engine.trader_brk.ticket = 49483982
|
||||||
|
assert not engine.trail_brk.enabled, "Vorbedingung: Trailing ist AUS"
|
||||||
|
|
||||||
|
engine._check_pending_fill()
|
||||||
|
|
||||||
|
assert engine.trail_brk.enabled, (
|
||||||
|
"Der BRK-Slot laeuft nach einem Pending-Fill OHNE Trailing - "
|
||||||
|
"nur mit dem Broker-SL (gemessen durchgefallen)")
|
||||||
|
|
||||||
|
|
||||||
|
def test_fill_laesst_SLOT1_trailing_in_ruhe(engine):
|
||||||
|
"""Die Gegenprobe: der Fill darf das Trailing der MANUELLEN Position nicht
|
||||||
|
anfassen. Der Nutzer schaltet es dort bewusst ab (z. B. nach einer
|
||||||
|
SL-Handeingabe, die `deactivate()` ausloest) - ein BRK-Entry darf es ihm
|
||||||
|
nicht wieder einschalten und seinen Stop weiterziehen."""
|
||||||
|
engine.trail.enabled = False
|
||||||
|
engine._pending_tickets = {49483983: "squeeze"}
|
||||||
|
engine.trader_brk.snap = {"ticket": 49483983, "order_type": 0,
|
||||||
|
"entry_price": 75.6}
|
||||||
|
engine.trader_brk.ticket = 49483983
|
||||||
|
|
||||||
|
engine._check_pending_fill()
|
||||||
|
|
||||||
|
assert not engine.trail.enabled, (
|
||||||
|
"Ein BRK-Fill hat das Trailing der manuellen Position eingeschaltet")
|
||||||
|
|||||||
+33
-1
@@ -159,12 +159,44 @@ def _sperrliste_vollstaendig(baum: ast.AST) -> list:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def _brk_bekommt_trailing(baum: ast.AST) -> list:
|
||||||
|
"""(E) Jeder Pfad, der eine BRK-Position EROEFFNET, muss `trail_brk` anfassen.
|
||||||
|
|
||||||
|
⚠⚠ DER GEFAEHRLICHSTE FUND DER SLOT-PRUEFUNG (2026-08-20): `trail_brk.toggle()`
|
||||||
|
wurde an genau ZWEI Stellen gerufen — beim Rueckbinden nach einem Neustart
|
||||||
|
(`_rebind_brk`) und ueber den TRAIL-Knopf (`toggle_trail`). Der FRISCHE
|
||||||
|
Pending-Fill kam in keiner davon vor, und das ist der haeufigste Weg, auf dem
|
||||||
|
eine BRK-Position entsteht (7 von 8 Trades seit dem Pending-Umbau). Der
|
||||||
|
Market-Fallback (`_open`) war noch schlechter: er schaltete `self.trail` ein,
|
||||||
|
also das Trailing der MANUELLEN Position — die BRK-Position blieb ungeschuetzt
|
||||||
|
UND dem Nutzer wurde auf seinem eigenen Trade das Trailing wieder angemacht.
|
||||||
|
Eine nur mit dem Broker-SL laufende BRK-Position ist genau die Variante, die
|
||||||
|
`backtest_brk_slonly.py` verworfen hat (alle zehn KI enthalten die Null,
|
||||||
|
Trefferquote faellt 40 -> 21 %).
|
||||||
|
⚠ Von aussen unsichtbar: die Position sieht in jeder Anzeige normal aus, ihr
|
||||||
|
fehlt nur der Schutz. Deshalb diese statische Regel.
|
||||||
|
"""
|
||||||
|
OEFFNER = {"_check_pending_fill": "der Pending-Fill",
|
||||||
|
"_open": "der Market-Fallback"}
|
||||||
|
befunde = []
|
||||||
|
for fn in [n for n in ast.walk(baum) if isinstance(n, ast.FunctionDef)]:
|
||||||
|
if fn.name not in OEFFNER:
|
||||||
|
continue
|
||||||
|
if "trail_brk" not in ast.unparse(fn):
|
||||||
|
befunde.append(
|
||||||
|
f"{fn.name}: erwaehnt `trail_brk` NICHT — {OEFFNER[fn.name]} "
|
||||||
|
f"wuerde eine BRK-Position OHNE Trailing eroeffnen "
|
||||||
|
f"(nur Broker-SL = gemessen durchgefallen)")
|
||||||
|
return sorted(befunde)
|
||||||
|
|
||||||
|
|
||||||
def pruefe() -> list:
|
def pruefe() -> list:
|
||||||
p = WURZEL / "core" / "engine.py"
|
p = WURZEL / "core" / "engine.py"
|
||||||
quelle = p.read_text(encoding="utf-8")
|
quelle = p.read_text(encoding="utf-8")
|
||||||
baum = ast.parse(quelle)
|
baum = ast.parse(quelle)
|
||||||
return (_init_reihenfolge(baum, quelle) + _slot_trennung(baum)
|
return (_init_reihenfolge(baum, quelle) + _slot_trennung(baum)
|
||||||
+ _close_beide(baum) + _sperrliste_vollstaendig(baum))
|
+ _close_beide(baum) + _sperrliste_vollstaendig(baum)
|
||||||
|
+ _brk_bekommt_trailing(baum))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user