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:
co-authored by
Claude Opus 5
parent
0208101707
commit
97617cd81d
@@ -1945,6 +1945,52 @@ Aktivierung genullt (kein Altwert-Fehlalarm); Erkennung erst ab dem 2. Modify. T
|
||||
v=108. `GET /api/snapshot` ist ohnehin öffentlich/token-frei nutzbar — externe
|
||||
Tools (Shortcuts, Home Assistant, …) können ihn direkt pollen.
|
||||
|
||||
## ⚠ Deployment-Drift — die strukturelle Schwachstelle (2026-07-31)
|
||||
|
||||
**Track B schützt gegen OVERFITTING** (ein Edge existiert gar nicht). Es schützt
|
||||
**nicht** gegen **DEPLOYMENT-DRIFT**: ein real existierender Edge wird unter anderen
|
||||
Bedingungen BETRIEBEN als VALIDIERT. An EINEM Tag wurden drei Fälle gefunden:
|
||||
|
||||
| # | Komponente | Gemessen unter | Betrieben unter | Schaden |
|
||||
|---|---|---|---|---|
|
||||
| 1 | P(break) | Anlauf zu **fixiertem** Level | **dynamisch** gewähltes Level | AUC 0,715 → **0,368** |
|
||||
| 2 | `breakout_k=0,3` | **feste** Zeitebene | TF wechselt 33×/Tag, löscht den Anker | 43 % → **93 % WARTEN** |
|
||||
| 3 | Trailing `mult` | **1,5** | **1,5–3,0** je nach TF | H1 ΣR −249 → **−1367**, Worst −1,50 → −2,50 |
|
||||
|
||||
Keiner wäre durch MEHR Backtesting gefunden worden — die Backtests waren korrekt.
|
||||
**Ursachen (strukturell):** (a) Backtests sind NACHBAUTEN, keine Nutzer des Live-Codes
|
||||
(`sim_run`/`_ema_series`/`_atr_series` liegen in ≥6 Skripten als Kopie); (b) es gibt
|
||||
**Live-only-Gates**, die kein Backtest modelliert (Entry-Raum, EIA, Dead-Hours,
|
||||
News-Blackout, Cooldowns, Startup-Grace); (c) Live-Parameter sind **kontextabhängig**
|
||||
(Trail-mult je TF, SL-ATR fix M15, TF selbst per Heuristik), Backtest-Parameter
|
||||
konstant; (d) es gab **keine Telemetrie über die Entscheidung selbst**.
|
||||
|
||||
**Behebung in 3 Stufen (User-Entscheidung 2026-07-31):**
|
||||
- **Stufe 1 — ERLEDIGT:** `_MULT_BY_TF` auf durchgehend **1,5** und
|
||||
`_MULT_BREAKOUT_ADD` auf **0,0** (`core/trailing.py`) — der einzige gemessene Wert.
|
||||
- **Stufe 2 — ERLEDIGT:** **Entscheidungs-Telemetrie.** (a) Jede Empfehlung loggt
|
||||
jetzt einen maschinenlesbaren **`block_reason`** (`recommendations.block_reason`,
|
||||
DB migriert mit Backup): `deadband · dead_hour · eia · htf_counter · stretch ·
|
||||
min_conf · breakout_pending · entry_room · no_data · stale`; NULL = kein Block.
|
||||
Ohne den war nicht feststellbar, WELCHES Gate die 93 % erzeugt. (b) **`analyze_
|
||||
divergence.py`** hält vier Dinge gegen die Backtest-Erwartung: **A** Signal-Verteilung
|
||||
(Soll ~43 % WARTEN), **B** Gate-Anteile inkl. Kennzeichnung „im Backtest modelliert?",
|
||||
**C** TF-Wechsel-Rate (Soll: Median ≥15 min), **D0** Modell-Kalibrierung
|
||||
(Ø-Vorhersage vs. echte Rate) und **D** Merkmals-Drift gegen `_PB_MU/_SD`.
|
||||
⚠ **Lehre aus dem Bau selbst:** die Merkmals-Drift (D) hätte den realen Fehler
|
||||
**NICHT** gefangen — mom3 lag nur **0,50σ** unter µ, bei Gewicht 1,43 wurden daraus
|
||||
aber −0,71 im Logit (23 % statt 41 %). Deshalb ist **D0 der schärfere Test** und die
|
||||
D-Schwelle auf 0,5σ gesetzt. Erster Lauf nach dem Fix: D0 zeigt **27,0 % vorhergesagt
|
||||
vs. 28,0 % real** (vorher 23 vs 41) — die Reparatur ist damit live bestätigt.
|
||||
- **Stufe 3 — OFFEN (später, einzeln):** geteilter Kern. Den Exit-Simulator EINMAL in
|
||||
`core/exit_model.py` extrahieren und von `trailing.py` UND allen Backtests nutzen
|
||||
lassen — Fall 3 wäre damit unmöglich gewesen. Gegenprüfung: bestehende Backtests
|
||||
müssen danach dieselben Zahlen liefern.
|
||||
|
||||
⚠ **Erwartung: die drei Fälle sind nicht vollständig.** Sie wurden bei gezielter Suche
|
||||
in ~20 min gefunden; die Trefferquote spricht für weitere. `analyze_divergence.py`
|
||||
regelmäßig laufen lassen (Kandidat für den Wochenreport).
|
||||
|
||||
## Ausstehende Messungen — Erinnerung per Timer
|
||||
|
||||
`measurement_reminder.py` + Windows-Task **`OilMeasurementReminder`** (täglich 18:00)
|
||||
|
||||
Reference in New Issue
Block a user