From 5925d9a5274c47bd97456ade9c77983f1dd7b226 Mon Sep 17 00:00:00 2001 From: Axel Hocks Date: Thu, 20 Aug 2026 09:00:01 +0200 Subject: [PATCH] Trade-Leiste: TP1/TP2/TP3 + Setup-Block "Entry Zone / SL / TP1-3" in der M15-Karte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-Wunsch, mit einer Vorlage im Format "USOIL BUY SETUP: Entry Zone / Stop Loss / Take Profit 1-3". (1) TRADE-LEISTE — drei Anzeige-Boxen fuer die LAUFENDE Position: TP1 · Level naechstes STEHENDES M30-Level in Trade-Richtung + P(haelt) TP2 · Trailing der Broker-TP, den `core/trailing.py` dynamisch fuehrt TP3 · Kegel Obergrenze des 80-%-Bandes auf 120 min (core/cone.py) Live gegengerechnet: 85.745 (67 % haelt) / 86.634 / 86.153 (trifft 75 %). (2) M15-KARTE — Setup-Block im Format der Vorlage, direkt unter dem Banner: Richtung · Entry Zone (Level ± 0,15xATR) · Stop Loss (2,0xATR_M15) · TP1 (Gegenlevel) · TP2 (3,5xATR) · TP3 (Kegel 120'). Blendet sich aus, wenn kein Veto, keine Zone oder kein ATR vorliegt - aktuell ist genau das der Fall (M30 flach -> kein Veto -> keine erlaubte Richtung), und das ist korrektes Verhalten, kein Fehler. ⚠⚠ DREI LEITPLANKEN, damit daraus keine Prognose wird: - Die RICHTUNG kommt ausschliesslich aus dem VETO (erlaubte Richtung). Die Karte gibt weiterhin KEINE Richtungsprognose ab - die ist ueber 1.071 Live-Episoden als Muenzwurf gemessen (48-51 %). Ohne Veto: kein Block. - Die drei TP sind ANZEIGE, nichts davon geht an den Broker. Ein FESTER TP am Gegenlevel ist der staerkste Gewinner-Kappen-Beleg des Projekts: er drehte den Squeeze von +0,102/+0,108 auf -0,066/-0,004 (backtest_trailing_sr.py). Deshalb steht an TP2 ausdruecklich, dass das Trailing ihn nachfuehrt. - NICHTS wird neu gerechnet - Zonen, ATR und Kegel stehen im Snapshot. Ein zweiter Rechenweg waere die Divergenz-Falle (dreimal zugeschlagen). - Neutral gerahmt, nicht gruen/rot: der Block sagt WO, nicht OB. Die 0,15xATR der Entry Zone sind die im Projekt gemessene "Beruehrung" (dieselbe Schwelle wie `at_level` im S/R-Hinweis), nicht geraten. Reine Frontend-Aenderung (v=195), kein Neustart. node --check, Render-Probe und die volle Pipeline gruen. Co-Authored-By: Claude Opus 5 --- web/app.js | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ web/index.html | 16 ++++++++++-- web/style.css | 13 ++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/web/app.js b/web/app.js index 0a4252b..abbe7ab 100644 --- a/web/app.js +++ b/web/app.js @@ -416,6 +416,45 @@ function renderM15(s, snap) { + "gedeckelt, der Verlust laeuft bis zum Stop. Reine Anzeige."; } + // --- SETUP-BLOCK: Entry Zone · SL · TP1-3 (User-Wunsch 2026-08-20) ------ + // ⚠⚠ Die RICHTUNG kommt aus dem VETO (erlaubte Richtung), NICHT aus einer + // Prognose — die Karte gibt keine ab, und das ist gemessen richtig so + // (1.071 Live-Episoden, 48–51 % Treffer). Der Block beantwortet nur: + // WENN gehandelt wird, zu welchen Preisen. + // ⚠ Nichts wird neu gerechnet — Zonen, ATR und Kegel stehen im Snapshot. + // ⚠ TP1 ist ein LEVEL, kein Auftrag: ein fester TP am Gegenlevel ist der + // staerkste Gewinner-Kappen-Beleg des Projekts (Squeeze +0,102/+0,108 → + // −0,066/−0,004). Deshalb steht bei TP2, dass das Trailing fuehrt. + { + const sb = $streng("m15-setupblock"); + const verb = ((s.bias || {}).verboten || "").toUpperCase(); + const erl = verb === "SHORT" ? "LONG" : verb === "LONG" ? "SHORT" : null; + const zonen = s.zonen || []; + const nah = zonen.slice().sort((a, b) => (a.gap_atr15 ?? 9) - (b.gap_atr15 ?? 9))[0]; + const atr = s.atr_m15 || 0; + if (sb && erl && nah && atr > 0) { + const lg = erl === "LONG"; + const e = nah.level, tol = 0.15 * atr; + const sl = lg ? e - 2.0 * atr : e + 2.0 * atr; + const geg = zonen.find(z => lg ? z.level > e : z.level < e); + const lv = ((snap || {}).cone || {}).levels || []; + const k120 = lv.find(x => x.band === 80 && x.minutes === 120); + const zl2 = [`${lg ? "▲" : "▼"} ${erl} — nur wenn die Kette gruen ist`, + `Entry Zone: ${f(e - tol, 3)} – ${f(e + tol, 3)}`, + `Stop Loss: ${f(sl, 3)} (2,0×ATR_M15)`]; + if (geg) zl2.push(`TP1: ${f(geg.level, 3)} (Level · ` + + `${100 - (geg.p_break ?? 50)} % haelt)`); + zl2.push(`TP2: ${f(lg ? e + 3.5 * atr : e - 3.5 * atr, 3)} ` + + `(3,5×ATR — das Trailing fuehrt ihn nach)`); + if (k120) zl2.push(`TP3: ${f(lg ? k120.hi : k120.lo, 3)} ` + + `(Kegel 120′, trifft ${Math.round(k120.coverage || 0)} %)`); + sb.innerHTML = zl2.join("
"); + sb.hidden = false; + } else if (sb) { + sb.hidden = true; + } + } + // --- 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 @@ -1158,6 +1197,33 @@ function render(d) { // Enter darauf schickt den GERUNDETEN Wert an den Broker — der Stop // verschiebt sich also still um bis zu 0,5 Cent. Bei einem Trail von // 11 Cent (ATR_M5 0,11 in dieser Nacht) sind das 5 % der Distanz. + // --- TP1/TP2/TP3: voraussichtliche Ziele (User-Wunsch 2026-08-20) ----- + // ⚠⚠ REINE ANZEIGE — keines davon wird an den Broker geschickt. Ein FESTER + // TP am Gegenlevel ist im Projekt der staerkste Gewinner-Kappen-Beleg: + // er drehte den Squeeze von +0,102/+0,108 auf −0,066/−0,004 + // (backtest_trailing_sr.py). Die drei Zahlen sind Orientierung, kein + // Auftrag — deshalb Anzeige-Boxen und keine Eingabefelder. + // ⚠ NICHTS wird neu gerechnet: Zonen und Kegel stehen ohnehin im Snapshot. + // Ein zweiter Rechenweg waere die Divergenz-Falle (dreimal zugeschlagen). + { + const lg = p.order_type === 0; + const ep = Number(p.entry_price) || 0; + // TP1 — naechstes STEHENDES Level in Trade-Richtung + const zn = ((d.m15_setup || {}).zonen) || []; + const ziel = zn.find(z => lg ? (z.seite === "res" && z.level > ep) + : (z.seite === "sup" && z.level < ep)); + $("tb-tp1").textContent = ziel + ? `${fmt(ziel.level, 3)} (${100 - (ziel.p_break ?? 50)}% hält)` + : "—"; + // TP2 — der Broker-TP, den das Trailing fuehrt + $("tb-tp2").textContent = p.tp ? fmt(p.tp, 3) : "—"; + // TP3 — Obergrenze des 80-%-Kegels auf 120 min + const lv = ((d.cone || {}).levels) || []; + const k = lv.find(x => x.band === 80 && x.minutes === 120); + $("tb-tp3").textContent = k + ? fmt(lg ? k.hi : k.lo, 3) + (k.coverage ? ` (trifft ${Math.round(k.coverage)}%)` : "") + : "—"; + } if (document.activeElement !== slEl) slEl.value = p.sl ? fmt(p.sl, 3) : ""; if (document.activeElement !== tpEl) tpEl.value = p.tp ? fmt(p.tp, 3) : ""; } else { diff --git a/web/index.html b/web/index.html index 8683d5a..b691fdd 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. --> - + @@ -82,6 +82,12 @@ + + + + + + @@ -116,6 +122,12 @@ wurde im Projekt verworfen, und User-Uebersteuerungen liefen gemessen 68 % WR. Sichtbar machen, nicht bevormunden. -->
+ +
① – ④ Prüfkette @@ -396,6 +408,6 @@
- + diff --git a/web/style.css b/web/style.css index cda47f6..5629260 100644 --- a/web/style.css +++ b/web/style.css @@ -662,3 +662,16 @@ main{padding-bottom:4.1111rem} /* Platz für die fixe Leiste */ filter:saturate(.55) brightness(.85); } .btn.eng-raum .btn-raum{ color:var(--accent); font-weight:700; } + +/* ── M15-Setup-Block: Entry Zone · SL · TP1-3 (2026-08-20) ──────────────── + ⚠ Bewusst NEUTRAL gerahmt, nicht gruen/rot: die Karte gibt keine + Richtungsprognose ab (ueber 1.071 Live-Episoden 48-51 % Treffer). Der Block + sagt nur, ZU WELCHEN PREISEN gehandelt wuerde, wenn die Kette gruen ist. */ +.m15-setup{ + margin:0.4444rem 0; padding:0.5rem 0.6667rem; + border:1px solid var(--line); border-left:3px solid var(--dim); + border-radius:var(--r-sm); background:var(--surface-2); + font-size:0.8889rem; line-height:1.7; +} +.m15-setup[hidden]{display:none} +.m15-setup .dim{color:var(--dim); font-size:0.8rem}