Files
IBKRTrader/deploy
RichardandClaude Opus 5 9f66183f1c
Build & Test / build (ubuntu-latest) (push) Waiting to run
Build & Test / build (windows-latest) (push) Waiting to run
Eine Roadmap statt sieben Konzepte; Quelldokumente ins Archiv
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>
2026-08-23 18:14:51 +02:00
..

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:

  1. AppTimeZone kann 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.
  2. Der PDF-Export formatiert Beträge fest gegen de-DE. Ohne ICU liefert CultureInfo.GetCultureInfo("de-DE") die invariante Kultur aus 1.234,56 wird 1,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:

  1. Umgebungsvariable — IBKRTRADER_CONFIG_DIR, IBKRTRADER_DATA_DIR, IBKRTRADER_LOG_DIR
  2. Neben der Binärdatei, wenn dort geschrieben werden darf (Entwicklung, portable Installation)
  3. 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.