Deployment-Drift: Stufe 1 (Trail-mult) + Stufe 2 (Entscheidungs-Telemetrie)

Behebt die strukturelle Schwachstelle, die heute dreimal zugeschlagen hat:
Komponenten werden unter anderen Bedingungen BETRIEBEN als VALIDIERT.
Track B schuetzt gegen Overfitting, nicht gegen Deployment-Drift.

STUFE 1 (core/trailing.py): _MULT_BY_TF durchgehend 1,5 (vorher M15 2,0 /
M30 2,5 / H1 3,0) und _MULT_BREAKOUT_ADD 0,5 -> 0,0. Die Staffelung war nie
gemessen; backtest_trailing.py validiert nur 1,5 und die breiteren Werte
sind dort messbar schlechter (80k Bars, 2 Halbjahre):
    mult 1,5  H1 SigmaR  -249 · H2 +1252 · Worst -1,50
    mult 2,0  H1 SigmaR  -412 · H2 +1187 · Worst -2,00
    mult 2,5  H1 SigmaR -1367 · H2 +1450 · Worst -2,50
Auf M30 fuhr der Bot also 5,5x schlechteres H1 und einen 67 % groesseren
Einzelverlust; bei Breakouts waren es 3,0 - nie getestet. Relevant, weil die
TF-Heuristik oft auf M15/M30 landet (31.07.: 19 von 33 Phasen).

STUFE 2a (wave_rec/history/engine): jede Empfehlung loggt einen
maschinenlesbaren block_reason - deadband, dead_hour, eia, htf_counter,
stretch, min_conf, breakout_pending, entry_room, no_data, stale. DB migriert
(Backup angelegt). Ohne den war nicht feststellbar, WELCHES der Gates die
93 % WARTEN erzeugt (Backtest-Erwartung ~43 %).

STUFE 2b (analyze_divergence.py, NEU): haelt vier Dinge gegen die
Backtest-Erwartung - A Signal-Verteilung, B Gate-Anteile inkl.
"im Backtest modelliert?", C TF-Wechsel-Rate, D0 Modell-Kalibrierung,
D Merkmals-Drift gegen _PB_MU/_SD.

LEHRE AUS DEM BAU SELBST: die Merkmals-Drift (D) haette den realen Fehler
NICHT gefangen - mom3 lag nur 0,50 Sigma unter mu, bei Gewicht 1,43 wurden
daraus aber -0,71 im Logit (23 % statt 41 % vorhergesagt). Deshalb ist D0
der schaerfere Test und die D-Schwelle auf 0,5 Sigma gesetzt.

Erster Lauf nach dem Fix bestaetigt das Nachtraining live:
D0 = 27,0 % vorhergesagt vs 28,0 % real (vorher 23 vs 41).

Stufe 3 (geteilter Exit-Kern) bleibt offen, spaeter und einzeln.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-07-31 12:54:34 +02:00
co-authored by Claude Opus 5
parent 0208101707
commit 97617cd81d
6 changed files with 322 additions and 17 deletions
+12 -5
View File
@@ -85,7 +85,13 @@ SCHEMA = [
setup TEXT,
regime TEXT,
rsi REAL,
news_score REAL
news_score REAL,
-- Maschinenlesbarer Grund für WARTEN (Stufe-2-Telemetrie 2026-07-31):
-- deadband · dead_hour · eia · htf_counter · stretch · min_conf ·
-- breakout_pending · entry_room · no_data · stale. NULL = kein Block.
-- Ohne den war live nicht feststellbar, WELCHES Gate die 93 % WARTEN
-- erzeugt (Backtest-Erwartung ~43 %).
block_reason TEXT
)
""",
"""
@@ -340,7 +346,8 @@ class HistoryLogger:
setup: str | None = None,
regime: str | None = None,
rsi: float | None = None,
news_score: float | None = None):
news_score: float | None = None,
block: str | None = None):
"""
Empfehlungs-Logging mit Throttling: nur jede N Sekunden, um die DB
nicht mit identischen Snapshots zu fluten.
@@ -355,13 +362,13 @@ class HistoryLogger:
(timestamp, signal, score, conf_pct,
angle_m5, angle_m15, angle_m30, angle_h1,
reversal, ai_sentiment, ai_confidence,
setup, regime, rsi, news_score)
VALUES (?,?,?,?, ?,?,?,?, ?,?,?, ?,?,?,?)
setup, regime, rsi, news_score, block_reason)
VALUES (?,?,?,?, ?,?,?,?, ?,?,?, ?,?,?,?,?)
""", (now, signal, score, conf_pct,
angles.get("M5"), angles.get("M15"),
angles.get("M30"), angles.get("H1"),
reversal, ai_sentiment, ai_confidence,
setup, regime, rsi, news_score))
setup, regime, rsi, news_score, block))
conn.commit()
def log_signal(self, *, signal_type: str, direction: str,