# 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.
