From 7915e171d04b1011367ce38e9d07543a6a21caeb Mon Sep 17 00:00:00 2001 From: Axel Hocks Date: Wed, 19 Aug 2026 19:17:18 +0200 Subject: [PATCH] M5-Kontextzeile in der M15-Karte statt einer eigenen M5-Setup-Karte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User fragte nach einer M1- oder M5-Setup-Karte und hat der hier gebauten Variante zugestimmt: eine reine ZUSTANDS-Zeile, ohne Richtung und ohne Banner. WARUM KEINE ZWEITE KARTE - und diesmal entscheidet eine frische Messung, nicht eine Meinung. Die entkoppelte Selbstmessung der BESTEHENDEN Karte steht bei n=342 (gruen + gerichtet, ab dem Hysterese-Stichtag 12.08.): 30 min 53,5 % KI [48,2 .. 58,8] -> enthaelt 50 % 60 min 49,3 % KI [44,0 .. 54,5] -> enthaelt 50 %, liegt DARUNTER Am 12.08. war die Bedingung fuer ein Ja VORAB fixiert worden: ">=350 Faelle, Trefferquote ueber 50 %, KI ohne die 50". Die Stichprobe ist jetzt da, die Bedingung ist NICHT erfuellt. Das ist kein "noch zu wenig Daten" mehr. Dazu die Messung vom 13.08.: als Handelsregel faellt die Karte durch (backtest_m15_auto.py, OeR -0,162/-0,094, beide KI ohne Null, schlechter als die HTF-Richtung UND schlechter als ihr eigenes Gegenteil). M1 scheitert zusaetzlich an der Arithmetik: Spread/ATR Median 0,319 gegen 0,193 (M5) und 0,104 (M15). Feiner aufloesen macht die EINZIGE gemessene Staerke der M15-Karte - die Kosten - monoton schlechter. Um 01:00 ist der Spread 1,051xATR_M1, also groesser als die mittlere Kerze; und die M1-Historie ist bei 80 Tagen gedeckelt, zwei Stichproben laegen im selben Regime. GEBAUT ist deshalb Zustand ohne Urteil: Squeeze-Lage (armiert/Ausbruch/keine Kompression + Box), Kosten in xATR_M5 mit den Schwellen aus backtest_realcosts.py (Median 0,193, ab 0,32 Kostenfalle) und der ATR. Der M5-RAUM wird bewusst NICHT wiederholt - Gate 3b rechnet ohnehin auf M5. ⚠ NUR ZUSAMMENGESETZT, nichts neu gerechnet: wave.squeeze und bid/ask/ATR_M5 stehen im Snapshot ohnehin. Ein zweiter Rechenweg war der Fehler des Konsens-Pfeils (komplettes zweites _verdict im 5-s-Takt) und ist die Quelle jeder Divergenz zwischen Karte und Chart. ⚠ Kein Verdict-Gewicht, kein Trade-Trigger, keine Farbampel - dieselbe Zurueckhaltung wie bei der Kerzen-Anatomie und der Ueberdehnungs-Anzeige. Live verifiziert: "M5 · keine Kompression (Box 3.52xATR) · Kosten 0.15xATR_M5 guenstig · ATR 0.165". Deploy ueber tools/deploy.py --feld m15_setup.m5 (Punktpfad), alle 5 Schritte gruen. Co-Authored-By: Claude Opus 5 --- core/engine.py | 34 ++++++++++++++++++++++++++++++++++ web/app.js | 28 ++++++++++++++++++++++++++++ web/index.html | 5 +++-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/core/engine.py b/core/engine.py index f720d62..c99034b 100644 --- a/core/engine.py +++ b/core/engine.py @@ -5006,6 +5006,40 @@ class TradingEngine: "conf_pct": wsig.get("conf_pct"), "raum": raum} + # ── 3c) M5-KONTEXT — reine ANZEIGE, KEINE Richtung, KEIN Banner + # (User-Entscheidung 2026-08-19 gegen eine eigene M5-Karte). + # ⚠⚠ Warum KEINE zweite Setup-Karte: die entkoppelte Selbstmessung + # dieser Karte steht bei n=342 auf 53,5 % [48,2 .. 58,8] (30 min) und + # 49,3 % (60 min) — die am 12.08. VORAB fixierte Bedingung ("bei + # >=350 Faellen ueber 50 % UND KI ohne die 50") ist damit bei + # vorhandener Stichprobe NICHT erfuellt. Dazu faellt die Karte als + # Handelsregel durch (`backtest_m15_auto.py`: OeR -0,162/-0,094, + # beide KI ohne Null). Eine zweite Karte derselben Bauart wuerde ein + # als Signal gemessen NEGATIVES Muster vervielfachen — und die + # Veto->Richtung-Falle, die in EINER Woche dreimal zuschlug, auf eine + # zweite Flaeche ausdehnen. + # ⚠ Deshalb bewusst nur ZUSTAND, kein Urteil: Squeeze-Lage, Kosten, + # ATR. Der M5-RAUM steht bereits in `motor.raum` (Gate 3b rechnet + # ohnehin auf M5) und wird hier NICHT wiederholt. + # ⚠ NUR ZUSAMMENGESETZT, nichts neu gerechnet — `wave.squeeze` und + # `cost_ratio` stehen im Snapshot ohnehin. Ein zweiter Rechenweg war + # der Fehler des Konsens-Pfeils (komplettes zweites `_verdict` im + # 5-s-Takt) und die Quelle jeder Divergenz zwischen Karte und Chart. + try: + _sq = (wave_snap or {}).get("squeeze") or {} + _atr5 = ((wave_snap or {}).get("pb_feats") or {}).get("atr") + out["m5"] = { + "squeeze": _sq.get("state"), + "squeeze_dir": _sq.get("dir"), + "box_atr": _sq.get("box_atr"), + "atr": _atr5, + # Spread/ATR_M5 — Schwellen aus `backtest_realcosts.py`: + # Median 0,193 · ab 0,32 die dokumentierte Kostenfalle. + "kosten": (round((ask - bid) / _atr5, 3) + if (bid and ask and _atr5 and _atr5 > 0) else None)} + except Exception: + out["m5"] = None + # ── 4) REICHWEITE — der Kegel (kalibriert: 80 %-Band trifft 77 %) lv = (cone or {}).get("levels") or [] b80 = [x for x in lv if x.get("band") == 80] diff --git a/web/app.js b/web/app.js index 48e0689..f8011a5 100644 --- a/web/app.js +++ b/web/app.js @@ -364,6 +364,34 @@ function renderM15(s) { + "gedeckelt, der Verlust laeuft bis zum Stop. Reine Anzeige."; } + // --- M5-Kontext: reine ZUSTANDS-Zeile, keine Richtung, kein Banner ------ + // Bewusst KEINE eigene M5-Karte (User-Entscheidung 19.08.): die entkoppelte + // Selbstmessung dieser Karte steht bei n=342 auf 53,5 % [48,2 .. 58,8] und + // schliesst die 50 nicht aus; als Handelsregel faellt sie durch. Hier steht + // deshalb nur, WIE der M5-Markt gerade aussieht -- ohne Urteil. + const m5El = $("m15-m5"); + const m5 = s.m5; + if (m5) { + const t = []; + if (m5.squeeze === "active") { + t.push(`Squeeze AUSBRUCH ${m5.squeeze_dir || ""}`.trim()); + } else if (m5.squeeze === "armed") { + t.push("Squeeze armiert" + (m5.box_atr != null ? ` (Box ${m5.box_atr}×ATR)` : "")); + } else { + t.push("keine Kompression" + + (m5.box_atr != null ? ` (Box ${m5.box_atr}×ATR)` : "")); + } + if (m5.kosten != null) { + // Schwellen aus backtest_realcosts.py: Median 0,193 - ab 0,32 Kostenfalle. + const k = m5.kosten; + t.push(`Kosten ${k.toFixed(2)}×ATR_M5 ${k <= 0.20 ? "günstig" : k < 0.32 ? "normal" : "⚠ teuer"}`); + } + if (m5.atr != null) t.push(`ATR ${Number(m5.atr).toFixed(3)}`); + m5El.textContent = "M5 · " + t.join(" · "); + } else { + m5El.textContent = "M5 · —"; + } + const moEl = $("m15-motor"); const seite = (o, lbl) => { if (!o) return null; diff --git a/web/index.html b/web/index.html index b6822ba..4e30886 100644 --- a/web/index.html +++ b/web/index.html @@ -12,7 +12,7 @@ ⚠ LOKAL eingebunden, kein CDN: die PWA laeuft ueber WireGuard und muss offline funktionieren. --> - + @@ -122,6 +122,7 @@ gemessen, aber ueber verschiedene Trades. Diese Zeile schliesst die Luecke. REINE ANZEIGE, blockt nichts. -->
+