docs/review-prompt.md — projektspezifisch statt generisch. Die gefaehrlichsten Fehler hier sind nicht Syntax, sondern "Messung != Betrieb", deshalb ist Deployment-Drift ein eigener Durchgang. Enthaelt die harten Grenzen (Secrets, DB-Backup, eine Instanz, keine Strategieaenderung ohne 2-Stichproben-Backtest, dokumentierte User- Entscheidungen nicht anfassen) und als Pruefliste genau die Fehlermuster, die in diesem Projekt real aufgetreten sind: stille catch-Bloecke, zu weite Plausibilitaetsfenster, aus stalen Eingaben abgeleitete Werte, zwei Quellen fuer denselben Zustand, null-unsichere DOM-Zugriffe, Ticket-Wechsel-Races. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.4 KiB
9.4 KiB
Review-Prompt — vollständige Projektprüfung
Zum Kopieren in eine frische Claude-Code-Sitzung im Projektordner. Zuletzt aktualisiert: 2026-08-02.
Führe eine vollständige Prüfung dieses Projekts durch: Fehler finden, toten Code
identifizieren, Optimierungen, Dokumentation, Verbesserungsvorschläge.
Lies zuerst CLAUDE.md vollständig. Antworte auf Deutsch.
## HARTE GRENZEN — diese gelten immer
1. `oil_widget_config.ini` enthält LIVE-SECRETS (API-Keys, Telegram-Token).
Niemals ins Repo, niemals in Logs, niemals in eine Antwort ausgeben. Wenn du
Werte daraus brauchst, lies gezielt einzelne Schlüssel.
2. Vor JEDEM schreibenden DB-Eingriff: Backup `oil_widget_history.db.bak-<datum>`.
3. Es darf immer nur EINE Server-Instanz gegen dasselbe MT5-Terminal laufen
(zwei TrailingManager = Konflikt). Prüfe das vor und nach jedem Neustart.
4. KEINE Strategie-Änderung ohne 2-Stichproben-Backtest. Für Änderungen am SIGNAL
gilt erhöhte Beweislast: 18 Signal-Eingriffe wurden bereits gemessen verworfen.
Im Zweifel: messen und berichten, nicht bauen.
5. Ändere nichts, was in CLAUDE.md als bewusste User-Entscheidung dokumentiert ist
(95 % Margin-Sizing, Circuit Breaker aus, `dead_hours` leer, Teil-Exit aus).
Du darfst es EINMAL als Risiko benennen — dann ist es erledigt.
6. Lösche nichts, was als „reaktivierbar" dokumentiert ist. Vorschlagen ja,
eigenmächtig entfernen nein.
## REIHENFOLGE
Arbeite die Durchgänge in dieser Reihenfolge ab. Berichte nach jedem Durchgang
kurz, bevor du weitermachst — nicht erst am Ende alles auf einmal.
### Durchgang 1 — Korrektheit (höchste Priorität)
Suche echte Fehler, keine Stilfragen. Diese Muster haben in diesem Projekt
nachweislich zu Fehlern geführt, prüfe sie gezielt:
- **Stille Fehlerschlucker**: `except Exception: pass`, leere `catch {}`. Ein
`catch`, der eine ganze Render-/Verarbeitungskette umschließt, versteckt echte
Fehler dauerhaft (real: `pollSnapshot` fror das Dashboard ein, Konsole leer).
Für jeden Fund: verschluckt er nur den erwarteten Fehler oder auch Logikfehler?
- **Zu weite Plausibilitätsprüfungen**: Bereiche, die einen groben Fehler als
gültig durchwinken (real: `_broker_offset_s` akzeptierte −9,5 h als Zeitzone,
weil das Fenster `[−12 h … +14 h]` war).
- **Werte aus möglicherweise STALEN Eingaben abgeleitet**: Funktionen, die aus
einem Tick/Preis/Snapshot etwas berechnen, ohne dessen Alter zu prüfen (real:
Broker-Offset und HL-Basis waren am Wochenende beide zirkulär).
- **Zwei Quellen für denselben Zustand**: `oil_widget_config.ini` gegen
`runtime_state.json` / `emergency_state.json`. Wer gewinnt beim Start? Weiß
jeder Konsument davon? (real: `auto_signal` lief tagelang gegen die ini.)
- **Frontend**: jede `$("id")`-ID in `web/app.js` muss in `web/index.html`
existieren — ein fehlendes Element wirft mitten im Render und bricht das
GESAMTE Dashboard ab. Neue Elemente null-sicher ansprechen.
- **`mt5_lock`**: alle MT5-Aufrufe darunter, mit Timeout, nicht reentrant. Prüfe
besonders Thread-Pool-/Executor-Jobs und Callbacks.
- **Broker-Zeit (UTC+3)**: jede `deal.time`/`tick.time`/`position.time`-Nutzung
muss umgerechnet sein. Ausnahme: `candles_m1.time` ist ROHE Broker-Zeit.
- **Race Conditions** in den Loops (`_pos_loop` 1 s, `_trend_loop`, `_price_loop`):
Werte, die nur beim Ticket-Wechsel EINMAL gesetzt werden, hängen stale, wenn
die Quelle in genau dem Tick nicht verfügbar war (real: Gewinn-Close-Schwelle).
Für jeden Fund: Datei:Zeile, konkretes Fehlszenario (welche Eingabe → welches
falsche Ergebnis), Schweregrad, Fix-Vorschlag. Keine Spekulation — wenn du einen
Fund nicht belegen kannst, kennzeichne ihn als „plausibel, nicht verifiziert".
### Durchgang 2 — Deployment-Drift (die Signatur-Schwäche dieses Projekts)
Das ist der wichtigste Durchgang. Track B schützt gegen Overfitting, NICHT
dagegen, dass ein real existierender Edge unter ANDEREN Bedingungen betrieben
als validiert wird. Es sind bereits 4 solche Fälle dokumentiert, alle an einem
Tag gefunden — die Liste ist erwartbar unvollständig.
Prüfe systematisch:
- Für jeden Live-Parameter (`[trading]`-Schlüssel, Konstanten in `core/`): Gegen
welchen Wert wurde gemessen? Steht er heute auf diesem Wert?
`measurement_reminder.py --status` zeigt die verankerten Werte.
- Ist ein Parameter live KONTEXTABHÄNGIG, im Backtest aber konstant?
(real: Trail-Multiplikator je Zeitebene, SL-ATR fest M15, TF per Heuristik)
- Gibt es LIVE-Gates, die kein Backtest modelliert? (Entry-Raum, EIA, Dead-Hours,
News-Blackout, Cooldowns, Startup-Grace) Welche Aussagen werden dadurch ungültig?
- Bekommt ein Modell live eine ANDERE Merkmalsverteilung als im Training?
(real: P(break) — trainiert auf Anlauf zu fixiertem Level, betrieben auf
dynamisch gewähltem → AUC 0,71 → 0,368)
- Nutzen die Backtests `core/exit_model.py` oder haben sie eigene Kopien der
Exit-Mechanik? Kopien sind der Nährboden für diese Fehlerklasse.
Führe `python analyze_divergence.py` aus und interpretiere das Ergebnis.
### Durchgang 3 — Toter Code
Trenne sauber in drei Kategorien und vermische sie nicht:
- **A) Wirklich tot**: nirgends aufgerufen, nicht dokumentiert, keine Historie.
→ Entfernen vorschlagen.
- **B) Bewusst schlafend**: dokumentiert als „reaktivierbar" oder „Backend bleibt,
UI aus" (z. B. TradersUnion, Take-Profit-Backend, Kegel-Export).
→ NICHT anfassen, nur auflisten.
- **C) Verwaist**: Config-Schlüssel ohne Leser, Snapshot-Felder ohne Konsument,
DB-Spalten ohne Schreiber, HTML-IDs ohne JS und umgekehrt.
→ Auflisten, Entfernung vorschlagen, Begründung dazu.
Konkrete Prüfungen: Config-Schlüssel gegen den Code, `snapshot`-Felder gegen
`app.js`, HTML-IDs gegen JS, importierte aber ungenutzte Module, duplizierte
Hilfsfunktionen über die Backtest-Skripte hinweg.
### Durchgang 4 — Performance
Zielgerichtet, nicht pauschal. Die relevanten Engpässe:
- **`mt5_lock`** ist der einzige echte Serialisierungspunkt. Wer hält ihn wie
lange? Gibt es vermeidbare Aufrufe im 1-s-Pfad?
- **Snapshot-Pfad** ist heiß (REST-Poll 4 s + WS-Push 1 s + `_pos_loop` 1 s).
Was wird dort berechnet, das gecacht werden könnte? Gibt es DB-Abfragen ohne
Cache?
- **SQLite**: fehlende Indizes auf den Zeitspalten der großen Tabellen
(`candles_m1`, `recommendations`, `verdict_votes` — jeweils zehntausende Zeilen).
- Micro-Optimierungen ohne Messung sind hier wertlos. Wenn du etwas vorschlägst,
miss vorher und nachher.
### Durchgang 5 — Dokumentation
CLAUDE.md ist die Quelle der Wahrheit und ~2700 Zeilen lang. Prüfe sie gegen den
CODE, nicht gegen sich selbst:
- Stimmen genannte Zahlen, Dateinamen, Funktionsnamen, Config-Schlüssel noch?
- Gibt es Aussagen, die inzwischen widerlegt sind, aber unkorrigiert dastehen?
(real: die 15-Min-Regel wurde mit „maximaler Auslenkung" begründet — eine Zahl,
die der Exit nie erreicht hätte.)
- Ist bei jeder Kennzahl klar, unter WELCHEM Exit-Modell und MIT/OHNE Kosten sie
gemessen wurde? Mehrere Altbefunde stammen aus einem vereinfachten Exit ohne
Kosten und reproduzieren mit dem echten nicht.
- Widersprüche zwischen Abschnitten.
Korrigiere gefundene Fehler direkt im Text und markiere die Korrektur sichtbar.
### Durchgang 6 — Verbesserungsvorschläge
Sortiert nach erwartetem Nutzen, nicht nach Aufwand. Für jeden Vorschlag:
- Was genau, welcher Hebel (Signal / Sizing / Exit / Infrastruktur / Verhalten)?
- Beleglage: gemessen, ableitbar, oder Vermutung? Sag es explizit.
- Was kostet ein Irrtum (EUR-Risiko, reversibel)?
Beachte die gemessene Hebel-Hierarchie: **Signal = klein** (18× belegt, dass
Filter nicht tragen), **Sizing/Exit/Verhalten = groß**. Ein Vorschlag, der am
Signal dreht, braucht eine sehr gute Begründung.
## ABSCHLUSS
Vor „fertig":
- `python -m py_compile <geänderte .py>`
- JS grob über Klammern-Balance prüfen (kein node im Env)
- Bei Web-Änderungen: `?v=N` in `web/index.html` hochzählen
- Server neu starten — und dann BEWEISEN, dass der Python-Code wirklich neu ist,
indem du ein NEUES Snapshot-Feld abfragst. Eine korrekt ausgelieferte
`app.js?v=N` beweist NICHTS (statische Dateien werden je Request von der Platte
gelesen; `restart_server.bat` hat schon zweimal still nicht neu gestartet).
- Prüfen, dass genau eine Instanz je Port läuft (8000 Oil, 8001 Hyperliquid).
- CLAUDE.md aktualisieren (zuletzt).
- Committen und nach Gitea pushen.
## BERICHTSFORM
- Befunde nach Schweregrad sortiert, nicht nach Datei.
- Je Befund: Datei:Zeile · Fehlszenario · Fix · verifiziert ja/nein.
- Ein eigener Abschnitt **„NICHT geprüft"** am Ende: was du ausgelassen hast und
warum. Eine ehrliche Lücke ist mehr wert als eine behauptete Vollständigkeit.
- Wenn ein Fix nicht umgesetzt wurde, sag es klar — nicht implizit weglassen.
Setze Fixes für Durchgang 1 (Korrektheit) und offensichtlich toten Code direkt um.
Alles, was Strategie, Schwellwerte oder Handelslogik berührt: erst berichten,
Entscheidung abwarten.
Varianten
Nur ein Durchgang: Den Abschnitt „HARTE GRENZEN" plus den gewünschten Durchgang plus „ABSCHLUSS" kopieren.
Nach einer Config-Änderung: Durchgang 2 allein, plus
python measurement_reminder.py --status.
Wöchentlich (leichtgewichtig): Durchgang 2 + python analyze_divergence.py.
⚠ NICHT die verworfenen Backtests wöchentlich neu rechnen — eine Woche ist
Rauschen (~2000 Bars), und 18 Ideen × 52 Wochen erzeugen bei 5 % Fehlalarmquote
~47 falsche „funktioniert jetzt!" pro Jahr.