diff --git a/CLAUDE.md b/CLAUDE.md index 066d533..c5baa32 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -812,6 +812,14 @@ dort bereits nachvalidiert, ØR +0,305.) **Eine** Oberfläche: close und notfall close … nicht setzen beim Eröffnen" → alle drei Auto-Arm-Modi 0, beim Öffnen einer Position wird KEIN Notfall-Stop gesetzt. Nur ein **manuell** im UI-Feld eingegebener Wert armiert (bleibt bis zum nächsten Positionswechsel). + **⚠ Vertipper-Schutz `[trading] emergency_min_eur=3` (Fix 2026-07-27):** ein manuell + gesetzter Notfall-Stop UNTER diesem Minimum wird als „aus" behandelt (nicht + scharfgestellt) + Log-Warnung. Grund: ein Sub-Spread-Wert schließt den Trade + **sofort** UND vererbt sich per `_emergency_remember` auf ALLE Folge-Trades — real + am 2026-07-27 setzte der User versehentlich −1 € → jeder neue Trade wurde in + Sekunden per Notfall-Close gekillt (Tickets 48504360/48504814 u. a., „sofort + geschlossen"). Guard in `set_emergency` (greift NUR auf die manuelle Eingabe; + die %-Auto-Arm-Pfade sind eh 0). 0 = kein Floor. Kurz-Historie des margin-%-Modus: 2026-07-17 komplett raus (2 % ≈ 0,76×ATR zerschoss die Squeeze-Trades, −48,94-€-Tag) · 2026-07-20 wenige Stunden als **3-%-GAP-NETZ (Balance-Basis)** mit `risk_pct=1.5` · **2026-07-23 kurz margin-basiert `=3.0`** diff --git a/core/config.py b/core/config.py index 52d30aa..8c7d318 100644 --- a/core/config.py +++ b/core/config.py @@ -266,6 +266,11 @@ DEFAULT_CONFIG = { # 2026-07-17: −48,94 €). Seit 2026-07-20 läuft stattdessen das %-GAP-NETZ # (auto_emergency_pct=3.0, s. u.) — nur in Kombination mit risk_pct=1.5 sinnvoll. "auto_emergency_loss": "0", + # Mindest-Notfall-Stop (Kontowährung): ein manuell gesetzter Wert DARUNTER + # wird als „aus" behandelt (Vertipper-Schutz — ein Sub-Spread-Wert schließt + # sofort und vererbt sich per _emergency_remember auf alle Folge-Trades; + # real 2026-07-27 killte ein −1-€-Stop jeden Trade in Sekunden). 0 = kein Floor. + "emergency_min_eur": "3", # Gewinn-mitnehmen automatisch beim Öffnen setzen (Kontowährung). 0 = aus # (dann nur manuell im UI). Merkt den zuletzt gesetzten Wert. "auto_takeprofit": "0", diff --git a/core/engine.py b/core/engine.py index 40bf5e9..c75f3b4 100644 --- a/core/engine.py +++ b/core/engine.py @@ -260,6 +260,15 @@ class TradingEngine: # garantiert identische Linien in Kachel/Chart/Close-Meldung + spart Lock-Last self._emergency_loss: float | None = None # aktiver Notfall-Stop (Verlust) self._last_pos_ticket = None # für Auto-Arm beim Öffnen + # Mindest-Notfall-Stop (Kontowährung): ein von Hand gesetzter Wert UNTER + # diesem Minimum wird als „aus" behandelt statt scharfgestellt — sonst killt + # ein Vertipper (z. B. „1") jeden Trade sofort, weil die Schwelle unter dem + # Spread liegt UND per _emergency_remember auf ALLE Folge-Trades vererbt wird + # (real 2026-07-27: −1-€-Stop schloss Trades in derselben Sekunde). 0 = aus. + try: + self._emergency_min = max(0.0, float(self.cfg["trading"].get("emergency_min_eur", "3") or 0)) + except (TypeError, ValueError): + self._emergency_min = 3.0 # Beim Öffnen einer neuen Position wird der Notfall-Stop automatisch auf # den ZULETZT genutzten Wert gesetzt (gemerkt über Trades hinweg). Start- # wert = [trading] auto_emergency_loss (0 = Auto-Arm aus). @@ -483,6 +492,13 @@ class TradingEngine: v = None except (TypeError, ValueError): v = None + # Vertipper-Schutz: ein Wert unter dem Minimum (Spread-Region) würde den + # Trade sofort schließen UND sich auf alle Folge-Trades vererben → als „aus" + # behandeln (Fix 2026-07-27, real: −1-€-Stop killte jeden Trade sofort). + if v is not None and self._emergency_min > 0 and v < self._emergency_min: + log.warning(f"Notfall-Stop −{v:.2f} < Minimum {self._emergency_min:.2f} € " + f"(zu eng, würde sofort schließen) → als AUS behandelt") + v = None self._emergency_loss = v if v is not None: self._emergency_remember = v # für die nächste Position merken