Axel HocksandClaude Opus 5 3e4a181c00 Messung: was bleibt vom BRK-Edge ohne Trailing? Ergebnis: kleiner Umbau faellt aus
User-Wunsch "BRK soll auch eroeffnen wenn M15 aktiv ist" + Entscheidung fuer
Variante 1+3 (erst messen, dann grosser Umbau in eigener Sitzung).

WARUM DIESE MESSUNG DIE BAUWEISE ENTSCHEIDET. Der KLEINE Umbau (Pendings nicht
mehr stornieren, open_* nicht mehr bei self.ticket abweisen) waere an einem
Abend gemacht - aber der zweite Trade haette dann nur den Broker-SL. `trader`
haelt EIN Ticket, und Trailing, Breakeven, Time-Stop, Notfall-Stop und
S/R-Close haengen alle daran (29 Stellen in engine.py). Die dokumentierten
Squeeze-Zahlen sind MIT dem kanonischen Exit gemessen; SL-only ist eine andere,
nie gemessene Konfiguration - Deployment-Drift per Konstruktion.

AUFBAU. Echte core.squeeze_scan-Regel, LIVE-Parameter (⚠ ATR-Floor 0,06, nicht
der Modul-Default 0,12), ruhende Stop-Order mit Fill bei BERUEHRUNG, Echtkosten,
80k M5, 2 Halbjahre, 95-%-Bootstrap, feste GETEILTE Einstiegsliste (alle
Varianten auf DENSELBEN Trades - sonst vergleicht man Populationen statt Exits).
⚠ KEINE Exit-Kopie: SL-only entsteht aus LIVE.with_(trail_start=999, be=999) -
der Trade bleibt in Phase "Init" und verlaesst sie nur ueber SL oder max_hold.
Es laeuft derselbe kanonische Code. Eine eigene Schleife waere das fuenfte
Exit-Modell gewesen.

ERGEBNIS (H1 / H2, OeR):
  A) kanonisch (heute)   -0,145 / +0,036    PF 0,76 / 1,07   WR 40 / 44 %
  B) SL only             -0,132 / +0,464    PF 0,92 / 1,27   WR 21 / 19 %
  C) SL + Time-Stop      -0,157 / +0,138    PF 0,87 / 1,12
  D) SL + TP             -0,188 / +0,073    PF 0,86 / 1,06
  E) SL + Time + TP      -0,212 / +0,064    PF 0,81 / 1,06

KEINE Variante erfuellt die vorab fixierte Regel (beidhaelftig OeR > 0 UND
PF > 1 UND 95-%-KI ohne die Null). H1 ist durchgehend negativ, und ALLE zehn
Intervalle enthalten die Null. Die vorab fixierte Antwort lautet damit:
GROSSER Umbau, nicht kleiner. Das deckt sich mit der Entscheidung des Users.

⚠⚠ GRENZE, die nicht ueberspielt werden darf: die KONTROLLE reproduziert NICHT.
Variante A liefert -0,145/+0,036, dokumentiert sind +0,124/+0,292
(backtest_squeeze_touchfill.py), und meine Einstiegszahl ist 362/559 gegen
1092/1807. Meine Auswahl ist also deutlich strenger. Damit sind die
ABSOLUTWERTE unbrauchbar; belastbar ist allein der INTERNE Vergleich, weil alle
Varianten auf derselben Entry-Liste laufen und sich nur im Exit unterscheiden.
Derselbe Vorbehalt wie am 13.08. bei backtest_squeeze_srclose2.py.

⚠⚠ UND DER INTERNE VERGLEICH IST KONTRAINTUITIV: SL-only sieht im OeR NICHT
schlechter aus (H1 -0,132 gegen -0,145, H2 +0,464 gegen +0,036). Das ist aber
kein Argument fuer den kleinen Umbau, sondern ein Varianz-Befund:
  - Trefferquote faellt 40 -> 21 % bzw. 44 -> 19 %. Vier von fuenf Trades laufen
    in den vollen -2R-Stop.
  - Die KI-Breite explodiert: [-0,108 .. +1,115] gegen [-0,081 .. +0,148] beim
    kanonischen Exit - rund das Vierfache.
Der Ertrag haengt an wenigen sehr langen Laeufern (max_hold 200 Bars = 16,7 h
ohne jede Absicherung). Unter 40-%-Margin-Sizing ist "81 % der Trades verlieren
volle 2R" eine ganz andere Risikoklasse als die gemessene - und statistisch
nicht von null zu unterscheiden.

FAZIT: nichts gebaut, nichts umgeschaltet. Der grosse Umbau (Trailing je Ticket)
bleibt der Weg, und er gehoert in eine eigene Sitzung mit FLACHEM Konto - ein
halb fertiger Ticket-Umbau laesst den Schutz-Stack an der falschen der beiden
Positionen haengen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:48:35 +02:00

Oil Trading Bot (MT5, WTI)

Algorithmischer WTI-Öl-Trading-Bot auf MetaTrader 5 mit headless FastAPI-Backend und Mobile-PWA. Analyse, Strategie, Backtests und LLM-Copilot laufen in Python; MQL5 ist nur eine dünne Zeichen-Schicht fürs Desktop-Terminal.

