M15-Auto-Entry gebaut (Default AUS) -- gegen die Messung, auf User-Wunsch
User wollte den Auto-Trade testen, nach vollstaendiger Information ueber die
Beleglage. backtest_m15_auto.py (13.08.): die gehandelte Lesart ist in BEIDEN
Halbjahren negativ (OeR -0,162/-0,094, PF 0,72/0,84), beide KI schliessen die
Null aus, Nachbarn monoton schlechter, und sie ist schlechter als die
HTF-Richtung UND als ihr eigenes Gegenteil. Live entkoppelt 46,8 % Treffer.
_check_auto_m15 im _pos_loop: Ausloeser gruen + gerichtet, Richtung exakt wie im
Backtest (auf->LONG, ab->SHORT), Dedup 1x je Episode ueber (Richtung, Level),
nur FLAT, Setup-Tag AUTOM15_*. Erbt die VOLLE Guard-Kette ueber
_auto_guard('m15') -- der Parameter war laut Docstring genau dafuer vorgesehen,
nachgebaut wurde nichts.
Abweichung ausdruecklich benannt: gemessen wurde der Einstieg AM Level mit Fill
bei Beruehrung, gebaut ist der Markt-Einstieg. Der ist hier mehrfach als der
schlechtere gemessen -- die Live-Zahlen sind eher noch unter -0,16/-0,09 zu
erwarten.
Abbruchregel VORAB fixiert: nach >=20 AUTOM15_*-Trades Verhaeltnis < 1,0 ODER
PF < 1 -> auto_m15 = false. Dieselbe Latte wie B5, damit sie nicht nachtraeglich
wandert.
Verifiziert: Toggle, Snapshot-Felder, Deploy mit --feld auto_m15, ruff F821
(neuer Code sitzt in einem except -- der dokumentierte blinde Fleck), 85 Tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cc3a710752
commit
bd65bdaad0
+111
-2
@@ -382,6 +382,19 @@ class TradingEngine:
|
||||
# ⚠ ECHTE Order — Default AUS (Autonomie nie stillschweigend an). `[trading]
|
||||
# auto_squeeze=true` aktiviert. Dedup über (dir, level) des Ausbruchs.
|
||||
self._auto_squeeze = self.cfg["trading"].get("auto_squeeze", "false").lower() == "true"
|
||||
# ── M15-KARTEN-AUTO-ENTRY (User-Wunsch 2026-08-19, "ich moechte das
|
||||
# auto trade testen"). ⚠⚠ GEGEN DIE MESSUNG gebaut und deshalb
|
||||
# Default AUS: `backtest_m15_auto.py` (13.08.) hat genau diese Regel
|
||||
# gemessen -- die Lesart ist in BEIDEN Halbjahren negativ
|
||||
# (OeR -0,162/-0,094, PF 0,72/0,84), das 95-%-KI schliesst beide Male
|
||||
# die Null aus, und sie ist schlechter als die HTF-Richtung UND als
|
||||
# ihr eigenes Gegenteil. Live bestaetigt (m15_states, entkoppelt):
|
||||
# 46,8 % Treffer auf 30 min. Der User hat das nach vollstaendiger
|
||||
# Information ausdruecklich zum TESTEN gewuenscht.
|
||||
self._auto_m15 = self.cfg["trading"].get("auto_m15", "false").lower() == "true"
|
||||
self._m15_last_entry_sig = None # Dedup (Richtung, Level) wie im Backtest
|
||||
self._m15_entry_count = 0
|
||||
self._last_m15 = None # letzter berechneter Kartenstand
|
||||
self._squeeze_skip_night = self.cfg["trading"].get("auto_squeeze_skip_night", "true").lower() == "true"
|
||||
# ── WELCHE Stunden ausgesetzt werden (2026-08-05, gemessen `backtest_cost_gate.py`).
|
||||
# War fest 0–7. Die Messung zeigt: KEINE Stunde ist in beiden Halbjahren negativ —
|
||||
@@ -825,6 +838,7 @@ class TradingEngine:
|
||||
self._check_pending_fill() # gefuellte Pending-Order zuordnen
|
||||
self._manage_squeeze_pending()
|
||||
self._check_auto_squeeze() # autonomer Entry auf Squeeze-Ausbruch
|
||||
self._check_auto_m15() # autonomer Entry auf die gruene M15-Karte
|
||||
except Exception as e:
|
||||
log.error(f"_pos_loop: {e}", exc_info=True)
|
||||
self._sleep(_POS_S)
|
||||
@@ -1158,8 +1172,13 @@ class TradingEngine:
|
||||
# den Squeeze. Der Parameter `pfad` bleibt in der Signatur — die
|
||||
# Guard-Kette ist bewusst EINE Quelle für alle autonomen Wege, und ein
|
||||
# künftiger zweiter Weg soll sie wieder benutzen, nicht nachbauen.
|
||||
if not self._auto_squeeze:
|
||||
return "Auto-Squeeze aus"
|
||||
# ⚠ Pfad-abhaengig seit 2026-08-19: der M15-Auto-Entry nutzt DIESELBE
|
||||
# Guard-Kette (Nacht, Circuit, News) statt sie nachzubauen -- genau das,
|
||||
# wofuer der Parameter laut Docstring gedacht ist.
|
||||
_an = {"squeeze": self._auto_squeeze,
|
||||
"m15": getattr(self, "_auto_m15", False)}.get(pfad, self._auto_squeeze)
|
||||
if not _an:
|
||||
return ("Auto-M15 aus" if pfad == "m15" else "Auto-Squeeze aus")
|
||||
skip = self._squeeze_skip_night
|
||||
if self._circuit_halted():
|
||||
return "Circuit-Breaker"
|
||||
@@ -1179,6 +1198,90 @@ class TradingEngine:
|
||||
"""Alias — `_check_auto_squeeze` ruft weiterhin diesen Namen."""
|
||||
return self._auto_guard("squeeze")
|
||||
|
||||
def set_auto_m15(self, on: bool) -> bool:
|
||||
"""M15-Karten-Auto-Entry an/aus. Rueckgabe = neuer Zustand."""
|
||||
self._auto_m15 = bool(on)
|
||||
self._m15_last_entry_sig = None
|
||||
log.info(f"Auto-M15-Entry {'AN' if self._auto_m15 else 'AUS'}")
|
||||
self._save_runtime_state()
|
||||
return self._auto_m15
|
||||
|
||||
def _check_auto_m15(self):
|
||||
"""Autonomer Entry auf die GRUENE, gerichtete M15-Karte (Default AUS).
|
||||
|
||||
⚠⚠ GEGEN DIE MESSUNG. `backtest_m15_auto.py` (13.08.): die Lesart ist in
|
||||
BEIDEN Halbjahren negativ (OeR -0,162 / -0,094, PF 0,72 / 0,84), das
|
||||
95-%-KI schliesst beide Male die Null aus, alle Nachbar-Schwellen werden
|
||||
monoton schlechter, und sie ist schlechter als die HTF-Richtung UND als
|
||||
ihr eigenes Gegenteil. Auf User-Wunsch zum TESTEN gebaut.
|
||||
|
||||
⚠ ABWEICHUNG VON DER GEMESSENEN VARIANTE, ausdruecklich benannt: gemessen
|
||||
wurde der Einstieg AM Level mit Fill bei Beruehrung; hier wird zum MARKT
|
||||
eingestiegen. Im Projekt ist der Markt-Einstieg mehrfach als der
|
||||
schlechtere gemessen (Squeeze +0,456 -> -0,158 allein durch den Preis).
|
||||
Die Live-Zahlen sind also eher noch unter den -0,16/-0,09 zu erwarten.
|
||||
Eine ruhende Order haette den geteilten `_pending_ziel`-Manager
|
||||
gebraucht, in dem der Squeeze Vorrang hat -- das ist ein eigener Umbau.
|
||||
|
||||
Dedup 1x je Episode ueber (Richtung, Level) -- exakt der Backtest-
|
||||
Schluessel `(d_les, nah["level"])`. Erbt die volle Guard-Kette
|
||||
(`_auto_guard("m15")`: Nacht, Circuit-Breaker, News-Blackout) sowie
|
||||
Startup-Schonfrist, Flat-Bedingung und die Wiedereinstiegs-Sperren.
|
||||
"""
|
||||
if not self._auto_m15:
|
||||
return
|
||||
try:
|
||||
if self._in_startup_grace():
|
||||
return
|
||||
s = getattr(self, "_last_m15", None)
|
||||
if not s or s.get("status") != "gruen":
|
||||
self._m15_last_entry_sig = None # re-armt bei Nicht-Gruen
|
||||
return
|
||||
les = s.get("lesart")
|
||||
if les not in ("auf", "ab"):
|
||||
self._m15_last_entry_sig = None
|
||||
return
|
||||
nah = s.get("nah") or {}
|
||||
lvl = nah.get("level")
|
||||
if lvl is None:
|
||||
return
|
||||
d = 1 if les == "auf" else -1 # wie im Backtest
|
||||
sig = (d, round(float(lvl), 3))
|
||||
if sig == self._m15_last_entry_sig:
|
||||
return # dieselbe Episode
|
||||
if (self.trader.snapshot() or {}).get("lots"):
|
||||
return # nur FLAT
|
||||
grund = self._auto_guard("m15")
|
||||
if grund:
|
||||
return
|
||||
# Wiedereinstiegs-Sperren teilen wir mit dem Squeeze (gleiche Logik,
|
||||
# gleiche Begruendung: Open-Close-Kaskaden nach einem Auto-Close).
|
||||
now = time.time()
|
||||
if (self._sr_close_dir == d
|
||||
and now - self._sr_close_ts < _SQUEEZE_SR_COOLDOWN_S):
|
||||
return
|
||||
if (self._pos_close_dir == d
|
||||
and now - self._pos_close_ts < _SQUEEZE_REENTRY_COOLDOWN_S):
|
||||
return
|
||||
self._m15_last_entry_sig = sig
|
||||
want = "long" if d > 0 else "short"
|
||||
# ⚠ Setup-TAG ist Pflicht, nicht Kosmetik: ohne ihn sind die Trades
|
||||
# in der DB von manuellen NICHT unterscheidbar und der Test spaeter
|
||||
# nicht auswertbar (Deployment-Drift Fall 8, 06.08.: vier reale
|
||||
# Squeeze-Trades landeten als setup=NULL, damit zaehlten B4-Monitor
|
||||
# und Abbruchregel NULL Bot-Trades).
|
||||
self._last_rec["setup"] = f"AUTOM15_{want.upper()}"
|
||||
fn = self.trader.open_long if d > 0 else self.trader.open_short
|
||||
err = self._open(fn, want, source="auto_m15")
|
||||
if err:
|
||||
log.warning(f"Auto-M15-Entry fehlgeschlagen: {err}")
|
||||
return
|
||||
self._m15_entry_count += 1
|
||||
log.info(f"AUTO-M15-ENTRY: {want.upper()} auf gruene Karte "
|
||||
f"(Lesart {les}, Level {lvl}) — selbstaendig eroeffnet")
|
||||
except Exception as e:
|
||||
log.warning(f"_check_auto_m15: {e}")
|
||||
|
||||
def _check_pending_fill(self):
|
||||
"""Hat eine von UNS platzierte Pending-Order gefuellt? Dann nachtragen.
|
||||
|
||||
@@ -2161,6 +2264,8 @@ class TradingEngine:
|
||||
if "manual_margin" in st:
|
||||
from core.config import set_manual_margin as _set
|
||||
self._manual_margin = _set(st["manual_margin"] or 0)
|
||||
if "auto_m15" in st:
|
||||
self._auto_m15 = bool(st["auto_m15"])
|
||||
if "cb_remember" in st:
|
||||
self._cb_remember = float(st["cb_remember"] or 8.0)
|
||||
if "cb_limit_pct" in st:
|
||||
@@ -2200,6 +2305,7 @@ class TradingEngine:
|
||||
# 0 = aus. So ueberlebt auch die Hoehe den Neustart.
|
||||
"cb_limit_pct": getattr(self, "_cb_limit_pct", 0.0),
|
||||
"cb_remember": getattr(self, "_cb_remember", 8.0),
|
||||
"auto_m15": getattr(self, "_auto_m15", False),
|
||||
# Kegel-ACI-Skalen (2026-08-08): ohne Persistenz waere
|
||||
# die muehsam erlernte Kalibrierung nach jedem Neustart
|
||||
# weg und liefe von 1,0 neu an. ⚠ JSON-Schluessel sind
|
||||
@@ -4181,6 +4287,7 @@ class TradingEngine:
|
||||
# die Fehlerklasse, fuer die der Linter am 07.08. eingebaut wurde.
|
||||
_m15 = self._m15_setup(market, wave_snap, _cone,
|
||||
self._alignment_cached(), wave_signal)
|
||||
self._last_m15 = _m15 # fuer `_check_auto_m15` im 1-s-Loop
|
||||
self._log_m15_state(_m15, market)
|
||||
self._check_m15_alert(_m15) # Telegram bei Flanke auf GRUEN
|
||||
self._log_cone_check(_cone)
|
||||
@@ -4352,6 +4459,8 @@ class TradingEngine:
|
||||
# ⚠ Eigenes Fenster (ab 01.08.) — NICHT dasselbe wie
|
||||
# `squeeze_monitor.live` (alle Trades). s. `_squeeze_b5_cached`.
|
||||
"squeeze_b5": self._squeeze_b5_cached(),
|
||||
"auto_m15": self._auto_m15,
|
||||
"m15_entry_count": self._m15_entry_count,
|
||||
# Kennzahlen der MANUELLEN Trades für die gleichnamige Karte
|
||||
# (2026-08-04). Rein deskriptiv; ~120 s gecacht, damit der heiße
|
||||
# Snapshot-Pfad nicht je Abruf die DB aggregiert.
|
||||
|
||||
Reference in New Issue
Block a user