Trailing neustart-fest: Zustand per-Ticket persistieren + bei Wiedererkennung reaktivieren
Problem: trail.enabled lebte nur im Speicher -> nach jedem restart_server.bat war das Trailing aus, die (auch per Auto-Squeeze eroeffnete) Position lief nur mit dem Broker-SL (kein Breakeven/Time-Stop). Die magic-match-Wiedererkennung reaktivierte es nie; der User musste es manuell einschalten (real 2026-07-29). Fix: - emergency_state.json persistiert zusaetzlich "trail" (=trail.enabled) per-Ticket. - _check_auto_close-Restore-Zweig: erkannte Position + trail war AN -> trail.toggle, Log "Trailing wiederhergestellt ... nach Neustart". War es AUS (manuelles SL/TP), bleibt es aus (persistierter Zustand entscheidet, kein TP-Ueberschreiben). - Change-Detection im _pos_loop persistiert bei jeder Aenderung (auch Selbst- Deaktivierung bei manueller SL/TP-Erkennung), nur bei Aenderung -> kein I/O je Tick. Verifiziert: Live-Position 48763789 nach Deploy-Neustart automatisch mit Trailing wiederhergestellt (Log + Snapshot trail.enabled=True). Keine Loop-Fehler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c15aa36d46
commit
e9653a842a
+19
-1
@@ -340,6 +340,7 @@ class TradingEngine:
|
||||
self._emergency_state_ticket = None
|
||||
self._emergency_state_loss = None
|
||||
self._emergency_state_tp = None
|
||||
self._emergency_state_trail = None # Trailing-Zustand per-Ticket (neustart-fest)
|
||||
self._load_emergency_state()
|
||||
# Startup-Schonfrist: bis zu diesem Zeitpunkt kein server-seitiger Auto-Close
|
||||
# (in start() gesetzt). Konfigurierbar via [trading] startup_close_grace_s.
|
||||
@@ -719,6 +720,14 @@ class TradingEngine:
|
||||
log.info(f"Auto-Close wiederhergestellt (Pos {ticket}): Stop "
|
||||
f"{('-'+format(self._emergency_loss,'.2f')) if self._emergency_loss else 'aus'} · TP "
|
||||
f"{('+'+format(self._takeprofit,'.2f')) if self._takeprofit else 'aus'}")
|
||||
# Trailing wiederherstellen: war es vor dem Neustart AN, wieder aktivieren
|
||||
# (Fix 2026-07-29: Trailing lebte nur im Speicher → nach jedem Neustart
|
||||
# aus, die Position lief nur mit Broker-SL, ohne Breakeven/Time-Stop; der
|
||||
# User musste es manuell einschalten). War es AUS (z. B. manuelles SL/TP
|
||||
# → deaktiviert), bleibt es aus — der persistierte Zustand entscheidet.
|
||||
if self._emergency_state_trail and not self.trail.enabled and self.data.symbol:
|
||||
self.trail.toggle(self.data.symbol)
|
||||
log.info(f"Trailing wiederhergestellt (Pos {ticket}) nach Neustart")
|
||||
else: # echt neue Position → armieren
|
||||
if self._emergency_margin_pct > 0:
|
||||
pass # wird unten margin-basiert (retry-sicher) gesetzt
|
||||
@@ -767,6 +776,12 @@ class TradingEngine:
|
||||
self._save_emergency_state()
|
||||
log.info(f"Notfall-Stop armiert (Pos {ticket}): "
|
||||
f"-{self._emergency_loss:.2f} ({self._emergency_margin_pct:.0f}% Margin {margin:.2f})")
|
||||
# Trailing-Zustand per-Ticket neustart-fest halten: nur bei ÄNDERUNG schreiben
|
||||
# (kein Datei-I/O je Tick). Fängt auch die Selbst-Deaktivierung des Trailings
|
||||
# (manuelles SL/TP im Terminal, `_do_modify`) — sonst würde der Neustart ein vom
|
||||
# User abgeschaltetes Trailing wieder anwerfen.
|
||||
if bool(self.trail.enabled) != bool(self._emergency_state_trail):
|
||||
self._save_emergency_state()
|
||||
if self._in_startup_grace(): # Startup-Schonfrist: armieren ja, schließen nein
|
||||
return
|
||||
pnl = ps.get("pnl")
|
||||
@@ -1326,6 +1341,7 @@ class TradingEngine:
|
||||
self._emergency_state_ticket = st.get("ticket")
|
||||
self._emergency_state_loss = st.get("loss")
|
||||
self._emergency_state_tp = st.get("tp")
|
||||
self._emergency_state_trail = st.get("trail")
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
except Exception as e:
|
||||
@@ -1341,11 +1357,13 @@ class TradingEngine:
|
||||
with open(tmp, "w", encoding="utf-8") as f:
|
||||
json.dump({"ticket": self._last_pos_ticket,
|
||||
"loss": self._emergency_loss,
|
||||
"tp": self._takeprofit}, f)
|
||||
"tp": self._takeprofit,
|
||||
"trail": bool(self.trail.enabled)}, f)
|
||||
os.replace(tmp, self._emergency_state_path)
|
||||
self._emergency_state_ticket = self._last_pos_ticket
|
||||
self._emergency_state_loss = self._emergency_loss
|
||||
self._emergency_state_tp = self._takeprofit
|
||||
self._emergency_state_trail = bool(self.trail.enabled)
|
||||
except Exception as e:
|
||||
log.warning(f"emergency_state speichern: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user