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
+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=')}")