Der offene Stand lag ueber sieben Konzepte, zwei Referenzdokumente und die
Phasen-Checkliste der Architektur verteilt. Dieselbe Aufgabe stand teils
doppelt unter zwei Namen - die asynchrone Fill-Verfolgung etwa als "bekannte
Grenze" in IBKR-Integration.md und zugleich als W-2 im OptionsWheel-Konzept.
Wer wissen wollte, was als Naechstes ansteht, musste alles neun lesen.
docs/ROADMAP.md fuehrt das zusammen:
- Fuenf Stufen in Abhaengigkeitsreihenfolge, von "Fundament schliessen" bis
zum OptionsWheel, dazu vier laufende Bahnen (Auslieferung, Accounting,
Supervisor, technische Schulden).
- Jede Zeile traegt ihre Herkunft (W-2, P5, Kapitalmodell 5, ...), damit die
Herleitung im Archiv auffindbar bleibt.
- Eigene Abschnitte fuer Zurueckgestelltes und Verworfenes. Zurueckgestellte
Ideen nennen ausdruecklich, WAS sie wieder aktuell macht; verworfene nennen
den Grund, damit sie nicht in sechs Monaten erneut vorgeschlagen werden.
- Erledigtes bleibt als Zeile mit Datum stehen statt zu verschwinden.
Archiv (git erkennt alle sieben als Umbenennung, Historie bleibt):
docs/konzepte/* -> docs/archiv/
docs/Kapital-und-Buchmodell.md -> docs/archiv/
Jedes archivierte Dokument bekommt oben einen Vermerk, warum es erhalten bleibt
und wo der lebende Stand steht. Inhaltlich ist keines veraendert.
Weiter gepflegt werden ARCHITECTURE.md (Aufbau + Phasen-Historie),
IBKR-Integration.md (Adapter-Design und Grenzen) und die TWS-Setup-Checkliste -
das sind Referenzen, keine Planung. Ihre eigenen Offen-Listen verweisen jetzt
mit Roadmap-Kennung dorthin, statt einen zweiten Stand zu fuehren.
Alle 63 relativen Markdown-Links geprueft, keiner tot. Fuenf Pfadverweise in
Code, csproj und systemd-Unit mitgezogen; die Unit zeigte auf die
Portierungsanalyse, die ausdruecklich den Stand VOR dem Umbau beschreibt - jetzt
auf ARCHITECTURE.md. Build 0 Warnungen, 198/198 Tests gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Kopfloser Betrieb auf Linux
Der Dienst IBKRTrader.Daemon fährt Trading-Kern, Worker, Accounting, Supervisor, REST-API und
MCP-Light ohne Oberfläche. Er nutzt denselben Host-Aufbau wie die Desktop-Shell
(IBKRTrader.Hosting), damit beide Varianten nicht auseinanderlaufen.
Veröffentlichen
dotnet publish src/IBKRTrader.Daemon -c Release -r linux-x64 --self-contained false -o out/
Ergebnis: ~11 MB, ein ELF-Launcher IBKRTrader.Daemon, keine Windows-Abhängigkeiten.
Mit --self-contained true entfällt die Runtime-Installation auf dem Zielhost (dann ~80 MB).
Voraussetzungen auf dem Host
| Paket | Wofür | Pflicht? |
|---|---|---|
dotnet-runtime-10.0 |
Laufzeit | ja (außer bei --self-contained) |
libicu |
Kulturen und Zeitzonen-ID-Umrechnung | ja – siehe Warnung unten |
fonts-dejavu-core |
PDF-Export des Accounting-Moduls | nur für den PDF-Export |
mariadb-client |
mariadb-dump für den BackupWorker |
nur fürs DB-Backup |
ICU ist nicht optional. Ohne ICU (bzw. mit
InvariantGlobalization=true) passieren zwei Dinge – beide lautlos, ohne Fehlermeldung:
AppTimeZonekann Windows-Zeitzonen-IDs nicht mehr auflösen und fällt auf die Systemzeitzone zurück, im Container also meist UTC. Genau die Verschiebung von Buchungszeitstempeln, die wir beseitigt haben.- Der PDF-Export formatiert Beträge fest gegen
de-DE. Ohne ICU liefertCultureInfo.GetCultureInfo("de-DE")die invariante Kultur – aus1.234,56wird1,234.56, in einem Dokument, das als prüfbare Aufstellung gilt.Der Daemon setzt deshalb ausdrücklich
InvariantGlobalization=false.
Verzeichnisse
Die Anwendung schreibt in drei Verzeichnisse. Aufgelöst wird in dieser Reihenfolge:
- Umgebungsvariable —
IBKRTRADER_CONFIG_DIR,IBKRTRADER_DATA_DIR,IBKRTRADER_LOG_DIR - Neben der Binärdatei, wenn dort geschrieben werden darf (Entwicklung, portable Installation)
- Sonst FHS —
/etc/ibkrtrader,/var/lib/ibkrtrader,/var/log/ibkrtrader
| Verzeichnis | Inhalt |
|---|---|
| Config | settings.json, master.key, openrouter.key |
| Data | Backups/ |
| Logs | Textlog je Modul, JSONL je Tag |
Beim Start steht die tatsächliche Ablage im Log (Ablage: config=…, data=…, logs=…).
Einrichtung
sudo useradd --system --no-create-home --shell /usr/sbin/nologin ibkrtrader
sudo mkdir -p /opt/ibkrtrader /etc/ibkrtrader /var/lib/ibkrtrader /var/log/ibkrtrader
sudo chown -R ibkrtrader:ibkrtrader /var/lib/ibkrtrader /var/log/ibkrtrader /etc/ibkrtrader
sudo chmod 750 /etc/ibkrtrader
Master-Key ablegen (nicht in die Unit-Datei – die ist für alle lesbar):
sudo install -o ibkrtrader -g ibkrtrader -m 600 /dev/null /etc/ibkrtrader/master.key
Der Dienst warnt beim Start, wenn master.key oder openrouter.key für Gruppe oder andere
zugänglich sind — Windows-ACLs übertragen sich beim Kopieren auf einen Linux-Host nicht.
Dienst einrichten
sudo cp deploy/ibkrtrader.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now ibkrtrader
journalctl -u ibkrtrader -f
Vor dem ersten Start prüfen
/opt/ibkrtrader/IBKRTrader.Daemon --check
Baut den Host, fährt alle Startprüfungen (Zeitzone, Ablageorte, Master-Key, DB-TLS) und beendet sich — ohne Worker zu starten oder eine Verbindung zur Börse aufzubauen. Geeignet für Deployment-Skripte und CI.
/opt/ibkrtrader/IBKRTrader.Daemon --db-version
Gibt die MariaDB-Serverversion aus (für das EF-ServerVersion-Pinning).
Betriebszeitzone
Trading.ApplicationTimeZoneId in settings.json, IANA-Schreibweise:
| Instanz | Wert |
|---|---|
| EU | Europe/Berlin |
| US | America/New_York |
Vor den ersten Trades festlegen und danach nicht mehr ändern. Ein Wechsel verschiebt rückwirkend die Tagesgrenzen von Logs, Berichten und Buchungsperioden. Gespeichert wird immer UTC — nur so bleiben die Daten beider Instanzen vergleichbar.
Was der Daemon nicht löst
Das IB Gateway ist eine Java-Anwendung mit Oberfläche. Für den Dauerbetrieb ohne Bildschirm braucht es IBC plus Xvfb, dazu die Behandlung des täglichen Neustarts und des 2FA-Handlings — eine eigene Baustelle, unabhängig von diesem Dienst. Alternative: das Gateway bleibt auf dem Windows-Rechner, der Linux-Dienst verbindet sich über Port 4002. Dann muss in der TWS-Konfiguration die erlaubte Client-IP eingetragen sein; der TWS-API-Verkehr ist unverschlüsselt und gehört nicht über ein unvertrautes Netz.