"""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 48–51 % — 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 13–38 % — 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'(
]*id="{re.escape(i)}"[^>]*>\s*]*)(>)', tip, t) for lbl, tip in HDR.items(): t = setze(rf'({re.escape(lbl)})', tip, t) for lbl, tip in TB.items(): t = setze(rf'({re.escape(lbl)})', tip, t) for i, tip in ELEM.items(): t = setze(rf'(
]*)(>)', tip, t) P.write_text(t, encoding="utf-8") print(f" title-Attribute: {t.count('title=')}")