Auto-Squeeze-Nachtsperre von 0-7 auf 3-6 Uhr verkuerzt (User-Vorgabe)
Gemessen (backtest_cost_gate.py, Teil 2): es gibt KEINE toten Stunden - alle 24 Stunden sind in beiden Halbjahren positiv, keine ist beidhaelftig negativ. Std 0 ist sogar die staerkste des Tages (OeR +1,48/+1,51) und lag im alten Gate. Jedes Fenster kostet also Ertrag; die Sperre kauft ausschliesslich Beaufsichtigungs-Ruhe. Gewaehlt wurde deshalb nach PREIS, nicht nach Edge: 3-6 ist das guenstigste Fenster mit noch >=4 h Schutz (SigmaR -12,5/-62,9 gegen -42,4/-242,6 bei 0-7 = ~27 %). Freigegeben: 0, 1, 2, 7 Uhr. Die 4-h-Untergrenze ist gesetzt, nicht gemessen. Umsetzung: neues [trading] auto_squeeze_night_hours (Default 3,4,5,6, leer = aus), genutzt von _check_auto_squeeze und _check_auto_signal. _SQUEEZE_NIGHT bleibt als STATISTISCHE Nacht-Definition fuer Entry-Checkliste und B4-Monitor - dort gilt die Kostenfalle weiter und der Altdaten-Vergleich bleibt stabil. 7 Parse-Faelle getestet (Default, fehlender Schluessel, leer, Muell, Rueckwaerts-Kompatibilitaet). Live verifiziert am NEUEN Snapshot-Feld squeeze_night_hours = 3,4,5,6 und am Startup-Log; genau eine Instanz auf 8000. Offen und als Reminder hinterlegt: der Backtest modelliert keine Slippage, und die freigegebenen Stunden liegen in der duennsten Liquiditaet. Nach 15 Squeeze-Trades aus 0/1/2/7 Uhr gegen die Erwartung pruefen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cdee6eced7
commit
1c9bb34095
@@ -346,6 +346,92 @@ def main():
|
||||
print(" waehrend ich schlafe\") ist eine Praeferenz und wird hier NICHT beruehrt.")
|
||||
print()
|
||||
|
||||
# ── TEIL 2: welche Nachtstunden sind WIRKLICH tot? ─────────────────────
|
||||
print("=" * 100)
|
||||
print(" TEIL 2 — WELCHE Nachtstunden tragen den Block? (je Stunde, sequentiell)")
|
||||
print("=" * 100)
|
||||
print(f" {'Std':>3} {'Kosten':>7} | {'n H1':>5} {'OeR H1':>8} {'SigmaR H1':>10}"
|
||||
f" | {'n H2':>5} {'OeR H2':>8} {'SigmaR H2':>10} Urteil")
|
||||
print(" " + "-" * 92)
|
||||
beide_neg = []
|
||||
for s in range(24):
|
||||
k1 = kennzahlen(sequentiell(K, H, L, C, lambda e, s=s: e["stunde"] == s, 0, mid))
|
||||
k2 = kennzahlen(sequentiell(K, H, L, C, lambda e, s=s: e["stunde"] == s, mid, N))
|
||||
ks_ = [e["kosten"] for e in E if e["stunde"] == s]
|
||||
kmed = sorted(ks_)[len(ks_) // 2] if ks_ else float("nan")
|
||||
if not k1 or not k2:
|
||||
continue
|
||||
neg = k1["sr"] < 0 and k2["sr"] < 0
|
||||
if neg:
|
||||
beide_neg.append(s)
|
||||
print(f" {s:>3} {kmed:>7.3f} | {k1['n']:>5} {k1['oer']:>+8.3f} {k1['sr']:>+10.1f}"
|
||||
f" | {k2['n']:>5} {k2['oer']:>+8.3f} {k2['sr']:>+10.1f} "
|
||||
f"{'beide NEGATIV' if neg else ''}")
|
||||
print()
|
||||
print(f" In BEIDEN Haelften negativ: {beide_neg or 'keine'}")
|
||||
print(" ⚠ Diese Liste NICHT direkt als Gate verwenden — 24 Stunden = 24 Tests,")
|
||||
print(" das waere in-sample-zirkulaer (dokumentierter Fehler, backtest_realcosts).")
|
||||
print(" Deshalb unten nur ZUSAMMENHAENGENDE Fenster: ein Fenster hat 1 Freiheits-")
|
||||
print(" grad statt 24 und laesst sich nicht auf das Rauschen zurechtlegen.")
|
||||
print()
|
||||
|
||||
# ── Fenster-Sweep, Regel vorab fixiert ────────────────────────────────
|
||||
print(" ZUSAMMENHAENGENDE NACHT-FENSTER (sequentiell, EIN Slot)")
|
||||
print(" REGEL (vor dem Lauf fixiert): das Fenster muss das heutige 0-7 im SigmaR")
|
||||
print(" in BEIDEN Haelften schlagen. Bei mehreren Treffern gewinnt das LAENGSTE")
|
||||
print(" — der Beaufsichtigungs-Grund hat Wert, der in keiner Zahl steht.")
|
||||
print(f" {'Fenster':<18}{'H1 n WR OeR PF SigmaR':>32}"
|
||||
f" |{'H2 n WR OeR PF SigmaR':>32}")
|
||||
print(" " + "-" * 96)
|
||||
fenster = [("kein Gate", ())]
|
||||
for a in range(0, 8):
|
||||
for b in range(a, 8):
|
||||
fenster.append((f"{a}-{b} Uhr", tuple(range(a, b + 1))))
|
||||
b1, b2 = ergebnis["ohne Gate (Basis)"]
|
||||
zeilen = []
|
||||
for lbl, hh in fenster:
|
||||
if not hh:
|
||||
continue
|
||||
k1 = kennzahlen(sequentiell(K, H, L, C,
|
||||
lambda e, hh=hh: e["stunde"] not in hh, 0, mid))
|
||||
k2 = kennzahlen(sequentiell(K, H, L, C,
|
||||
lambda e, hh=hh: e["stunde"] not in hh, mid, N))
|
||||
if not k1 or not k2:
|
||||
continue
|
||||
p1 = k1["sr"] - b1["sr"]; p2 = k2["sr"] - b2["sr"] # Preis (negativ)
|
||||
nblk = sum(1 for e in E if e["stunde"] in hh)
|
||||
zeilen.append({"lbl": lbl, "hh": hh, "h": len(hh), "p1": p1, "p2": p2,
|
||||
"n": nblk, "je": (p1 + p2) / len(hh)})
|
||||
|
||||
print(" PREIS DER BEAUFSICHTIGUNG — was kostet ein Fenster gegenueber KEINEM Gate?")
|
||||
print(" ⚠ Keine Stunde ist in beiden Haelften negativ. Es gibt also keine")
|
||||
print(" 'toten Stunden' zu streichen — jedes Fenster KOSTET. Die Frage ist")
|
||||
print(" nur, wieviel Schlaf-Schutz man wie teuer einkauft. Das ist eine")
|
||||
print(" PREIS-Minimierung fuer eine Praeferenz, KEINE Edge-Behauptung —")
|
||||
print(" deshalb ist die Auswahl hier auch nicht overfitting-gefaehrdet.")
|
||||
print(f" {'Fenster':<12}{'Std':>4}{'geblockt':>10}{'Preis H1':>10}{'Preis H2':>10}"
|
||||
f"{'SigmaR/Std':>12}")
|
||||
print(" " + "-" * 60)
|
||||
for z in sorted(zeilen, key=lambda z: -z["je"])[:12]:
|
||||
print(f" {z['lbl']:<12}{z['h']:>4}{z['n']:>10}{z['p1']:>+10.1f}"
|
||||
f"{z['p2']:>+10.1f}{z['je']:>+12.1f}")
|
||||
heute = next(z for z in zeilen if z["lbl"] == "0-7 Uhr")
|
||||
print(f" {'... heute:':<12}{heute['h']:>4}{heute['n']:>10}{heute['p1']:>+10.1f}"
|
||||
f"{heute['p2']:>+10.1f}{heute['je']:>+12.1f} <- 0-7 Uhr")
|
||||
print()
|
||||
# Auswahl: guenstigstes Fenster, das noch >=4 Stunden Schlaf-Schutz gibt.
|
||||
# 4 h ist gesetzt, nicht gemessen — darunter waere der Schutzzweck hinfaellig.
|
||||
kand = [z for z in zeilen if z["h"] >= 4]
|
||||
best = max(kand, key=lambda z: z["je"])
|
||||
print(f" => EMPFEHLUNG (>=4 h Schutz, guenstigstes Fenster): **{best['lbl']}**")
|
||||
print(f" Preis H1 {best['p1']:+.1f} / H2 {best['p2']:+.1f} R "
|
||||
f"gegen heute {heute['p1']:+.1f} / {heute['p2']:+.1f}")
|
||||
print(f" = {100*abs(best['p1'])/abs(heute['p1']):.0f} % / "
|
||||
f"{100*abs(best['p2'])/abs(heute['p2']):.0f} % der heutigen Kosten,"
|
||||
f" bei {best['h']} statt 8 Stunden")
|
||||
print(f" freigegeben: {[s for s in range(8) if s not in best['hh']]} Uhr")
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user