Fuenf User-Vorgaben in einem Durchgang.
(1) HYPERLIQUID + MUSTER + TRAILING AUS DER MELDUNGEN-KARTE. Die drei Divs sind
ENTFERNT, nicht nur versteckt; die Render-Bloecke bleiben stehen (null-sicher),
damit ein Zurueckholen eine reine HTML-Aenderung ist. Backend rechnet
unveraendert weiter (hl_ctx, patterns_tf, trail_info stehen im Snapshot).
Stufe F bekam eine dokumentierte Ausnahmeliste - sonst haette sie drei
Dauer-Treffer gemeldet, und eine Pruefung mit Dauer-Treffern wird ignoriert.
⚠⚠ DABEI ZWEI ECHTE ABSTUERZE GEFUNDEN - und der Weg dahin ist der Punkt.
`hl-note` wurde ueber das Auffang-`$` geholt; nach dem Entfernen des Elements
griffen ZWEI Zweige ungeschuetzt auf `hlEl.classList` zu. Im Browser ein
TypeError mitten im Render = das GESAMTE Dashboard friert auf Altwerten ein.
Die Render-Probe blieb zunaechst GRUEN - ihr eigener blinder Fleck: die
DOM-Attrappe lieferte fuer JEDE ID ein Element, `$streng` konnte darin also NIE
`null` zurueckgeben. Genau der Fall, fuer den es `$streng` gibt, war ungeprueft.
Behoben: die Attrappe kennt jetzt die echten IDs aus index.html
(`getElementById: id => HTML_IDS.has(id) ? el() : null`) - und meldete die
beiden Zweige im selben Lauf. Danach beide Waechter ergaenzt.
(2) BILD-MODALBOX. Klick auf ein Chartmuster oeffnet es gross.
⚠⚠ BEWUSST OHNE BIBLIOTHEK: ein Lightbox-Paket waere 15-40 KB plus ein zweites
Bedienkonzept fuer ~30 Zeilen Code. Das Dashboard laeuft nur ueber WireGuard,
ein CDN ist gar nicht erreichbar; das Projekt hat aus demselben Grund Tailwind
abgelehnt und am 05.08. die vendorte lightweight-charts (164 KB) entfernt.
Delegierter Klick auf `document`, weil die Kacheln bei JEDEM Render neu erzeugt
werden - ein Handler am <img> waere nach dem naechsten Snapshot weg.
Grosse Fassung (1408 px, ~133 KB) liegt getrennt unter muster/gross/ und wird
ERST beim Klick geladen; die Kachel bleibt bei 25 KB. Esc und Klick auf den
Hintergrund schliessen.
(3) NEUES BILD gescannt: "Inverse Tasse+Henkel.jpg". `inv_cup` hatte bis dahin
ausdruecklich KEIN Bild ("lieber keins als ein falsches") - jetzt zugeordnet.
Damit 16 Muster, keins ohne Datei, keine Datei ohne Zuordnung.
(4) SCHRIFT IN DER TRADE-LEISTE um 2 px (bezogen auf die 18-px-Referenz)
verkleinert - 4 Regeln: Ueberschrift, Feldbeschriftungen, Werte/Eingaben,
Knoepfe.
⚠ Erster Versuch nahm alles zwischen `.tb-title{` und `.mg-row` und traf 80
Regeln statt 4 - die halbe Oberflaeche. Zurueckgesetzt und namentlich
aufgezaehlt. Ein Zeilenbereich ist kein Selektor.
(5) M15-KARTE PER DEFAULT EINGEKLAPPT. Das `open` am ersten <details> ist weg.
⚠ Zusaetzlich der localStorage-Schluessel gebumpt (oil_m15_akk -> oil_m15_akk2):
bei jedem, der die Karte je aufgeklappt hatte, stand dort `true`, und das
gewinnt gegen den neuen Default. Ein neuer Schluessel setzt genau EINMAL
zurueck; danach merkt sich die Karte die eigene Wahl wie bisher.
Pipeline A-G gruen, 97 Tests, 14 render*-Funktionen (Fixture UND leerer
Snapshot), deployt und am ausgelieferten HTML/JS verifiziert.
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.