Hinweis: Interne Doku, Antworten und UI-Texte sind auf Deutsch. Die ausführliche Entwickler-/Strategie-Dokumentation steht in CLAUDE.md und docs/.

Überblick

  • server.py + core/engine.py — headless FastAPI-Web-Backend, das die Mobile-PWA in web/ bedient (Zugriff vom Handy z. B. via WireGuard).
  • Eine Oberfläche: die PWA. Das frühere Tkinter-Widget wurde entfernt.
  • ⚠ Immer nur eine Server-Instanz gegen dasselbe MT5-Terminal laufen lassen (zwei TrailingManager = Konflikt).

Architektur (core/)

Modul Aufgabe
mt5data.py Preis / Trend / Konto
trader.py Orders + SL/TP
trailing.py Trailing / Teil-Exit / Time-Stop
wave_rec.py Empfehlung (EMA12/50-Trendfolge, Squeeze-Breakout, Gates)
elliott.py Elliott-Wellen / FVG
structure.py Marktstruktur (HH/HL/LH/LL, BOS, Regressionskanal — Anzeige)
daily_levels.py Tages-Prognose (Web-Recherche)
gaps.py D1-Kurslücken
candle_logger.py M1-Candle-Log → candles_m1
agent.py KI-Copilot (LLM)
history.py SQLite-Persistenz
config.py Konstanten + oil_widget_config.ini-Loader
engine.py headless Motor: fährt die Loops als Threads, liefert snapshot()

engine._verdict() aggregiert die Module zur Gesamtempfehlung (verdict im Snapshot) — Details: docs/gesamtempfehlung.md.

Voraussetzungen

  • Windows (das MetaTrader5-Python-Wheel ist Windows-only; das Backend läuft neben dem MT5-Terminal).
  • Python 3.12 mit fastapi, uvicorn, MetaTrader5 (+ weitere Abhängigkeiten, die die Module importieren).
  • Ein laufendes MetaTrader-5-Terminal mit dem WTI-Symbol des Brokers (z. B. SpotCrude bei Pepperstone).

Einrichtung

  1. Repo klonen.
  2. Config-Vorlage kopieren und mit echten Keys füllen:
    cp oil_widget_config.ini.example oil_widget_config.ini
    
    Dann oil_widget_config.ini ausfüllen (LLM-/News-/Telegram-/Graph-Keys, WTI-Symbol, Trading-Schalter). Diese Datei enthält Live-Secrets und ist per .gitignore vom Repo ausgeschlossen — niemals committen. Erläuterungen zu allen [trading]-Schaltern stehen als Kommentare in core/config.py.
  3. MT5-Terminal starten und einloggen.

Starten

# Änderungen aktivieren / Server (neu) starten:
restart_server.bat

Auto-Start ist als Windows-Aufgabe OilTradingServer (Login-Trigger, versteckt via VBS) eingerichtet. Die PWA ist danach unter http://<host>:8000/ erreichbar.

Strategie in Kürze

  • Richtung = EMA12 vs. EMA50 (wave_rec.py), mit Totband, Anti-Überdehnung, S/R- und Session-Konfidenz.
  • Volatilitäts-Squeeze-Breakout = additiver, backtest-validierter Auto-Entry (Kompression → Ausbruch); optional autonom (auto_squeeze).
  • Gates: ATR-Breakout-Bestätigung, Entry-Raum, Mindest-Konfidenz, Higher-TF- Gegen-Trend, EIA-Blackout.
  • Exit: SL-Band ~2×ATR, Breakeven ab +1,3×ATR, Trailing, Time-Stop, sowie ein kalibriertes P(Durchbruch)-Modell für den S/R-Close am Gegenlevel.

Methodik: Strategie-Änderungen werden per 2-Stichproben-Backtest (zwei Zeiträume/Regime) mit echten Kosten belegt, bevor sie live gehen — „erst messen, dann umbauen". Die zahlreichen backtest_*.py-Skripte dokumentieren geprüfte und verworfene Ideen.

Nützliche Skripte

Befehl Zweck
python backtest_signal.py [TF] [N] [K] Empfehlungs-Edge messen (ereignisbasiert)
python analyze_execution.py Spread-/Slippage-/MAE-MFE-Kalibrierung
python weekly_review.py Wochenreport (Live-Stats vs. Backtest-Erwartung)
python -m py_compile <datei> Syntaxprüfung vor „fertig"

Web-Assets

Der Browser cacht hart: bei jeder JS/CSS-Änderung in web/index.html die Asset-Version ?v=N hochzählen. Der Server sendet Cache-Control: no-store.

Datenhaltung

  • oil_widget_history.db (SQLite): trades, recommendations, candles_m1 u. a. Nicht im Repo (per .gitignore) — vor Eingriffen Backup (*.bak-<datum>).
  • Laufzeit-State (emergency_state.json, runtime_state.json, report_state.json) wird vom Server erzeugt und ist ebenfalls nicht versioniert.

Lizenz

Privates Projekt — keine Lizenz vergeben.

S
Description
No description provided
Readme
88 MiB
Languages
Python 87.2%
JavaScript 5.2%
MQL5 3.4%
CSS 1.9%
HTML 1.5%
Other 0.8%