Live-Code von Backtest-Skript entkoppelt: core/squeeze_scan.py

core/engine.py (squeeze_monitor) und weekly_review.py importierten
backtest_breakout_squeeze - die Abhaengigkeitsrichtung war verkehrt:
ein Fehler im Backtest konnte den laufenden Bot treffen.

Schwerer wog, WIE die Parameter hineinkamen:

    BQ._N = _SQ_N; BQ._K = _SQ_K

Das mutiert Modul-Globale eines Backtests, wirkt prozessweit und damit auf
jeden anderen Nutzer desselben Moduls im selben Prozess. Die Werte weichen
real ab (Backtest _N=12, live _SQ_N=10).

Geloest ueber core/squeeze_scan.py - Parameter stehen in der Signatur.
backtest_breakout_squeeze.py leitet nur noch weiter, damit es EINE
Implementierung gibt statt zweier (der sim_run/_ema_series-Fehler).

Der Exit ist bewusst NICHT mitrepariert: exit_legacy ist eine bitgenaue
Kopie inkl. seiner Abweichungen vom kanonischen Exit (Trail 1,5 statt 1,0,
kein Lock/Time-Stop/TP, max_hold 288 statt 200). Damit misst der B4-Monitor
gegen einen veralteten Exit - separater, offener Befund. Ihn hier still
mitzuaendern haette die Vergleichsgrundlage verschoben.

Bitgenauigkeit bewiesen (tests/test_squeeze_scan.py): die alte Fassung liegt
eingefroren im Test und laeuft gegen die neue ueber 500 synthetische Reihen
x 3 Multiplikatoren. Ein Vorher/Nachher-Lauf waere ungueltig gewesen - der
Backtest zieht Bars live aus MT5, das Fenster verschiebt sich staendig.

Test selbst per Mutationsprobe geprueft: 5 von 6 eingebauten Fehlern schlagen
an, der sechste (d>0 -> d>=0) ist beweisbar aequivalent, da d nur +-1 ist.

Live-Gegenprobe auf 9000 M5-Bars: n=112, Treffer 44%, OeR +0,178, PF 1,26.

