1) CIRCUIT-BREAKER SCHARF -- daily_loss_limit_pct 0 -> 8. Live verifiziert:
enabled=True, limit_eur 89,44. Steht nicht in runtime_state.json, die ini
greift direkt. Begruendung: MaxDD 82,8 % auf dem gemessenen IST-Pfad,
schlechtester Einzeltrade -381 EUR.
2) B5-DEADLOCK RECHNERISCH AUFGELOEST -- die Regel ist ENTSCHIEDEN, nicht
vertagt. Stand 11/20: Verhaeltnis 0,14 (Latte 1,0), PF 0,39 (Latte 1,0).
Was die 9 Rest-Trades leisten muessten:
9/0 Gewinner -> 165,72 EUR je Trade = 12,2x der bisherige Schnitt
7/2 -> 186,17 EUR
5/4 -> 222,99 EUR
Der groesste Squeeze-Gewinn des Zeitraums war 77,34 EUR -- selbst der beste
Fall verlangt 2,1x den Rekord, neunmal in Folge. Latte nicht mehr erreichbar.
auto_squeeze bleibt FALSE. Wiederaufnahme waere eine NEUE Entscheidung mit
NEUER, vorab fixierter Latte.
3) core/kontrolle.py -- Kontroll-Fixture mit den Referenzwerten. Bricht bewusst
NICHT ab: ein Backtest darf abweichen, er muss es nur wissen und sagen.
4) core/live_config.py -- EINE Quelle der Live-Parameter (ini + runtime_state in
der Vorrangfolge des Engine-Starts). Dritte Instanz derselben Fehlerklasse:
ATRMIN_STD 0,12 statt 0,06, fehlendes set_entry_room, nachgebauter Cluster.
5) stichprobe.paarweise()/zeig_paarweise() -- gepaarter Vergleich. Anlass:
trail_start sah sequentiell besser aus, gepaart kippte das Vorzeichen
(Selektions- statt Exit-Effekt). Selbsttest in drei Richtungen bestanden.
6) tools/check_konstanten.py -- Waechter fuer veraltete Zahlen.
Erster Lauf: zwei Befunde, BEIDE Fehler in meiner eigenen Ableitung (Margin
aus Balance geschaetzt statt vom Broker gelesen; Elliott ohne
Gueltigkeitsfenster gezaehlt). Beide korrigiert.
Danach ein ECHTER Fund: meine am 13.08. notierten "~405 EUR/Lot" sind falsch,
der exakte Broker-Wert ist 712,84 -- die urspruenglich notierten 670 lagen
naeher als meine Korrektur. Lehre: eine abgeleitete Zahl ist keine gemessene.
Stand jetzt 0 Befunde.
7) Puls-Waechter bedingungs-bewusst: PULS traegt je Zeile die Vorbedingung,
bedingte Tabellen erscheinen als Hinweis statt als Ausfall. 0 Zeilen bleibt
IMMER ein Befund (der rec_outcomes-Fall). Grund: ein Waechter mit
Fehlalarmen wird ignoriert -- so ist der Divergenz-Waechter verstummt.
Pipeline gruen (85 Tests), Deployment ueber deploy.py --feld circuit_breaker
verifiziert, genau eine Instanz je Port.
Nicht angefasst: Sizing (User-Entscheidung) und die 44 Backtests mit eigener
Exit-Kopie (Migrations-Regel).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
96 lines
4.2 KiB
Python
96 lines
4.2 KiB
Python
"""KONTROLL-FIXTURE: ein Backtest muss die Referenz reproduzieren, BEVOR er berichtet.
|
||
|
||
⚠⚠ WARUM ES DAS GIBT (2026-08-13). Zwei an einem Tag gebaute Messungen konnten
|
||
den dokumentierten Squeeze-Referenzwert (+0,124/+0,292, `backtest_squeeze_
|
||
touchfill.py`) NICHT reproduzieren — sie kamen auf −0,151/−0,079 bei einem
|
||
Drittel der Trades. Beide Ergebnisse mussten deshalb auf den **relativen**
|
||
Vergleich beschränkt werden; die absolute Aussage war nicht führbar. Und es
|
||
blieb offen, ob der dokumentierte Wert oder die neue Pipeline danebenliegt.
|
||
|
||
`backtest_verworfene_v2.py` macht es vorbildlich von Hand („✅ Die Kontrolle
|
||
reproduziert … Pipeline in Ordnung"). Hier ist dasselbe als geteilte Funktion,
|
||
damit es niemand vergisst.
|
||
|
||
from core.kontrolle import pruefe_squeeze
|
||
ok = pruefe_squeeze(h1_oer, h2_oer, n_h1, n_h2) # meldet und gibt bool
|
||
|
||
⚠ Es wird NICHT abgebrochen. Ein Backtest darf von der Referenz abweichen — er
|
||
muss es nur WISSEN und sagen. Ein harter Abbruch würde legitime Varianten
|
||
(andere Fill-Annahme, anderer Exit) unmöglich machen; eine stille Abweichung
|
||
dagegen erzeugt genau die Fehlschlüsse, die hier vermieden werden sollen.
|
||
|
||
⚠ Die Referenzen sind MESSWERTE, keine Wunschzahlen. Wer sie ändert, muss die
|
||
Quelle nennen — sonst wandert die Latte mit dem Ergebnis.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class Referenz:
|
||
name: str
|
||
quelle: str
|
||
h1: float
|
||
h2: float
|
||
n_h1: int
|
||
n_h2: int
|
||
toleranz: float = 0.06 # ØR-Abstand, ab dem gewarnt wird
|
||
|
||
|
||
# ── Die dokumentierten Referenzwerte des Projekts ────────────────────────────
|
||
SQUEEZE_TOUCHFILL = Referenz(
|
||
name="Squeeze · ruhende Order am Level, Fill bei Beruehrung",
|
||
quelle="backtest_squeeze_touchfill.py (2026-08-06)",
|
||
h1=+0.124, h2=+0.292, n_h1=1092, n_h2=1807)
|
||
|
||
SQUEEZE_CLOSEBRUCH = Referenz(
|
||
name="Squeeze · Fill bei Close-Bruch (die OPTIMISTISCHE Annahme)",
|
||
quelle="backtest_squeeze_entry.py (2026-08-05)",
|
||
h1=+0.456, h2=+0.611, n_h1=801, n_h2=1280)
|
||
|
||
SQUEEZE_MARKT = Referenz(
|
||
name="Squeeze · Markt-Einstieg am Bar-Close",
|
||
quelle="backtest_squeeze_entry.py (2026-08-05)",
|
||
h1=-0.158, h2=-0.006, n_h1=801, n_h2=1280)
|
||
|
||
|
||
def pruefe(ref: Referenz, h1: float, h2: float,
|
||
n_h1: int | None = None, n_h2: int | None = None,
|
||
still: bool = False) -> bool:
|
||
"""Reproduziert der Lauf die Referenz? Meldet den Befund, gibt bool zurueck."""
|
||
d1, d2 = abs(h1 - ref.h1), abs(h2 - ref.h2)
|
||
ok = d1 <= ref.toleranz and d2 <= ref.toleranz
|
||
if still:
|
||
return ok
|
||
print(f"\n ── KONTROLLE: {ref.name}")
|
||
print(f" Referenz {ref.quelle}")
|
||
print(f" erwartet H1 {ref.h1:+.3f} · H2 {ref.h2:+.3f}"
|
||
f" (n {ref.n_h1}/{ref.n_h2})")
|
||
n_txt = "" if n_h1 is None else f" (n {n_h1}/{n_h2})"
|
||
print(f" gemessen H1 {h1:+.3f} · H2 {h2:+.3f}{n_txt}")
|
||
print(f" Abstand H1 {d1:.3f} · H2 {d2:.3f} (Toleranz {ref.toleranz})")
|
||
if ok:
|
||
print(" ✅ reproduziert — die Pipeline ist in Ordnung, ABSOLUTWERTE "
|
||
"sind belastbar.")
|
||
else:
|
||
print(" ❌ WEICHT AB. Dann gilt:")
|
||
print(" · der RELATIVE Vergleich innerhalb dieses Laufs bleibt gueltig,")
|
||
print(" solange alle Varianten dieselbe Entry-Liste benutzen;")
|
||
print(" · die ABSOLUTWERTE sind es NICHT — sie duerfen nicht als")
|
||
print(" Ertragsaussage berichtet werden.")
|
||
if n_h1 is not None and (n_h1 < ref.n_h1 * 0.6 or n_h1 > ref.n_h1 * 1.6):
|
||
print(f" · ⚠ auch die Trade-ZAHL weicht stark ab ({n_h1} gegen "
|
||
f"{ref.n_h1}) — meist ein anderer Filter (ATR-Floor, Cooldown,")
|
||
print(" Slot-Behandlung), nicht der Markt.")
|
||
return ok
|
||
|
||
|
||
def pruefe_squeeze(h1: float, h2: float, n_h1=None, n_h2=None,
|
||
variante: str = "touchfill") -> bool:
|
||
"""Bequemer Aufruf fuer die haeufigste Kontrolle."""
|
||
ref = {"touchfill": SQUEEZE_TOUCHFILL,
|
||
"closebruch": SQUEEZE_CLOSEBRUCH,
|
||
"markt": SQUEEZE_MARKT}[variante]
|
||
return pruefe(ref, h1, h2, n_h1, n_h2)
|