Gesamtempfehlung: nur noch Module mit Stimmrecht · Tooltips ueberall (v=147)

· Modul-Chips: neues `used`-Flag in _verdict.add(). used=False = dauerhaft
  entmachtet (Elliott, Orderbuch — beide heute gemessen ohne Inhalt), das
  Frontend filtert sie aus. ⚠ Sie bleiben im Snapshot und in verdict_votes:
  log_verdict_votes speist daraus die Telemetrie und die 25.000-Verdict-Messung
  braucht die Reihe weiter. Ausgeblendet wird die Anzeige, nicht die Messung.
  Module mit weight=0 aus SITUATIVER Stille (Welle bei WARTEN, Squeeze ohne
  Ausbruch) bleiben sichtbar.
· #vd-note (Muenzwurf-Hinweistext) entfernt, samt CSS. Die Aussage steht
  weiter im Karten-Tooltip.
· Tooltips auf allen Dashboard-Anzeigen (59 title-Attribute): Karten,
  Header-Boxen, Trade-Leiste, Anzeige-Elemente. Wo eine Messung existiert,
  steht sie drin. Gesetzt ueber set_tooltips.py — idempotent, ergaenzt nur
  fehlende title=.

Verifiziert: keine Anzeige mehr ohne Tooltip, keine doppelten IDs, Tag-Balance
ok, v=147 ausgeliefert, Elliott/Orderbuch used=False, eine Instanz auf 8000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-06 23:46:31 +02:00
co-authored by Claude Opus 5
parent 38b493de35
commit caa937f87d
6 changed files with 189 additions and 80 deletions
+19 -1
View File
@@ -3744,7 +3744,25 @@ dort bereits nachvalidiert, ØR +0,305.) **Eine** Oberfläche:
machte daraus ein wortloses `None`. Danach hätte er den **Trend-Loop 7 s machte daraus ein wortloses `None`. Danach hätte er den **Trend-Loop 7 s
blockiert** → läuft jetzt im **Daemon-Thread**, wie der Wirtschaftskalender und blockiert** → läuft jetzt im **Daemon-Thread**, wie der Wirtschaftskalender und
aus demselben Grund. aus demselben Grund.
- Asset-Version aktuell **v=145** (in `web/index.html` hochzählen, siehe Workflows). - **Gesamtempfehlung aufgeräumt + Tooltips überall (User-Vorgabe 2026-08-06,
v=147):**
· **Nur noch Module MIT Stimmrecht als Chip.** `_verdict.add()` hat ein
**`used`**-Flag; `used=False` heisst *dauerhaft* entmachtet (Elliott, Orderbuch —
beide heute gemessen ohne Inhalt), das Frontend filtert sie aus.
**Sie bleiben im Snapshot und in `verdict_votes`**`log_verdict_votes` speist
daraus die Telemetrie, und die 25.000-Verdict-Messung braucht die Reihe weiter.
Ausgeblendet wird die Anzeige, nicht die Messung.
⚠ Module mit `weight=0` aus **situativer** Stille (Welle bei WARTEN, Squeeze ohne
Ausbruch) bleiben sichtbar — die sprechen wieder.
· **`#vd-note` entfernt** (der Münzwurf-Hinweistext) samt CSS. Die Aussage steht
weiter im Tooltip der Karte und in dieser Datei.
· **Tooltips auf allen Dashboard-Anzeigen** (59 `title`-Attribute): Karten-
Überschriften, Header-Boxen, Trade-Leiste und die Anzeige-Elemente. Wo eine
Messung existiert, steht sie im Tooltip (z. B. Kerzen-Anatomie: „Lehrbuch-Lesart
gemessen INVERTIERT"; Bounce: „~50 % Trefferquote, KEIN Signal"). Gesetzt über
`set_tooltips.py`**idempotent**, ergänzt nur fehlende `title=`, damit ein
erneuter Lauf nichts überschreibt.
- Asset-Version aktuell **v=147** (in `web/index.html` hochzählen, siehe Workflows).
Schriftgrößen 2026-07-24 global **+4px** (2× je +2px auf User-Wunsch; Body-Basis Schriftgrößen 2026-07-24 global **+4px** (2× je +2px auf User-Wunsch; Body-Basis
14→18px). ⚠ Betrifft in `style.css` sowohl `font-size:Npx` (71×) ALS AUCH die 14→18px). ⚠ Betrifft in `style.css` sowohl `font-size:Npx` (71×) ALS AUCH die
`font:<weight> Npx/…`-**Shorthand** (3×: `.ms-chip`/`.ms-bos-lbl`/`.sqm-badge` `font:<weight> Npx/…`-**Shorthand** (3×: `.ms-chip`/`.ms-bos-lbl`/`.sqm-badge`
+13 -5
View File
@@ -2835,9 +2835,17 @@ class TradingEngine:
bid = (market or {}).get("bid") bid = (market or {}).get("bid")
votes = [] votes = []
def add(name, vote, weight, detail): def add(name, vote, weight, detail, used=True):
votes.append({"name": name, "vote": int(vote), """`used=False` = das Modul hat DAUERHAFT kein Stimmrecht (gemessen
"weight": weight, "detail": detail}) ohne Inhalt) und wird im Dashboard NICHT mehr als Chip gezeigt.
⚠ Es bleibt trotzdem in `votes` — `log_verdict_votes` speist daraus
die Telemetrie, und die 25.000-Verdict-Messung braucht die Reihe
weiter. Ausgeblendet wird nur die Anzeige, nicht die Messung.
Nicht zu verwechseln mit `weight=0` aus SITUATIVER Stille (Welle bei
WARTEN, Squeeze ohne Ausbruch): die sprechen zeitweise und bleiben
sichtbar."""
votes.append({"name": name, "vote": int(vote), "weight": weight,
"detail": detail, "used": bool(used)})
# 1) Welle — primär (validierter Edge). ⚠ Bei WARTEN hat sie KEINE Aussage # 1) Welle — primär (validierter Edge). ⚠ Bei WARTEN hat sie KEINE Aussage
# → Gewicht 0 (Fix 2026-07-30). Vorher stand w=3,0 permanent im Nenner und # → Gewicht 0 (Fix 2026-07-30). Vorher stand w=3,0 permanent im Nenner und
@@ -2910,7 +2918,7 @@ class TradingEngine:
# ⚠ Reine ANZEIGE-Änderung: die Order steuert die Welle über die # ⚠ Reine ANZEIGE-Änderung: die Order steuert die Welle über die
# Headline, nicht der Konsens. Zurück: `ew = 1.0 if ev != 0 else 0.0`. # Headline, nicht der Konsens. Zurück: `ew = 1.0 if ev != 0 else 0.0`.
ew = 0.0 ew = 0.0
add("Elliott", ev, ew, edet) add("Elliott", ev, ew, edet, used=False)
# 7) Squeeze-Breakout — Event-Signal: stimmt NUR bei `active` mit (dann 2,0, # 7) Squeeze-Breakout — Event-Signal: stimmt NUR bei `active` mit (dann 2,0,
# gemessen 2-Stichproben-positiv, unter der Welle=3,0). armed/keine → Gewicht 0 # gemessen 2-Stichproben-positiv, unter der Welle=3,0). armed/keine → Gewicht 0
@@ -3012,7 +3020,7 @@ class TradingEngine:
ldet = f"{tr['dir']} {tr.get('slope_per_h', 0):+.2f}$/h" ldet = f"{tr['dir']} {tr.get('slope_per_h', 0):+.2f}$/h"
except Exception: except Exception:
pass pass
add("Orderbuch", ov, ow, odet) add("Orderbuch", ov, ow, odet, used=False)
add("Liq-Trend", lv, lw, ldet) add("Liq-Trend", lv, lw, ldet)
# Bias nur über stimmberechtigte Module (weight>0); agree/total = wie viele # Bias nur über stimmberechtigte Module (weight>0); agree/total = wie viele
+95
View File
@@ -0,0 +1,95 @@
"""Setzt Tooltips (title=) auf alle Dashboard-Anzeigen. Idempotent."""
import pathlib
import re
P = pathlib.Path(r"c:\Users\ah\Downloads\tradingrobot\web\index.html")
t = P.read_text(encoding="utf-8")
KARTEN = {
"trade-bar": "Der aktuell offene Trade. SL, TP und die Close-Schwellen sind hier direkt editierbar — Enter oder Verlassen des Feldes sendet.",
"card-verdict": "Aggregation aller Module zu einer Empfehlung. Die HEADLINE (Welle) steuert die Order, alles darunter ist Konsens-Anzeige. Gemessen an 1.071 Live-Episoden trifft die Richtung zu 4851 % — die Karte taugt als Veto (gegen das Signal zu handeln kostet gemessen 6,60 € je Lot), nicht als Prognose.",
"card-pos": "Live-Meldungen zum laufenden Trade und zur Marktlage: Squeeze, Überdehnung, S/R-Nähe, News- und Kalender-Konflikte, Hyperliquid-Kontext.",
"card-trail": "Zustand des Trailing-Stops (Phase, aktueller SL, High-Water). Ausgeblendet — das Trailing läuft im Hintergrund weiter.",
"card-stats-live": "Kompakte Bilanz über Woche und Gesamt. Verhältnis = Ø-Gewinn geteilt durch Ø-Verlust; unter 1 heißt, die Verlierer sind größer als die Gewinner.",
"card-agent": "Einschätzung des KI-Copiloten (LLM). Stimmt mit Gewicht 1,0 mit, wenn er eine Richtung nennt — bei NEUTRAL zählt er nicht. Als Prognose nicht belegt.",
"card-patterns": "Mechanisch erkannte Chartmuster auf M30 mit Trigger und Kursziel. Gewicht 0,25. Die Ziel-Trefferquote liegt gemessen nur bei 1338 % — Kontext, keine Vorhersage.",
"card-structure": "Price-Action-Struktur auf M30: Swing-Folge, letzter Bruch (BOS) und Regressionskanal. Reine Anzeige — als Signal über alle Zeitebenen gemessen und verworfen.",
"card-candles": "Kerzengröße, Dochte und Volumen der letzten M5-Kerzen. Reine Anzeige und bewusst neutral gefärbt: die Lehrbuch-Lesart ist hier gemessen INVERTIERT — der Kurs läuft nach einer Klimax-Kerze eher GEGEN sie.",
"card-manual": "Deine eigenen manuellen Trades im Vergleich zum Bot, aufgeteilt nach Signal-Deckung. Rein deskriptiv.",
"card-trades": "Die zuletzt geschlossenen Trades mit Ergebnis und Schließgrund.",
"card-gaps": "Offene Kurslücken des Jahres. Vakuum = echte Lücke zwischen den Tagesspannen (fließt als S/R in die Konfidenz ein), Eröffnung = Schluss-zu-Eröffnung (reine Anzeige).",
}
HDR = {
"BALANCE": "Kontostand ohne die offene Position.",
"TAG P/L": "Realisiertes Ergebnis von heute. Brutto — die Quellensteuer wird größtenteils erstattet und ist hier nicht abgezogen.",
"EQUITY": "Kontostand einschließlich der offenen Position.",
"PEPPERSTONE KURS": "Der Kurs, zu dem tatsächlich gehandelt wird. Steht er länger als 3 Minuten still, gilt der Markt als geschlossen und das Label zeigt ZU.",
"HYPERLIQUID KURS": "Roher Kurs des Hyperliquid-Öl-Perps — läuft 24/7, auch wenn Pepperstone geschlossen ist. Anderer Kontrakt, deshalb nicht identisch; der Tooltip am Wert nennt die umgerechnete Entsprechung.",
"G/V": "Gewinn/Verlust der offenen Position, NETTO nach Quellensteuer. Bei geschlossenem Markt eine Schätzung auf Basis des Hyperliquid-Kurses (mit ≈ markiert).",
}
TB = {
"Laufzeit": "Wie lange der Trade schon läuft. Ab 2 Stunden bernstein — dann greift der Time-Stop, falls der Trade nie in die Gewinnphase kam.",
"Richtung": "LONG = auf steigende Kurse, SHORT = auf fallende.",
"Lots": "Positionsgröße. Ergibt sich aus dem Einsatz-Feld in der Order-Leiste.",
"Einsatz": "Die gebundene Margin dieser Position.",
"Auto-Close": "Schließt am nächsten S/R-Level automatisch, wenn das Level wahrscheinlich hält. Derzeit AUS.",
"SL": "Stop-Loss beim Broker. Ändern schaltet das Trailing ab, damit es die Handeingabe nicht zurückzieht.",
"TP": "Take-Profit beim Broker. Ändern schaltet das Trailing ab.",
"Gewinn-Close": "Mindestgewinn in Euro, unter dem der Auto-Close am Level NICHT schließt. Leer oder 0 = aus.",
"Notfall-Close": "Harte Verlustgrenze in Euro — der Server schließt sofort, wenn sie erreicht ist. Wirkt auch bei gesperrtem Handy. ⚠ Ein gesetzter Wert wird auf den nächsten Trade übernommen, bis er gelöscht wird.",
}
ELEM = {
"vd-signal": "Die eigentliche Empfehlung samt Zeitebene — sie steuert die Order. Bei WARTEN steht dahinter, was noch fehlt.",
"vd-consensus": "Wie viele der stimmberechtigten Module dieselbe Richtung sehen, plus die aktuellen Handelskosten (Spread geteilt durch ATR).",
"vd-modules": "Die Module mit Stimmrecht. Die Zahl im Chip ist das Gewicht, graue Chips schweigen gerade. Dauerhaft entmachtete Module werden hier nicht mehr gezeigt.",
"vd-meter": "Bias-Nadel: gewichteter Konsens der Module zwischen SHORT und LONG. Reine Anzeige — die Order steuert die Headline.",
"wave-turns": "EMA-Stand je Zeitebene: grün aufwärts, rot abwärts. Eine frische Kreuzung blinkt. Reine Anzeige.",
"wave-squeeze": "Volatilitäts-Squeeze: der Kurs komprimiert und bricht aus. Das einzige 2-Stichproben-validierte Einstiegssignal des Projekts.",
"wave-bounce": "Warnung bei Überdehnung — der Kurs ist weit von seiner EMA weg. KEIN Signal: die Richtungstreffer-Quote liegt gemessen bei ~50 %.",
"cur-near": "Nächstes S/R-Level und Abstand dorthin.",
"wave-reasons": "Die Begründungen, aus denen sich Richtung und Konfidenz zusammensetzen.",
"pos-srhint": "Nähert sich der Kurs dem Ziel-Level, steht hier die Durchbruch-Wahrscheinlichkeit. Das Modell dahinter ist out-of-sample kalibriert (AUC 0,65).",
"pos-stophint": "Dasselbe für das Level auf der Verlustseite — reine Anzeige, hier wird nichts automatisch geschlossen.",
"news-conflict": "Warnt, wenn der News-Flow deutlich gegen die offene Position oder das aktive Signal steht. Kontext — als Prognose nicht belegt.",
"cal-note": "Laufendes oder bevorstehendes High-Impact-Ereignis aus dem Wirtschaftskalender. Sperrt autonome Einstiege, nicht manuelle.",
"flip-note": "Zustand des Auto-Flip-Close. Derzeit aus — in beiden Halbjahren gemessen negativ.",
"agent-bias": "Richtungsaussage des Copiloten. NEUTRAL heißt, er zählt in der Empfehlung nicht mit.",
"agent-reason": "Die Begründung des Copiloten im Klartext.",
"pt-list": "Erkannte Muster mit Skizze, Trigger und Kursziel.",
"ms-swings": "Swing-Folge: HH/HL = Aufwärtsstruktur, LH/LL = Abwärtsstruktur.",
"ms-bos": "Letzter Break of Structure — welches Swing-Level zuletzt gebrochen wurde.",
"ms-chan": "Position des Kurses im Regressionskanal: 0 % = unterer Rand, 100 % = oberer.",
"ca-list": "Erkannte Kerzenformen der letzten M5-Bars mit Volumen-Vergleich.",
"mt-grid": "Deine manuellen Trades über heute, 30 Tage und gesamt, dazu der Bot zum Vergleich.",
"mt-split": "Aufgeteilt danach, ob der Trade MIT oder OHNE Deckung durch die Empfehlung lief. Gegen das Signal kostet gemessen 6,60 € je Lot.",
"trades": "Zuletzt geschlossene Trades: Richtung, Ergebnis und Schließgrund.",
"gaps-list": "Offene Kurslücken mit Zone, Fill-Level und Abstand zum aktuellen Kurs.",
"stx-row": "Trades, Trefferquote, Profitfaktor und das Verhältnis von Ø-Gewinn zu Ø-Verlust.",
}
def setze(muster: str, tip: str, text: str) -> str:
"""Haengt title= an, wenn noch keins da ist (idempotent)."""
def rep(m):
attrs = m.group(2)
if "title=" in attrs:
return m.group(0)
return m.group(1) + attrs + f' title="{tip}"' + m.group(3)
return re.sub(muster, rep, text, count=1)
for i, tip in KARTEN.items():
t = setze(rf'(<section class="card[^"]*"[^>]*id="{re.escape(i)}"[^>]*>\s*<h2)([^>]*)(>)',
tip, t)
for lbl, tip in HDR.items():
t = setze(rf'(<label(?: id="[^"]*")?)()(>{re.escape(lbl)}</label>)', tip, t)
for lbl, tip in TB.items():
t = setze(rf'(<span class="tb-field[^"]*"><label)()(>{re.escape(lbl)}</label>)', tip, t)
for i, tip in ELEM.items():
t = setze(rf'(<div class="[A-Za-z0-9 _-]+" id="{re.escape(i)}")([^>]*)(>)', tip, t)
P.write_text(t, encoding="utf-8")
print(f" title-Attribute: {t.count('title=')}")
+8 -1
View File
@@ -159,7 +159,14 @@ function renderVerdict(v, snap) {
// Modul-Chips // Modul-Chips
const vote = (x) => x > 0 ? ["long", "▲"] : x < 0 ? ["short", "▼"] : ["flat", "—"]; const vote = (x) => x > 0 ? ["long", "▲"] : x < 0 ? ["short", "▼"] : ["flat", "—"];
$("vd-modules").innerHTML = (v.votes || []).map(mod => { // ⚠ NUR Module zeigen, die wirklich in die Empfehlung einfliessen
// (User-Vorgabe 2026-08-06). `used === false` = dauerhaft entmachtet, weil
// gemessen ohne Inhalt (Elliott: 1.384 Episoden flach bei 25,9 % Einfluss;
// Orderbuch: 2.688 Episoden beidhaelftig negativ). Sie bleiben im Snapshot
// und in `verdict_votes` — nur der Chip entfaellt.
// Module mit `weight === 0` bleiben SICHTBAR: die schweigen nur situativ
// (Welle bei WARTEN, Squeeze ohne Ausbruch) und sprechen wieder.
$("vd-modules").innerHTML = (v.votes || []).filter(m => m.used !== false).map(mod => {
const [c, a] = vote(mod.vote); const [c, a] = vote(mod.vote);
// Gewicht sichtbar machen: Module OHNE Aussage (w=0) grau, sonst das Gewicht // Gewicht sichtbar machen: Module OHNE Aussage (w=0) grau, sonst das Gewicht
// anzeigen — so ist erkennbar, dass z. B. Orderbuch/Liq-Trend (0,5, ungemessen) // anzeigen — so ist erkennbar, dass z. B. Orderbuch/Liq-Trend (0,5, ungemessen)
+54 -67
View File
@@ -6,7 +6,7 @@
<meta name="theme-color" content="#0d1117"> <meta name="theme-color" content="#0d1117">
<title>Oil · MT5</title> <title>Oil · MT5</title>
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="style.css?v=145"> <link rel="stylesheet" href="style.css?v=147">
</head> </head>
<body> <body>
<!-- Modul-Menü (ganz oben) --> <!-- Modul-Menü (ganz oben) -->
@@ -36,16 +36,16 @@
</div> </div>
</div> </div>
<div class="price-row"> <div class="price-row">
<div class="px"><label>BALANCE</label><span id="balance"></span></div> <div class="px"><label title="Kontostand ohne die offene Position.">BALANCE</label><span id="balance"></span></div>
<div class="px"><label>TAG P/L</label><span id="day-pl"></span></div> <div class="px"><label title="Realisiertes Ergebnis von heute. Brutto — die Quellensteuer wird größtenteils erstattet und ist hier nicht abgezogen.">TAG P/L</label><span id="day-pl"></span></div>
<div class="px"><label>EQUITY</label><span id="equity"></span></div> <div class="px"><label title="Kontostand einschließlich der offenen Position.">EQUITY</label><span id="equity"></span></div>
<div class="px"><label id="hdr-price-lbl">PEPPERSTONE KURS</label><span id="hdr-price"></span></div> <div class="px"><label id="hdr-price-lbl" title="Der Kurs, zu dem tatsächlich gehandelt wird. Steht er länger als 3 Minuten still, gilt der Markt als geschlossen und das Label zeigt ZU.">PEPPERSTONE KURS</label><span id="hdr-price"></span></div>
<!-- Hyperliquid-Kurs NEBEN dem Broker-Kurs (User 2026-08-01). HL handelt 24/7, <!-- Hyperliquid-Kurs NEBEN dem Broker-Kurs (User 2026-08-01). HL handelt 24/7,
Pepperstone nicht — am Wochenende der einzige lebende Kurs. Basis-korrigiert, Pepperstone nicht — am Wochenende der einzige lebende Kurs. Basis-korrigiert,
also direkt vergleichbar. Beide Quellen AUSGESCHRIEBEN (User 2026-08-01): also direkt vergleichbar. Beide Quellen AUSGESCHRIEBEN (User 2026-08-01):
„KURS"/„HL" ließ offen, welcher Kurs woher kommt. --> „KURS"/„HL" ließ offen, welcher Kurs woher kommt. -->
<div class="px" id="px-hl"><label>HYPERLIQUID KURS</label><span id="hdr-hl"></span></div> <div class="px" id="px-hl"><label title="Roher Kurs des Hyperliquid-Öl-Perps — läuft 24/7, auch wenn Pepperstone geschlossen ist. Anderer Kontrakt, deshalb nicht identisch; der Tooltip am Wert nennt die umgerechnete Entsprechung.">HYPERLIQUID KURS</label><span id="hdr-hl"></span></div>
<div class="px"><label>G/V</label><span id="hdr-pnl"></span></div> <div class="px"><label title="Gewinn/Verlust der offenen Position, NETTO nach Quellensteuer. Bei geschlossenem Markt eine Schätzung auf Basis des Hyperliquid-Kurses (mit ≈ markiert).">G/V</label><span id="hdr-pnl"></span></div>
</div> </div>
</header> </header>
@@ -54,32 +54,32 @@
<div id="circuit-banner" class="circuit hidden"></div> <div id="circuit-banner" class="circuit hidden"></div>
<!-- Aktueller Trade (nur bei offener Position) — Anzeige + SL/TP/Close editierbar --> <!-- Aktueller Trade (nur bei offener Position) — Anzeige + SL/TP/Close editierbar -->
<section class="card wide trade-bar hidden" id="trade-bar"> <section class="card wide trade-bar hidden" id="trade-bar">
<h2 class="tb-title">aktueller Trade läuft <span class="tb-runtime" id="tb-runtime"></span></h2> <h2 class="tb-title" title="Der aktuell offene Trade. SL, TP und die Close-Schwellen sind hier direkt editierbar — Enter oder Verlassen des Feldes sendet.">aktueller Trade läuft <span class="tb-runtime" id="tb-runtime"></span></h2>
<div class="tb-row"> <div class="tb-row">
<span class="tb-field"><label>Laufzeit</label> <span class="tb-field"><label title="Wie lange der Trade schon läuft. Ab 2 Stunden bernstein — dann greift der Time-Stop, falls der Trade nie in die Gewinnphase kam.">Laufzeit</label>
<b class="tb-val" id="tb-dur"></b></span> <b class="tb-val" id="tb-dur"></b></span>
<span class="tb-field"><label>Richtung</label> <span class="tb-field"><label title="LONG = auf steigende Kurse, SHORT = auf fallende.">Richtung</label>
<b class="tb-val tb-dir" id="tb-dir"></b></span> <b class="tb-val tb-dir" id="tb-dir"></b></span>
<span class="tb-field"><label>Lots</label> <span class="tb-field"><label title="Positionsgröße. Ergibt sich aus dem Einsatz-Feld in der Order-Leiste.">Lots</label>
<b class="tb-val" id="tb-lots"></b></span> <b class="tb-val" id="tb-lots"></b></span>
<span class="tb-field"><label>Einsatz</label> <span class="tb-field"><label title="Die gebundene Margin dieser Position.">Einsatz</label>
<b class="tb-val" id="tb-margin"></b></span> <b class="tb-val" id="tb-margin"></b></span>
<span class="tb-field"><label>Auto-Close</label> <span class="tb-field"><label title="Schließt am nächsten S/R-Level automatisch, wenn das Level wahrscheinlich hält. Derzeit AUS.">Auto-Close</label>
<button id="srclose-btn" class="tb-val tb-btn"></button></span> <button id="srclose-btn" class="tb-val tb-btn"></button></span>
<span class="tb-field stop"><label>SL</label> <span class="tb-field stop"><label title="Stop-Loss beim Broker. Ändern schaltet das Trailing ab, damit es die Handeingabe nicht zurückzieht.">SL</label>
<input id="tb-sl" type="number" inputmode="decimal" step="0.01" placeholder="—"></span> <input id="tb-sl" type="number" inputmode="decimal" step="0.01" placeholder="—"></span>
<span class="tb-field gain"><label>TP</label> <span class="tb-field gain"><label title="Take-Profit beim Broker. Ändern schaltet das Trailing ab.">TP</label>
<input id="tb-tp" type="number" inputmode="decimal" step="0.01" placeholder="—"></span> <input id="tb-tp" type="number" inputmode="decimal" step="0.01" placeholder="—"></span>
<span class="tb-field gain"><label>Gewinn-Close</label> <span class="tb-field gain"><label title="Mindestgewinn in Euro, unter dem der Auto-Close am Level NICHT schließt. Leer oder 0 = aus.">Gewinn-Close</label>
<input id="srmin-input" type="number" inputmode="decimal" step="1" placeholder="€"></span> <input id="srmin-input" type="number" inputmode="decimal" step="1" placeholder="€"></span>
<span class="tb-field stop"><label>Notfall-Close</label> <span class="tb-field stop"><label title="Harte Verlustgrenze in Euro — der Server schließt sofort, wenn sie erreicht ist. Wirkt auch bei gesperrtem Handy. ⚠ Ein gesetzter Wert wird auf den nächsten Trade übernommen, bis er gelöscht wird.">Notfall-Close</label>
<input id="emg-input" type="number" inputmode="decimal" step="1" placeholder="€"></span> <input id="emg-input" type="number" inputmode="decimal" step="1" placeholder="€"></span>
</div> </div>
</section> </section>
<!-- Gesamtempfehlung (aus allen Modulen aggregiert) --> <!-- Gesamtempfehlung (aus allen Modulen aggregiert) -->
<section class="card wide" id="card-verdict"> <section class="card wide" id="card-verdict">
<h2>Gesamtempfehlung</h2> <h2 title="Aggregation aller Module zu einer Empfehlung. Die HEADLINE (Welle) steuert die Order, alles darunter ist Konsens-Anzeige. Gemessen an 1.071 Live-Episoden trifft die Richtung zu 4851 % — die Karte taugt als Veto (gegen das Signal zu handeln kostet gemessen 6,60 € je Lot), nicht als Prognose.">Gesamtempfehlung</h2>
<div class="vd-head"> <div class="vd-head">
<!-- ⚠ Der Ring ist ein SCORE, keine Trefferwahrscheinlichkeit. Gemessen <!-- ⚠ Der Ring ist ein SCORE, keine Trefferwahrscheinlichkeit. Gemessen
(`analyze_verdict_calibration.py`) ist conf_pct nicht kalibriert und (`analyze_verdict_calibration.py`) ist conf_pct nicht kalibriert und
@@ -89,23 +89,10 @@
<span class="vd-ring-in"><b id="vd-conf"></b><i class="vd-ring-lbl">Score</i></span> <span class="vd-ring-in"><b id="vd-conf"></b><i class="vd-ring-lbl">Score</i></span>
</div> </div>
<div class="vd-main"> <div class="vd-main">
<div class="vd-signal" id="vd-signal">◌ —</div> <div class="vd-signal" id="vd-signal" title="Die eigentliche Empfehlung samt Zeitebene — sie steuert die Order. Bei WARTEN steht dahinter, was noch fehlt.">◌ —</div>
<div class="vd-consensus" id="vd-consensus"></div> <div class="vd-consensus" id="vd-consensus" title="Wie viele der stimmberechtigten Module dieselbe Richtung sehen, plus die aktuellen Handelskosten (Spread geteilt durch ATR)."></div>
</div> </div>
</div> </div>
<!-- ⚠⚠ STEHENDER VORBEHALT (2026-08-06, gemessen `analyze_signal_live.py`
an 1.071 Live-Episoden): die Richtungsaussage trifft in 4851 % der
Fälle — ein Münzwurf. Der Ertrag entsteht nachweislich aus dem
EINSTIEGSPREIS (ruhende Order am Level: ØR +0,35/+0,32 gegen 0,09/0,11
am Markt) und der Exit-Asymmetrie, nicht aus der Trefferquote. Die Zeile
steht bewusst fest im Markup und nicht in JS: sie ist ein Dauerhinweis,
kein Zustand. -->
<div class="vd-note" id="vd-note"
title="Gemessen an 1.071 Live-Episoden (08.05.06.08.2026), gegen die Drift der jeweiligen Hälfte gelesen: Treffer 48,351,1 %, Überschuss max. +0,085×ATR — unter den realen Handelskosten von 0,265×ATR.">
ⓘ Richtung ≈ Münzwurf (gemessen 4851 % Treffer). Der Ertrag kommt aus
Einstiegspreis und Exit, nicht aus der Trefferquote — lies das hier als
<b>Auslöser für eine Order am Level</b>, nicht als Kursprognose.
</div>
<!-- Warum WARTEN? Verteilung der blockierenden Gates über den heutigen Tag. <!-- Warum WARTEN? Verteilung der blockierenden Gates über den heutigen Tag.
Ohne die Zeile war „warum gab es so wenige Empfehlungen?" nur per Ohne die Zeile war „warum gab es so wenige Empfehlungen?" nur per
DB-Abfrage zu beantworten (real 06.08.: 6 von 646 Zeilen ohne Block). --> DB-Abfrage zu beantworten (real 06.08.: 6 von 646 Zeilen ohne Block). -->
@@ -120,9 +107,9 @@
<div class="vd-track"><div class="vd-needle" id="vd-needle"></div></div> <div class="vd-track"><div class="vd-needle" id="vd-needle"></div></div>
<span class="vd-end long">LONG</span> <span class="vd-end long">LONG</span>
</div> </div>
<div class="vd-modules" id="vd-modules"></div> <div class="vd-modules" id="vd-modules" title="Die Module mit Stimmrecht. Die Zahl im Chip ist das Gewicht, graue Chips schweigen gerade. Dauerhaft entmachtete Module werden hier nicht mehr gezeigt."></div>
<!-- Zeitebenen-Ampel (M1/M5/M15/M30/H1), aus der Welle hierher verschoben --> <!-- Zeitebenen-Ampel (M1/M5/M15/M30/H1), aus der Welle hierher verschoben -->
<div class="tf-turns" id="wave-turns"></div> <div class="tf-turns" id="wave-turns" title="EMA-Stand je Zeitebene: grün aufwärts, rot abwärts. Eine frische Kreuzung blinkt. Reine Anzeige."></div>
<!-- Erwartete Spanne, komprimiert (User-Vorgabe 2026-08-05; die eigene Karte <!-- Erwartete Spanne, komprimiert (User-Vorgabe 2026-08-05; die eigene Karte
`#card-cone` ist dafür entfallen). ⚠ STREUUNG, nicht Richtung — deshalb `#card-cone` ist dafür entfallen). ⚠ STREUUNG, nicht Richtung — deshalb
bewusst UNTER der Bias-Nadel und neutral gefärbt, damit sie nicht als bewusst UNTER der Bias-Nadel und neutral gefärbt, damit sie nicht als
@@ -133,14 +120,14 @@
<!-- Meldungen (ex-Position + Wellen-Meldungen; Welle-Karte entfällt) --> <!-- Meldungen (ex-Position + Wellen-Meldungen; Welle-Karte entfällt) -->
<section class="card wide" id="card-pos"> <section class="card wide" id="card-pos">
<h2>Meldungen</h2> <h2 title="Live-Meldungen zum laufenden Trade und zur Marktlage: Squeeze, Überdehnung, S/R-Nähe, News- und Kalender-Konflikte, Hyperliquid-Kontext.">Meldungen</h2>
<div class="squeeze-ind" id="wave-squeeze"></div> <div class="squeeze-ind" id="wave-squeeze" title="Volatilitäts-Squeeze: der Kurs komprimiert und bricht aus. Das einzige 2-Stichproben-validierte Einstiegssignal des Projekts."></div>
<div class="bounce-ind" id="wave-bounce"></div> <div class="bounce-ind" id="wave-bounce" title="Warnung bei Überdehnung — der Kurs ist weit von seiner EMA weg. KEIN Signal: die Richtungstreffer-Quote liegt gemessen bei ~50 %."></div>
<div class="cur-near" id="cur-near"></div> <div class="cur-near" id="cur-near" title="Nächstes S/R-Level und Abstand dorthin."></div>
<div class="pos-srhint hidden" id="pos-srhint"></div> <div class="pos-srhint hidden" id="pos-srhint" title="Nähert sich der Kurs dem Ziel-Level, steht hier die Durchbruch-Wahrscheinlichkeit. Das Modell dahinter ist out-of-sample kalibriert (AUC 0,65)."></div>
<div class="pos-stophint hidden" id="pos-stophint"></div> <div class="pos-stophint hidden" id="pos-stophint" title="Dasselbe für das Level auf der Verlustseite — reine Anzeige, hier wird nichts automatisch geschlossen."></div>
<div class="news-conflict hidden" id="news-conflict"></div> <div class="news-conflict hidden" id="news-conflict" title="Warnt, wenn der News-Flow deutlich gegen die offene Position oder das aktive Signal steht. Kontext — als Prognose nicht belegt."></div>
<div class="news-conflict hidden" id="cal-note"></div> <div class="news-conflict hidden" id="cal-note" title="Laufendes oder bevorstehendes High-Impact-Ereignis aus dem Wirtschaftskalender. Sperrt autonome Einstiege, nicht manuelle."></div>
<!-- HL-Kontext (Funding/Open Interest/Oracle-Premium). ⚠ REINE ANZEIGE: <!-- HL-Kontext (Funding/Open Interest/Oracle-Premium). ⚠ REINE ANZEIGE:
gemessen (`analyze_hl_funding.py`, 5.095 Stundenwerte, 7 Monate) gemessen (`analyze_hl_funding.py`, 5.095 Stundenwerte, 7 Monate)
hält entüberlappt KEIN Bucket die 2-Stichproben-Regel. Kein hält entüberlappt KEIN Bucket die 2-Stichproben-Regel. Kein
@@ -151,8 +138,8 @@
backtest_flipclose2.py), läuft auf ausdrücklichen User-Wunsch. Hatte backtest_flipclose2.py), läuft auf ausdrücklichen User-Wunsch. Hatte
bis 2026-08-05 KEINE Anzeige — ein Exit, der echtes Geld bewegt und den bis 2026-08-05 KEINE Anzeige — ein Exit, der echtes Geld bewegt und den
niemand sieht. Jetzt sichtbar, damit die Entscheidung informiert ist. --> niemand sieht. Jetzt sichtbar, damit die Entscheidung informiert ist. -->
<div class="news-conflict hidden" id="flip-note"></div> <div class="news-conflict hidden" id="flip-note" title="Zustand des Auto-Flip-Close. Derzeit aus — in beiden Halbjahren gemessen negativ."></div>
<div class="reasons" id="wave-reasons"></div> <div class="reasons" id="wave-reasons" title="Die Begründungen, aus denen sich Richtung und Konfidenz zusammensetzen."></div>
<div class="kv"><span>Setup</span><b id="wave-setup"></b></div> <div class="kv"><span>Setup</span><b id="wave-setup"></b></div>
<div class="kv"><span>Lauf</span><b id="wave-move"></b></div> <div class="kv"><span>Lauf</span><b id="wave-move"></b></div>
</section> </section>
@@ -164,7 +151,7 @@
<!-- Trailing (Dashboard-Kachel ausgeblendet 2026-07-22, User-Vorgabe; Backend/ <!-- Trailing (Dashboard-Kachel ausgeblendet 2026-07-22, User-Vorgabe; Backend/
Logik unverändert aktiv, nur die Anzeige raus) --> Logik unverändert aktiv, nur die Anzeige raus) -->
<section class="card wide hidden" id="card-trail"> <section class="card wide hidden" id="card-trail">
<h2>Trailing</h2> <h2 title="Zustand des Trailing-Stops (Phase, aktueller SL, High-Water). Ausgeblendet — das Trailing läuft im Hintergrund weiter.">Trailing</h2>
<div class="kv"><span>Status</span><b id="trail-state"></b></div> <div class="kv"><span>Status</span><b id="trail-state"></b></div>
<div class="kv"><span>Phase</span><b id="trail-phase"></b></div> <div class="kv"><span>Phase</span><b id="trail-phase"></b></div>
<div class="kv"><span>SL</span><b id="trail-sl"></b></div> <div class="kv"><span>SL</span><b id="trail-sl"></b></div>
@@ -174,8 +161,8 @@
<!-- Live-Statistik — ganz unten --> <!-- Live-Statistik — ganz unten -->
<section class="card wide" id="card-stats-live"> <section class="card wide" id="card-stats-live">
<h2>Statistik (live)</h2> <h2 title="Kompakte Bilanz über Woche und Gesamt. Verhältnis = Ø-Gewinn geteilt durch Ø-Verlust; unter 1 heißt, die Verlierer sind größer als die Gewinner.">Statistik (live)</h2>
<div class="stx-row" id="stx-row"><span class="dim">lade …</span></div> <div class="stx-row" id="stx-row" title="Trades, Trefferquote, Profitfaktor und das Verhältnis von Ø-Gewinn zu Ø-Verlust."><span class="dim">lade …</span></div>
</section> </section>
</main> </main>
@@ -193,18 +180,18 @@
<!-- KI-Agent — Verdict-Gewicht 1,0 bei gerichteter Aussage, 0 bei NEUTRAL --> <!-- KI-Agent — Verdict-Gewicht 1,0 bei gerichteter Aussage, 0 bei NEUTRAL -->
<section class="card wide" id="card-agent"> <section class="card wide" id="card-agent">
<h2>KI-Copilot <span class="ca-tf">Gewicht 1,0</span></h2> <h2 title="Einschätzung des KI-Copiloten (LLM). Stimmt mit Gewicht 1,0 mit, wenn er eine Richtung nennt — bei NEUTRAL zählt er nicht. Als Prognose nicht belegt.">KI-Copilot <span class="ca-tf">Gewicht 1,0</span></h2>
<div class="signal" id="agent-bias">◌ —</div> <div class="signal" id="agent-bias" title="Richtungsaussage des Copiloten. NEUTRAL heißt, er zählt in der Empfehlung nicht mit.">◌ —</div>
<div class="agent-head" id="agent-head"></div> <div class="agent-head" id="agent-head"></div>
<div class="agent-text" id="agent-reason"></div> <div class="agent-text" id="agent-reason" title="Die Begründung des Copiloten im Klartext."></div>
<ul class="risks" id="agent-risks"></ul> <ul class="risks" id="agent-risks"></ul>
</section> </section>
<!-- Chartmuster — Verdict-Gewicht `_PAT_W`=0,25 (User-Vorgabe „5 %" 2026-08-01); <!-- Chartmuster — Verdict-Gewicht `_PAT_W`=0,25 (User-Vorgabe „5 %" 2026-08-01);
`forming` zählt halb. Deshalb LIVE, nicht Anzeige. --> `forming` zählt halb. Deshalb LIVE, nicht Anzeige. -->
<section class="card wide" id="card-patterns"> <section class="card wide" id="card-patterns">
<h2>Chartmuster <span class="pt-tf">M30 · Gewicht 0,25</span></h2> <h2 title="Mechanisch erkannte Chartmuster auf M30 mit Trigger und Kursziel. Gewicht 0,25. Die Ziel-Trefferquote liegt gemessen nur bei 1338 % — Kontext, keine Vorhersage.">Chartmuster <span class="pt-tf">M30 · Gewicht 0,25</span></h2>
<div class="pt-list" id="pt-list"><span class="dim"></span></div> <div class="pt-list" id="pt-list" title="Erkannte Muster mit Skizze, Trigger und Kursziel."><span class="dim"></span></div>
</section> </section>
</section> </section>
@@ -220,13 +207,13 @@
<!-- Marktstruktur (M30) — Signalvariante gemessen verworfen <!-- Marktstruktur (M30) — Signalvariante gemessen verworfen
(backtest_structure.py + backtest_structure_tf.py: 24/24 Zellen negativ) --> (backtest_structure.py + backtest_structure_tf.py: 24/24 Zellen negativ) -->
<section class="card wide" id="card-structure"> <section class="card wide" id="card-structure">
<h2>Marktstruktur <span class="ms-tf">M30 · nur Anzeige</span></h2> <h2 title="Price-Action-Struktur auf M30: Swing-Folge, letzter Bruch (BOS) und Regressionskanal. Reine Anzeige — als Signal über alle Zeitebenen gemessen und verworfen.">Marktstruktur <span class="ms-tf">M30 · nur Anzeige</span></h2>
<div class="ms-top"> <div class="ms-top">
<span class="ms-trend" id="ms-trend"></span> <span class="ms-trend" id="ms-trend"></span>
<div class="ms-swings" id="ms-swings"></div> <div class="ms-swings" id="ms-swings" title="Swing-Folge: HH/HL = Aufwärtsstruktur, LH/LL = Abwärtsstruktur."></div>
</div> </div>
<div class="ms-bos" id="ms-bos"></div> <div class="ms-bos" id="ms-bos" title="Letzter Break of Structure — welches Swing-Level zuletzt gebrochen wurde."></div>
<div class="ms-chan" id="ms-chan"> <div class="ms-chan" id="ms-chan" title="Position des Kurses im Regressionskanal: 0 % = unterer Rand, 100 % = oberer.">
<div class="ms-chan-head"><span id="ms-chan-dir"></span> <div class="ms-chan-head"><span id="ms-chan-dir"></span>
<span class="ms-chan-note" id="ms-chan-note"></span></div> <span class="ms-chan-note" id="ms-chan-note"></span></div>
<div class="ms-chan-track"><div class="ms-chan-fill" id="ms-chan-fill"></div> <div class="ms-chan-track"><div class="ms-chan-fill" id="ms-chan-fill"></div>
@@ -239,8 +226,8 @@
Lehrbuch-Deutung ist invertiert, deshalb steht die GEMESSENE Lesart im Lehrbuch-Deutung ist invertiert, deshalb steht die GEMESSENE Lesart im
Hinweistext und die Kachel ist bewusst neutral gefärbt. --> Hinweistext und die Kachel ist bewusst neutral gefärbt. -->
<section class="card wide" id="card-candles"> <section class="card wide" id="card-candles">
<h2>Kerzen-Anatomie <span class="ca-tf">M5 · nur Anzeige</span></h2> <h2 title="Kerzengröße, Dochte und Volumen der letzten M5-Kerzen. Reine Anzeige und bewusst neutral gefärbt: die Lehrbuch-Lesart ist hier gemessen INVERTIERT — der Kurs läuft nach einer Klimax-Kerze eher GEGEN sie.">Kerzen-Anatomie <span class="ca-tf">M5 · nur Anzeige</span></h2>
<div class="ca-list" id="ca-list"><span class="dim"></span></div> <div class="ca-list" id="ca-list" title="Erkannte Kerzenformen der letzten M5-Bars mit Volumen-Vergleich."><span class="dim"></span></div>
</section> </section>
</section> </section>
@@ -275,22 +262,22 @@
rechnet nichts hoch. Der volle Entscheidungskontext (ctx_*) wird erst rechnet nichts hoch. Der volle Entscheidungskontext (ctx_*) wird erst
seit dem 04.08. mitgeschrieben; die Reifegrad-Zeile macht das sichtbar. --> seit dem 04.08. mitgeschrieben; die Reifegrad-Zeile macht das sichtbar. -->
<section class="card wide" id="card-manual"> <section class="card wide" id="card-manual">
<h2>Manuelle Trades <span class="mt-sub">deine Historie · 30 Tage</span></h2> <h2 title="Deine eigenen manuellen Trades im Vergleich zum Bot, aufgeteilt nach Signal-Deckung. Rein deskriptiv.">Manuelle Trades <span class="mt-sub">deine Historie · 30 Tage</span></h2>
<div class="mt-grid" id="mt-grid"></div> <div class="mt-grid" id="mt-grid" title="Deine manuellen Trades über heute, 30 Tage und gesamt, dazu der Bot zum Vergleich."></div>
<div class="mt-split" id="mt-split"></div> <div class="mt-split" id="mt-split" title="Aufgeteilt danach, ob der Trade MIT oder OHNE Deckung durch die Empfehlung lief. Gegen das Signal kostet gemessen 6,60 € je Lot."></div>
<div class="mt-note dim" id="mt-note"></div> <div class="mt-note dim" id="mt-note"></div>
</section> </section>
<!-- Letzte Trades --> <!-- Letzte Trades -->
<section class="card wide" id="card-trades"> <section class="card wide" id="card-trades">
<h2>Letzte Trades</h2> <h2 title="Die zuletzt geschlossenen Trades mit Ergebnis und Schließgrund.">Letzte Trades</h2>
<div class="trades" id="trades"></div> <div class="trades" id="trades" title="Zuletzt geschlossene Trades: Richtung, Ergebnis und Schließgrund."></div>
</section> </section>
<!-- Kurslücken (Gaps) — Fill-Magnete, nur Kontext --> <!-- Kurslücken (Gaps) — Fill-Magnete, nur Kontext -->
<section class="card wide" id="card-gaps"> <section class="card wide" id="card-gaps">
<h2>Kurslücken (Gaps 2026)</h2> <h2 title="Offene Kurslücken des Jahres. Vakuum = echte Lücke zwischen den Tagesspannen (fließt als S/R in die Konfidenz ein), Eröffnung = Schluss-zu-Eröffnung (reine Anzeige).">Kurslücken (Gaps 2026)</h2>
<div class="gaps-list" id="gaps-list"><span class="dim">lade …</span></div> <div class="gaps-list" id="gaps-list" title="Offene Kurslücken mit Zone, Fill-Level und Abstand zum aktuellen Kurs."><span class="dim">lade …</span></div>
</section> </section>
</section> </section>
@@ -345,6 +332,6 @@
</div> </div>
<div id="toast" class="toast hidden"></div> <div id="toast" class="toast hidden"></div>
<script src="app.js?v=145"></script> <script src="app.js?v=147"></script>
</body> </body>
</html> </html>
-6
View File
@@ -215,12 +215,6 @@ main{display:grid;grid-template-columns:1fr 1fr;gap:11px;padding:11px}
#vd-conf{line-height:1} #vd-conf{line-height:1}
.vd-ring-lbl{font-size:10px;font-weight:600;font-style:normal;color:var(--dim); .vd-ring-lbl{font-size:10px;font-weight:600;font-style:normal;color:var(--dim);
letter-spacing:.5px;line-height:1;margin-top:1px} letter-spacing:.5px;line-height:1;margin-top:1px}
/* Stehender Vorbehalt unter der Headline: die Richtung ist gemessen ein Muenzwurf.
Bewusst gedaempft und gestrichelt — Kontext, keine Warnung. */
.vd-note{font-size:13px;line-height:1.45;color:var(--dim);background:var(--surface-2);
border:1px dashed var(--line);border-radius:var(--r-sm);
padding:7px 10px;margin:0 0 11px}
.vd-note b{color:var(--bright);font-weight:700}
/* Block-Verteilung + Selbst-Kalibrierung: beide bewusst leise (Kontext, keine /* Block-Verteilung + Selbst-Kalibrierung: beide bewusst leise (Kontext, keine
Handlungsaufforderung). Die Trefferquote faerbt nur bei klarer Abweichung von Handlungsaufforderung). Die Trefferquote faerbt nur bei klarer Abweichung von
den gemessenen ~50 %, damit Rauschen nicht wie ein Signal aussieht. */ den gemessenen ~50 %, damit Rauschen nicht wie ein Signal aussieht. */