User: "trailing scheint nicht zu funktionieren wenn man es einmal manuell
aktiviert hat und dann wieder einschaltet."
AM LOG UND AM ZUSTAND NACHGEPRUEFT - es lief die ganze Zeit:
19:30:52 Manuelle SL/TP-Aenderung erkannt (SL 87.297) -> Trailing abgeschaltet
19:31:01 AKTIVIERT ATR=0.5689 (M30) mult=1.0x
danach phase=Init, HW 87.39, enabled=true, trail_mult=1.0
`toggle()` setzt alles sauber zurueck (High-Water, Phase, _last_sl/_last_tp,
TF und Mult werden neu eingefroren). Es war KEIN Defekt.
WARUM ES TROTZDEM NICHTS TAT - zwei Gruende, beide korrekt:
(a) Phase "Init": der Trail springt erst ab `trail_start` an, und der steht
seit HEUTE auf 1,3xATR (war 0,3). Der Gewinn lag bei 0,13xATR - also
Faktor 10 zu frueh. Wer die alte Einstellung gewohnt ist, erwartet den
Trail zehnmal frueher als er kommt.
(b) Er lockert einen Stop NIE. Nach der Handeingabe lag der SL bei 87.300,
der Trail haette HW-1,0xATR = 86.821 gewollt - deutlich schlechter. Also
zu Recht keine Aenderung. Um 87.300 zu schlagen, braeuchte es HW >= 87.869.
DER EIGENTLICHE MANGEL WAR DIE SICHTBARKEIT: die Trailing-KARTE ist seit dem
22.07. ausgeblendet (User-Vorgabe). Damit gab es KEINE Stelle mehr, an der man
Phase, High-Water oder den gewollten Stop sehen konnte - "es tut nichts" und
"es wartet zu Recht" sahen identisch aus.
GEBAUT: `engine._trail_info()` -> Snapshot `trail_info` -> Zeile `#trail-note`
in der Meldungen-Karte. Live:
"Trailing wartet - springt ab 1.3xATR Gewinn an (jetzt 0.38x, also ab Kurs
88.054)."
Drei weitere Zustaende: "Trailing AUS - nur der Broker-SL schuetzt", "laeuft,
zieht aber NICHT nach: sein Stop waere X, der gesetzte Y ist enger", und
"laeuft - zieht den Stop auf X nach".
⚠ Nur ZUSAMMENGESETZT aus dem, was der Snapshot ohnehin enthaelt - kein
zweiter Rechenweg (der Konsens-Pfeil-Fehler).
⚠⚠ BEINAHE-FEHLER beim Bau, gefangen: der Block landete in `renderKontext(snap)`,
mein Code las aber `d.trail_info`. Ein ReferenceError haette den GESAMTEN Render
abgebrochen (Dashboard friert auf Altwerten ein) - genau die Klasse, die am
01.08. schon einmal zugeschlagen hat. `node --check` sieht das NICHT. Gefunden,
weil ich die umgebende Funktion nachgelesen habe, und danach mit einem
Minimal-DOM gegengeprueft (snap / leer / null - alle drei laufen durch).
NEBENBEI: der Kommentar an `_TRAIL_START_ATR` sagte weiterhin "0,3", der Wert
ist 1,3. Genau diese Zahl macht den Unterschied, um den es hier geht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.mdunddocs/.
Überblick
server.py+core/engine.py— headless FastAPI-Web-Backend, das die Mobile-PWA inweb/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.
SpotCrudebei Pepperstone).
Einrichtung
- Repo klonen.
- Config-Vorlage kopieren und mit echten Keys füllen:
Dann
cp oil_widget_config.ini.example oil_widget_config.inioil_widget_config.iniausfüllen (LLM-/News-/Telegram-/Graph-Keys, WTI-Symbol, Trading-Schalter). Diese Datei enthält Live-Secrets und ist per.gitignorevom Repo ausgeschlossen — niemals committen. Erläuterungen zu allen[trading]-Schaltern stehen als Kommentare incore/config.py. - 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_m1u. 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.