Aktivierung beim naechsten Neustart - bei offener Position kein Neustart fuer
eine verhaltensneutrale Aenderung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-07 07:21:45 +02:00
co-authored by Claude Opus 5
parent a35a0e7006
commit fd3c7f57a5
6 changed files with 398 additions and 51 deletions
+62
View File
@@ -4731,6 +4731,68 @@ Signal-Eingriffe sind gescheitert, und die gemessene Stärke des Users liegt in
AUSWAHL, nicht in einer Regel. Ein Modul, das ihm seine eigene Historie zur aktuellen
Lage zeigt, spielt auf diese Stärke; eines das für ihn einsteigt, ersetzt sie.
## ⚠⚠ LIVE-CODE HING AN EINEM BACKTEST-SKRIPT — behoben 2026-08-07
**Befund:** `core/engine.py` (`squeeze_monitor`) und `weekly_review.py` importierten
**`backtest_breakout_squeeze`**. Die Abhängigkeitsrichtung war damit verkehrt herum:
„Backtests sind nur Dokumentation" stimmte nicht — ein Fehler dort konnte den
laufenden Bot treffen.
⚠ **Der schwerere Teil war nicht der Import, sondern wie die Parameter hineinkamen:**
```python
BQ._N = _SQ_N; BQ._K = _SQ_K # Modul-Globale eines Backtests mutieren
```
Das wirkt **prozessweit** und damit auf jeden anderen Nutzer desselben Moduls im
selben Prozess. Dass die Werte real abweichen, ist keine Theorie: der Backtest-Default
ist `_N=12`, live gilt `_SQ_N=**10**`. Wer das Skript nach dem Monitor-Aufruf im selben
Prozess benutzt hätte, hätte still mit Live- statt Backtest-Parametern gerechnet.
**Gelöst: `core/squeeze_scan.py`**`atr_series` · `exit_legacy` · `scan`, alle
Parameter in der **Signatur** statt in Modul-Globalen. `engine`/`weekly_review` rufen
`core` auf; `backtest_breakout_squeeze.py` leitet nur noch weiter, damit es **eine**
Implementierung gibt statt zweier, die auseinanderdriften (der Fehler, den das Projekt
bei `sim_run`/`_ema_series` — Kopien in ≥6 Skripten — schon einmal gemacht hat).
⚠⚠ **DER EXIT WURDE BEWUSST NICHT MITREPARIERT.** `exit_legacy` ist eine bitgenaue
Kopie inklusive seiner Abweichungen vom kanonischen Live-Exit (`exit_model.LIVE`):
| | Squeeze-Backtest / B4-Monitor | LIVE |
|---|---|---|
| Trail | **1,5** | **1,0** (seit 31.07.) |
| Lock-Phase | keine | ja |
| Time-Stop | keiner | 120 min |
| Initial-TP | keiner | 3,5×ATR |
| max_hold | 288 | 200 |
**Das ist ein FÜNFTES Exit-Modell** neben den drei aus dem Stufe-3-Refactor und dem
kanonischen. Der B4-Monitor („Entry-Edge · Mechanik") misst also gegen einen
**veralteten** Exit. Das hier stillschweigend mitzuändern hätte die Vergleichsgrundlage
des Monitors verschoben, ohne dass es jemand merkt — **offener Befund, eigene
Entscheidung.** ⚠ Beim Umstellen ist die Erwartungsspanne (+0,14…+0,23 ØR) mit
neu zu bestimmen; sie stammt aus Messungen mit genau diesem Exit.
**Bitgenauigkeit BEWIESEN, nicht behauptet** (`tests/test_squeeze_scan.py`, 5 Tests):
die alte Fassung liegt **eingefroren** im Test (wörtlich aus `git show HEAD:…`) und
läuft gegen die neue über **500 synthetische Kursreihen × 3 Multiplikatoren**.
⚠ Ein Vorher/Nachher-Lauf des Backtests wäre **ungültig** gewesen: er zieht seine Bars
live aus MT5, das Fenster verschiebt sich mit jeder Minute — gleiche Zahlen wären
Zufall, verschiedene kein Beleg. Die Reihen wechseln blockweise die Vola, sonst liegt
der ATR immer über oder immer unter `_ATRMIN` und Kompressions-Bedingung, Filter und
Cooldown werden nie durchlaufen. Zusätzlich prüft der Test, dass überhaupt >500
Ausbrüche entstehen — „beide finden nichts" ist kein Nachweis von Gleichheit.
**Der Test wurde selbst geprüft (Mutationsprobe):** 6 gezielte Fehler in
`squeeze_scan.py` eingebaut — Trail 1,5→1,4 · Breakeven 1,3→1,2 · Cooldown +1 Bar ·
Ausbruchs-Level +0,1 % · ATR-Fenster +1 Bar schlagen **alle** an. Der sechste
(`d > 0``d >= 0`) nicht — **kein Test-Loch, sondern beweisbar äquivalent**: `d` ist
im ganzen Pfad nur ±1, die beiden Vergleiche unterscheiden sich allein bei `d == 0`.
⚠ Ein grüner Test ohne Mutationsprobe belegt nichts — dieselbe Fehlerklasse
(„Erfolg melden, wo nichts geprüft wurde") ist am 07.08. viermal aufgetreten.
Live-Gegenprobe auf 9.000 M5-Bars mit den echten Live-Parametern: n=112, Treffer 44 %,
**ØR +0,178, PF 1,26** — im dokumentierten Erwartungsband.
**Aktivierung steht aus:** zum Zeitpunkt des Umbaus lief eine offene Position
(2,47 Lots); ein Neustart hätte ihr 1020 s Trailing/Time-Stop/Notfall-Stop genommen
für eine Änderung, die per Test **nichts** am Verhalten ändert. Greift beim nächsten
regulären Neustart.
## Backtest-Audit 2026-08-04 — rechnen die Skripte noch korrekt?
**Anlass:** User-Frage nach dem `angle=`-Fund in `backtest_auto_signal.py`. Prüfung