Files
IBKRTrader/docs/ROADMAP.md
T
RichardandClaude Opus 5 b221e0447b
Build & Test / build (ubuntu-latest) (push) Canceled after 0s
Build & Test / build (windows-latest) (push) Canceled after 0s
Roadmap: Begruendungen zu Waehrungsfaehigkeit, #479 und #480
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 15:50:51 +02:00

719 lines
42 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IBKRTrader – Roadmap
> **Der Planungsstand steht nicht mehr in dieser Datei.** Er liegt seit dem 2026-08-30 im
> Deploymentcenter, Projekt `ibkrtrader` – dort, wo auch Fehler und Zuständigkeiten geführt werden.
> Zwei Pfleger für dasselbe Feld waren der Grund, warum die alte Fassung an drei Stellen behauptete,
> etwas sei offen, das längst erledigt war.
>
> **Die Arbeitsteilung:** Status, Reihenfolge, Zielfassung und Bearbeiter kommen aus dem
> Deploymentcenter (`dc_roadmap`, WebUI). Begründung, Auslöser und Herleitung stehen hier.
>
> Der Block zwischen den `dc:roadmap`-Markern ist eine **erzeugte Kopie** und darf älter sein als
> der echte Stand. **Dort niemals von Hand etwas ändern** – der nächste Lauf überschreibt es. Alles
> außerhalb der Marker ist von Hand und bleibt.
>
> Die Kennung ist die **Item-ID** aus dem Deploymentcenter (`#289`), nicht mehr `B1` oder `W-2`.
> Handvergebene Kennungen wurden nach einer Löschung neu vergeben und meinten dann etwas anderes;
> eine Item-ID wird nie zweimal vergeben. Der Themenbuchstabe bleibt – aber nur als Gruppe: `[B]`.
>
> **Ein neues Vorhaben entsteht immer zuerst im Deploymentcenter** (`dc_report`), dann erscheint es
> im Block, dann schreibt man die Begründung darunter. Ein Punkt, der nur in dieser Datei steht,
> ist keine eingeplante Arbeit – er taucht in keiner Arbeitsschlange auf und wird nie übernommen.
**Übernommen am 2026-08-30** – 57 Einträge, 10 Themenbereiche. Die alte Fassung mit handgepflegten
Statustabellen steht in der Git-Historie (bis Commit `9f66183`).
---
## Wo wir stehen
Gebaut und grün: Multi-Projekt-Aufbau nach PolytraderSharp, Generic Host, EF Core, Trading-Kern,
drei Module (CongressTrading, Accounting, Supervisor), Avalonia-Oberfläche auf Windows **und**
Linux, kopfloser Daemon, Deploymentcenter-Anbindung. 198 Tests, Build ohne Warnungen.
Nicht gebaut: **Es hat noch nie eine echte Order gegeben.** Der Broker-Adapter ist gegen das
Paper-Konto verifiziert – Verbindung, Konto, Kurse, Optionskette, Greeks, What-If-Order – aber
`PlaceOrderAsync` mit echter Ausführung steht aus (**#293**). Alles, was danach kommt
(Fill-Buchung, Kapitalmodell, OptionsWheel), hängt an diesem einen Nachweis.
**Was der erste Betriebstest ergeben hat (2026-08-31).** Der Stand `9f66183` wurde auf der
Linux-Test-VM gebaut und gefahren, ohne die Testkrücken des Aufbaus – also so, wie er ausgeliefert
würde. Build ohne Warnungen, 198 Tests grün, `--smoke-ui` alle neun Fenster, Launcher und
Workers-Ansicht rendern unter Xvfb. Der Dauerlauf hat dann zehn Fehler zutage gefördert, sechs
davon in `[X]`. Der Kern: **Was das System über sich selbst meldet, stimmt nicht.** Ein toter
Worker zeigt einen nächsten Lauf an, ein fehlgeschlagenes Backup meldet „OK", und `--check` bestätigt
eine Datenbank, die es nie kontaktiert hat. Das ist keine Ansammlung von Einzelfehlern, sondern ein
Muster – und es trifft ausgerechnet die Anzeigen, an denen man einen unbeaufsichtigten Betrieb
ablesen würde.
**Der Regelkreis steht seit dem 2026-08-31.** Werkbank- und Laufzeit-Token sind ausgestellt
(#315), der Heartbeat der Testinstanz läuft (`ibkrtrader-linuxtest` / `linuxtest-vm`), und die
Detektoren des Deploymentcenters arbeiten darauf. Der Fehler-Stream ist wieder **abgeschaltet**,
bis #403 behoben ist – sonst schreibt der Testaufbau in die Produktivmeldungen.
Zwei Sicherungen sind absichtlich getrennt und beide stehen auf „aus": `IBKR.UseTwsApi` schaltet
den Adapter, `TradingEnabled` den Handel.
---
## Die Reihenfolge – warum diese und keine andere
Die Rangfolge im Deploymentcenter (`roadmap_rank`) bildet fünf Stufen ab. Sie stehen hier als
Prosa, weil sie eine Begründung sind und keine Statusspalte.
**Stufe 0 – Was im Betrieb nachweislich nicht trägt.** Themenbereich `[X]`, Rang 1 bis 6. Diese
Punkte stammen nicht aus einer Planung, sondern aus einem Testlauf gegen den ausgelieferten Stand
auf der Linux-VM am 2026-08-31. Sie stehen vor Stufe 1, weil sie die Stufen darunter unprüfbar
machen: Ein Worker, der still stirbt, und ein Backup, das Erfolg meldet, ohne eines zu sein,
verfälschen jede spätere Messung. Solange sie offen sind, sagt ein grünes Dashboard nichts aus.
**Stufe 1 – Fundament schließen.** `#289`, `#290`, `#291`, `#292`, `#293`. Diese Punkte blockieren
oder gefährden alles Weitere. Zwei davon sind Sicherheitsschulden, die durch Warten nur teurer
werden: ein Passwort und ein Token, die beide bereits in einer Historie stehen.
**Stufe 2 – Den Handelspfad belastbar machen.** `#294`, `#295`, `#296`, `#297`. Ohne das ist kein
unbeaufsichtigter Betrieb zu verantworten.
**Stufe 3 – Options-Fundament im Core.** `#298` bis `#301`. Reine Core-Arbeit, nützt allen Modulen,
nicht nur dem Wheel. Der Aktienpfad bleibt unverändert – neue Felder sind optional, `Kind = Stock`
ist der Default.
**Stufe 4 – Kapital- und Buchmodell.** `#302` bis `#308`. Wird scharf, sobald ein **zweites** Modul
handelt. Heute handelt nur CongressTrading; mit dem Wheel sind es zwei, die sich ein Konto und ein
Guthaben teilen. Das vollständig ausgearbeitete Konzept liegt im
[Archiv](archiv/Kapital-und-Buchmodell.md) – es ist die Referenz, gegen die die Umsetzung geprüft
wird, und war nie umgesetzt.
**Stufe 5 – Modul OptionsWheel.** `#309` bis `#314`. Erst ab hier entsteht das Modul selbst.
Vollautomatisch von Anfang an – Sicherungen sind Schalter und Limits, keine Klick-Freigabe.
Strike-Wahl delta-basiert im Band 0,15–0,30. Nur Watchlist, kein Screening.
**Laufende Bahnen** hängen an keiner Stufe und können jederzeit dazwischen laufen: Auslieferung
(`[D]`), Accounting (`[A]`), Supervisor (`[S]`), technische Schulden (`[T]`).
---
<!-- dc:roadmap stand=2026-09-01T07:48Z items=68 projekt=ibkrtrader -->
<!-- ERZEUGT - nicht von Hand aendern. Dieser Block wird bei jedem Lauf von
`php cli/roadmap.php --write` ueberschrieben. Der Zustand wird im
Deploymentcenter gepflegt, nicht hier. Prosa gehoert AUSSERHALB der
Marker - dort bleibt sie unberuehrt. -->
### Als Naechstes
1. **[X] #388 — WorkerBase: Intervall ueber 24,85 Tage toetet den Worker still und reisst beim Herunterfahren den Prozess mit**
2. **[X] #390 — Fehlgeschlagener DB-Dump gilt als erfolgreicher Backup-Lauf**
3. **[X] #389 — BackupWorker sichert eine andere Datenbank als die, mit der die Anwendung arbeitet**
4. **[X] #391 — --check meldet "Pruefdurchlauf OK", ohne die Datenbank je zu erreichen**
### X — Kritische Bugs
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #388 | WorkerBase: Intervall ueber 24,85 Tage toetet den Worker still und reisst beim Herunterfahren den Prozess mit | 📋 Offen | — |
| #390 | Fehlgeschlagener DB-Dump gilt als erfolgreicher Backup-Lauf | 📋 Offen | — |
| #389 | BackupWorker sichert eine andere Datenbank als die, mit der die Anwendung arbeitet | 📋 Offen | — |
| #391 | --check meldet "Pruefdurchlauf OK", ohne die Datenbank je zu erreichen | 📋 Offen | — |
| #394 | CapitolTrades-Scraper behandelt 429 nicht - beide CT-Worker fallen bei jedem Lauf aus | 📋 Offen | — |
| #396 | Die Shell reagiert unter Linux nicht auf SIGTERM - kein geordnetes Herunterfahren ausserhalb des Fensters | 📋 Offen | — |
### B — Betrieb und Sicherheit
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #289 | DB-Passwort der produktiven MariaDB rotieren | 📋 Offen | — |
| #290 | Gitea-Zugangstoken aus der Remote-URL nehmen | 📋 Offen | — |
| #291 | EF-Schema auf die Datenbank anwenden | 📋 Offen | — |
### H — Handelspfad (TWS-Broker-Adapter)
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #293 | PlaceOrderAsync gegen das Paper-Konto verifizieren | 📋 Offen | — |
| #294 | Asynchrone Order- und Fill-Verfolgung | 📋 Offen | — |
| #295 | IBKR-Zugangsdaten mit EncryptedStringConverter ablegen | 📋 Offen | — |
| #296 | IBC/IBController einrichten (Auto-Login, taeglicher Gateway-Neustart) | 📋 Offen | — |
### O — Options-Fundament im Core
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #298 | InstrumentKind/OptionSpec, IbkrMapping.Option, Positionen mit Multiplikator | 📋 Offen | — |
| #299 | Optionskette und Greeks im Core (reqSecDefOptParams, tickOptionComputation) | 📋 Offen | — |
| #300 | Positionsabgleich bei Zuteilung/Verfall und RiskService um sell-to-open erweitern | 📋 Offen | — |
| #301 | IV-Rank als Core-Baustein | 📋 Offen | — |
### K — Kapital- und Buchmodell
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #302 | Buecher und Eigentumsregeln | 📋 Offen | — |
| #303 | Ein Pool, Obergrenzen | 📋 Offen | — |
| #304 | Margin-Sperre in vier Schichten | 📋 Offen | — |
| #305 | Reservierungen ueber den Order-Lebenszyklus inkl. Crash-Recovery | 📋 Offen | — |
| #306 | Abgleich (Reconciliation) gegen den Broker | 📋 Offen | — |
| #307 | Benachrichtigungen ueber Outbox und Sink-Abstraktion | 📋 Offen | — |
| #308 | Startwerte festlegen und in settings.example.json dokumentieren | 📋 Offen | — |
| #331 | Self-Cross-Netting (Modul A kauft, Modul B verkauft dasselbe Symbol) | 🧊 Zurueckgestellt — Ausloeser: die Warnung im Order-Gateway tatsaechlich anschlaegt | — |
| #332 | Corporate Actions (Splits, Spin-offs) in der Buchzuordnung | 🧊 Zurueckgestellt — Ausloeser: ein Break durch eine Kapitalmassnahme real auftritt | — |
| #336 | Echte IBKR-Sub-Accounts (Advisor-/Family-Struktur) zur Trennung der Buecher | ❌ Verworfen | — |
### W — Strategiemodule
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #309 | OptionsWheel: Modul-Geruest | 📋 Offen | — |
| #310 | OptionsWheel: reine Strategie-Logik und Tests | 📋 Offen | — |
| #311 | OptionsWheel: Verdrahtung und vollautomatischer Paper-Betrieb | 📋 Offen | — |
| #312 | OptionsWheel: Earnings-Sperre ueber den IV-Behelf | 📋 Offen | — |
| #314 | OptionsWheel: Live-Freigabe | 📋 Offen | — |
| #327 | Trendfolge-/Momentum-Modul auf Tagesbasis als zweites Standbein | 🧊 Zurueckgestellt — Ausloeser: das OptionsWheel im Paper-Betrieb laeuft UND das Kapital- und Buchmodell (Stufe 4) steht | — |
| #338 | Fundamentales Screening (Value, Quality, Growth) | ❌ Verworfen | — |
| #339 | Earnings-Strategien (Straddle vor Zahlen, Post-Earnings-Drift) | ❌ Verworfen | — |
| #340 | Marktweite Anomalie-Suche / Screener-getriebene Auswahl | ❌ Verworfen | — |
| #341 | Daytrading, Scalping, Orderbuch-Strategien | ❌ Verworfen | — |
| #342 | Gap-Strategien auf Eroeffnung | ❌ Verworfen | — |
| #343 | Strike-Wahl ueber prozentualen Abstand statt delta-basiert | ❌ Verworfen | — |
### D — Auslieferung und Deploymentcenter
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #292 | CI wieder gruen bekommen (SDK als PackageReference statt Cross-Repo-Pfad) | 📋 Offen | — |
| #315 | Tokens fuer ibkrtrader vervollstaendigen | 📋 Offen | — |
| #316 | Update-Anwenden verdrahten | 📋 Offen | — |
| #317 | Erstes echtes Release fahren | 📋 Offen | — |
| #318 | Deploymentcenter-Baustein in die Projektdatei aufnehmen | ✅ Erledigt | — |
| #319 | Lizenzfenster fuer die Shell | 📋 Offen | — |
| #334 | Desktop-Distribution der Shell ueber die Release-Pipeline | 🧊 Zurueckgestellt — Ausloeser: die Shell auf fremden Rechnern laufen soll | — |
### A — Modul Accounting
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #313 | Accounting-Anschluss fuer Optionen | 📋 Offen | — |
| #320 | Live-IBKR-Flex-Abruf und Balance-Anker | 📋 Offen | — |
| #321 | EZB-FX-Ingest (acc_fx_rates fuellen) | 📋 Offen | — |
| #322 | Steuerschicht: Jurisdiktionsprofil festlegen | 📋 Offen | — |
| #345 | Modulzuordnung als Korrektur des Steuerbuchs | ❌ Verworfen | — |
### S — Modul Supervisor
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #323 | Counterfactual-Kursaufloesung fuer Aktien | 📋 Offen | — |
| #324 | Externer Versand des Tagesberichts | 📋 Offen | — |
| #344 | Agent-zu-Agent-Orchestrierung im Supervisor | ❌ Verworfen | — |
### M — Marktdaten und externe Quellen
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #328 | Marktdaten-Abo US-Realtime (NYSE/AMEX/NASDAQ) | 🧊 Zurueckgestellt — Ausloeser: wir Screening oder Intraday-Strategien wollen | — |
| #329 | OPRA-Abo (Optionen-Realtime) | 🧊 Zurueckgestellt — Ausloeser: die Ausfuehrungsqualitaet im Paper-Betrieb messbar stoert | — |
| #330 | Refinitiv-Fundamentaldaten | 🧊 Zurueckgestellt — Ausloeser: der IV-Behelf der Earnings-Sperre sich als zu unscharf erweist | — |
| #335 | Ungepruefte Datenfragen der TWS API klaeren | 🧊 Zurueckgestellt — Ausloeser: eine Strategie eine der Fragen braucht - die Ratenbegrenzung schon bei einem naechtlichen Watchlist-Abruf | — |
### T — Technische Schulden und Entscheidungen
| | Vorhaben | Stand | Ziel |
|---|---|---|---|
| #297 | Entscheiden, welcher IBKR-Zugangsweg bleibt | 📋 Offen | — |
| #325 | Log-Level ist nicht konfigurierbar | 📋 Offen | — |
| #326 | Diagramme einloesen oder die Avalonia-11-Pinnung aufgeben | 📋 Offen | — |
| #392 | Der Daemon schreibt jede SQL-Anweisung von EF Core auf stdout | 📋 Offen | — |
| #393 | Workers-Ansicht: die Spalte "Aktiv" ist wirkungslos - Worker lassen sich zur Laufzeit nicht abschalten | 📋 Offen | — |
| #395 | "Letzter Lauf" bleibt bei einem fehlgeschlagenen Worker-Lauf leer | 📋 Offen | — |
| #403 | Die Umgebung des Fehler-Streams steht fest im Kompilat - jede Release-Fassung meldet "production" | 📋 Offen | — |
| #409 | --smoke-ui braucht unter Linux doch ein Anzeigegeraet und ist damit nicht CI-tauglich | 📋 Offen | — |
| #333 | Web-UI ueber die interne REST-API | 🧊 Zurueckgestellt — Ausloeser: Fernzugriff auf eine laufende Instanz noetig wird | — |
| #337 | InvariantGlobalization=true fuer ein schlankes Linux-Image | ❌ Verworfen | — |
<!-- /dc:roadmap -->
---
## Begründungen
*Nicht jedes Vorhaben braucht eine – die meisten sind eine Zeile im Block wert und mehr nicht.
Hier steht, was eine Tabellenzelle nicht trägt.*
### [X] #388 — WorkerBase: Intervall über 24,85 Tage tötet den Worker still
`SemaphoreSlim.WaitAsync(TimeSpan)` nimmt höchstens `int.MaxValue` Millisekunden – rund 24,85 Tage.
`WorkerBase.RunLoopAsync` reicht die Restzeit ungeprüft durch. Zwei **ausgelieferte Vorgaben**
liegen darüber: `InstrumentSyncWorker` mit 43.200 Minuten und `CongressHistoryImportWorker` mit
365 Tagen.
Das Bemerkenswerte ist nicht der Fehler, sondern seine Unsichtbarkeit. Die Ausnahme fällt weder in
den `try/catch` von `RunOnceAsync` noch in das `catch (OperationCanceledException)` der
Warteschleife. Der Task faultet, der Worker ist tot, geloggt wird nichts, und die Workers-Ansicht
zeigt weiter einen „Nächsten Lauf" an – für den `CT-HistoryImport` einen im Jahr 2027.
Beim Herunterfahren kommt die gespeicherte Ausnahme zurück: `StopAsync` awaitet den Task und fängt
nur `OperationCanceledException`. Sie läuft bis in `Program.Main` durch und beendet den Prozess mit
Exitcode 134. Damit erreicht der Daemon weder `StopModulesAsync` noch die Zeile „IBKRTrader
beendet." – unter systemd ist **jedes** Stoppen ein Fehlschlag. Dreimal nachgestellt, zuletzt nach
4,5 Stunden Dauerlauf.
Die Testkrücken auf der VM (`FromDays(7)`, `IntervalMinutes 1440`) umgehen genau das und gehören
nach der Behebung wieder heraus.
### [X] #390 und #389 — Das Backup meldet Erfolg, ohne eines zu sein
Zwei getrennte Fehler, die sich gegenseitig verdecken.
**#390 ist der gefährlichere.** `RunMysqlDumpAsync` behandelt einen Exitcode ungleich 0 mit
`Logger.Warn` und kehrt normal zurück; fehlt das Dump-Werkzeug ganz, wird nur „übersprungen"
protokolliert. `ExecuteAsync` läuft durch, `core_worker_log` trägt `Success`, die Workers-Ansicht
zeigt „OK". Im Log stehen die beiden Zeilen direkt untereinander:
```
Warn : mariadb-dump Exitcode 2: ... "Unknown server host 'your-db-host'" when trying to connect
Info : Backup abgeschlossen: 2026-08-31_14-30
```
**#389 ist die Ursache dieses konkreten Fehlschlags.** Es gibt zwei Datenbank-Konfigurationen:
`Database:MySqlConnectionString` aus `appsettings*.json` – daran hängen EF und alle drei Module –
und `AppSettings.Database` aus `settings.json`, aus der sich `BackupWorker` und `DbVersion`
bedienen. Nichts erzwingt, dass beide dasselbe meinen; die Vorgabe der zweiten ist der Platzhalter
`your-db-host`. Eine Installation kann also monatelang sauber laufen und dabei kein einziges
brauchbares Backup haben. Die Grundregeln sagen „Zugangsdaten NUR in settings.json" – die
maßgebliche Verbindung liegt tatsächlich woanders.
Reihenfolge mit Absicht: **erst #390, dann #389.** Ein Worker, der über Erfolg lügt, verdeckt jedes
weitere Backup-Problem, auch die, die nach #389 noch kommen.
### [X] #391 — `--check` erreicht die Datenbank nie
Der Schalter ist als Trockenlauf „für Deployment und CI" dokumentiert und soll laut Kommentar die
„DB-Verbindungszeichenfolge" prüfen. Er prüft den *String*, nicht die *Verbindung*: `RunStartupChecks`
baut den Host, sieht sich Dateirechte an und schaut nach, ob „SslMode" im Text vorkommt. Gegen
`Server=127.0.0.1;Port=3999;Database=gibtsnicht` meldet er `=== Prüflauf OK ===` und Exitcode 0.
Zweiter Punkt derselben Sache: Die Warnungen der Startprüfungen gehen nur in die Logdatei. Ein
CI-Schritt, der Exitcode und Ausgabe auswertet – der einzige Grund, warum es diesen Schalter gibt –
sieht davon nichts.
### [X] #394 — CapitolTrades antwortet mit 429, und niemand fängt es auf
Am 2026-08-27 und am 2026-08-31 dasselbe Bild, unabhängig von der Tageszeit: beide CT-Worker
scheitern bei **jedem** Lauf. `EnsureSuccessStatusCode` wirft, es gibt keinen Backoff, kein
`Retry-After`, keine Pause zwischen den Seiten – und beide Worker starten gleichzeitig gegen
dieselbe Seite. Der ScrapeWorker versucht es alle 30 Minuten unverändert erneut.
Damit fördert das erste und bislang einzige Strategiemodul keine Daten. Ob die Sperre an der
Abrufrate hängt oder daran, dass die Gegenstelle den Vorgabe-`User-Agent` erkennt, ist **nicht
geklärt** – das gehört vor jede Änderung an der Frequenz.
### [X] #396 — Die Shell ignoriert SIGTERM
`StartWithClassicDesktopLifetime` blockiert in der Avalonia-Nachrichtenschleife; das geordnete
Herunterfahren liegt im `finally` darum und wird nur erreicht, wenn das letzte Fenster geschlossen
wird. Ein POSIX-Signal fängt niemand ab. Zweimal nachgestellt: Nach `kill -TERM` läuft der Prozess
unverändert weiter.
Auf Linux heißt das: Beim Abmelden und beim Herunterfahren wird die Shell nach Ablauf der Frist mit
SIGKILL abgeräumt. Modul-Stopp und Host-Stopp laufen nie, offene Einträge in `core_worker_log`
bleiben auf „Running" stehen. Der Daemon macht es richtig – er behandelt SIGTERM über
`WaitForShutdownAsync`; nur die Shell nicht.
### [T] #403 — Die Umgebung des Fehler-Streams steht im Kompilat
`DcErrorReporter` legt sie als Konstante fest: `#if DEBUG` heißt „development", sonst „production".
Die Wahl fällt damit beim Bauen statt beim Betreiben, und ein Testaufbau soll ja gerade das
Kompilat prüfen, das ausgeliefert wird. Am 2026-08-31 hat die Test-VM darum drei Fehler als
`production` in den Bugtracker gestellt. Die Umgebungen `staging` und `testing`,
die der Bugtracker kennt, sind aus der Anwendung heraus gar nicht erreichbar.
### [D] #292 — CI wieder gruen bekommen (SDK als PackageReference statt Cross-Repo-Pfad)
Das Deploymentcenter-SDK hängt als Cross-Repo-`ProjectReference` am Schwester-Repo;
`.gitea/workflows/build.yml` checkt nur IBKRTrader aus, also ist der CI-Lauf seit dem 2026-08-23
rot. Das war die bewusst in Kauf genommene Folge der Interimslösung.
Es kostet mehr als einen roten Haken. Am 2026-08-30 stellte sich heraus, dass die tatsächlich
kompilierte SDK-Fassung längst auf **2.6.0** stand, während überall „2.5.1" dokumentiert war –
gewandert durch ein `git pull` im Schwester-Repo, ohne eine einzige Änderung auf unserer Seite.
Ein `changelog?since=2.5.1` fragt dann nach dem falschen Ausgangspunkt. Ein `PackageReference` mit
fester Versionsnummer beendet beides auf einmal.
### [H] #294 — Asynchrone Order- und Fill-Verfolgung
`PlaceOrderAsync` ist synchron gedacht: Ausführung oder Fehlschlag innerhalb
`OrderTimeoutSeconds`. Eine Limit-Order im Buch oder eine Market-Order außerhalb der Handelszeiten
gilt damit als Fehlschlag – **ist bei IBKR aber weiter aktiv.** Das ist kein Schönheitsfehler,
sondern der Fall, in dem unser Bild vom Konto und das echte Konto auseinanderlaufen.
Diese Aufgabe stand doppelt in zwei Konzepten: als Befund der IBKR-Integration und als `W-2` im
OptionsWheel-Konzept. Es ist dieselbe Arbeit. Sie ändert den Seam, deshalb kommt sie **vor**
Stufe 4 und Stufe 5, nicht parallel dazu.
### [O] #298 — InstrumentKind/OptionSpec, IbkrMapping.Option, Positionen mit Multiplikator
Heute rechnet `Position.Notional` als `Quantity × AvgPrice`. Bei Optionen ist das um Faktor 100
falsch – womit **jedes Risikolimit wirkungslos wäre**, und zwar lautlos und in die gefährliche
Richtung. Deshalb steht dieser Punkt vor allem anderen im Options-Fundament.
### [O] #300 — Positionsabgleich bei Zuteilung/Verfall und RiskService um sell-to-open erweitern
Zuteilung und Verfall ändern Positionen **ohne** Order von uns – ein Bestand, den niemand gekauft
hat. Zugleich lehnt `EvaluateSell` heute einen Verkauf ohne Bestand grundsätzlich ab, und genau das
ist die Kernoperation des Wheels.
**Niemals nackt:** Short Call nur mit 100 freien Aktien je Kontrakt, Short Put nur mit reserviertem
Cash über Strike × 100. Die Prüfung gehört in den **Core**, damit ein Modulfehler keine ungedeckte
Option schreiben kann. Ein Modul, das sich selbst prüft, prüft sich irgendwann nicht mehr.
### [O/K] Entscheidungen bei der Umsetzung von #298, #300 und #302–#305
Die Umsetzung am 2026-09-04 hat vier Stellen aufgedeckt, an denen die Konzepte nicht eindeutig
waren oder sich widersprachen. Sie sind so entschieden worden:
**Schicht B heißt ab jetzt „kein *ungedeckter* Short".** Das Kapitalmodell formuliert §4 Schicht B
als „kein Short – Verkäufe werden auf die Buchmenge gekappt, Shorts sind implizit Margin". Für
Aktien gilt das unverändert. Für Optionen wäre es gleichbedeutend mit „kein OptionsWheel", denn
dessen Kernoperation *ist* ein verkaufter Kontrakt. Der Grund der Regel war nie der Short an sich,
sondern der **Kredit**: ein Cash-Secured Put mit reservierter Deckung über Strike × Kontraktgröße
und ein Covered Call mit gesperrten Aktien nehmen keinen Kredit auf. Die Sperre wird damit nicht
gelockert, sondern auf ihren eigentlichen Gegenstand gestellt. Ein nackter Verkauf bleibt
unmöglich, und zwar im Core.
**Die Hausreserve wird einmal abgezogen, nicht zweimal.** §4 Schicht A zieht sie vom freien
Bargeld ab, §3 zieht sie in `Verteilbar` erneut ab. Das ist dieselbe Rücklage, zweimal beschrieben.
Der doppelte Abzug hätte bei 5 % Reserve rund ein Zehntel des Kapitals stillgelegt, ohne dass es
irgendwo sichtbar gewesen wäre. `CapitalSnapshot.HouseReserve` steht nur noch zur Anzeige.
**Der Positionsschlüssel ist eine Spalte, nicht der Sechser-Verbund.** Das OptionsWheel-Konzept
sieht `(Module, Symbol, Kind, Expiry, Strike, Right)` als fachlichen Schlüssel vor. MySQL verlangt
für Primärschlüsselspalten NOT NULL; Expiry, Strike und Right sind bei Aktien aber leer, man
bräuchte also Platzhalter wie das Datum 1000-01-01. Stattdessen trägt `core_position.ContractKey`
einen druckbaren Instrumentenschlüssel – bei Aktien schlicht das Ticker-Symbol („AAPL"), bei
Optionen „AAPL|20260918|C|150". Bestandszeilen ändern sich dadurch inhaltlich nicht; die Migration
füllt die Spalte aus `Symbol`.
**Der Reservierungszustand INTENT entfällt.** §5 nennt ihn vor RESERVED. Absicht und Reservierung
entstehen aber in derselben Transaktion hinter dem globalen Order-Lock – ein Zustand, den niemand
je beobachten kann, wäre eine Zeile, die immer leer ist. Wird die Reservierung später zweistufig,
gehört er nachgezogen.
**Neu hinzugekommen: das Buch `DIAG`.** Der Order-Nachweis (#293) und später das
DebugTrading-Modul (#468) platzieren echte Orders. Ihre Positionen dürfen nicht in der Buchführung
eines Strategiemoduls landen – sie verfälschten dessen Auslastung, dessen GuV und dessen
Konzentration, und zwar dauerhaft, weil die Position echt ist.
### [O/K] Währung gehört zur Identität eines Instruments
Am 2026-09-04 stellte sich beim Order-Nachweis heraus, dass das Paper-Konto sein Bargeld in **EUR**
hält und in USD mit −3.751 im Minus steht. Ein USD-Kauf wäre damit ein USD-Kredit gewesen, und
Schicht C hat ihn zu Recht abgelehnt. Die Entscheidung fiel gegen ein Aussetzen der Sicherung und
für das, was das Problem an der Wurzel löst: **Instrumente sind währungsfähig.**
Die Währung steht dabei im Instrumentenschlüssel und nicht bloß als Attribut daneben. Derselbe
Ticker notiert an mehreren Plätzen — SAP gibt es in Frankfurt in EUR und als ADR in New York in
USD, zu deutlich verschiedenen Kursen. Zwei Notierungen als eine Position zu führen, würde Bestand
und Deckung vermischen.
**USD bleibt implizit** (`AAPL`, nicht `AAPL:USD`). Andernfalls wäre jede Bestandszeile ab sofort
ein anderes Instrument als vorher und aus einer Position würden zwei. Trennzeichen ist der
Doppelpunkt, nicht der Punkt — Ticker enthalten Punkte (BRK.B).
### [X] #479 — Die Order lief auf die falsche Notierung
Der teuerste Fund des Tages, und einer, den kein Unit-Test hätte finden können. Geprüft, bepreist
und reserviert wurde `SAP:EUR` zu 188,74 EUR. Ausgeführt wurde die SAP-ADR in New York zu 216,68
USD; das USD-Guthaben rutschte um 434 ins Minus.
Damit wurde **genau der Margin-Kredit aufgenommen, den Schicht C verhindern soll** — an der
Sicherung vorbei, weil die Sicherung ein anderes Instrument geprüft hatte als das, was gehandelt
wurde. Ohne Fehlermeldung. Die Bücher wiesen anschließend eine EUR-Position zum USD-Preis aus, die
es beim Broker nie gab.
Die Ursache war eine nicht gesetzte Eigenschaft: `ExecutionService` baute die `OrderRequest` aus
Einzelfeldern, und `Currency` fiel still auf USD zurück. Die Lehre ist allgemeiner als der Fehler:
**eine neue Dimension an der Identität eines Objekts macht jede Stelle, die dieses Objekt aus
Teilen zusammensetzt, zu einer Fehlerquelle.** Deshalb wurde nicht die Zuweisung nachgetragen,
sondern `OrderRequest.For(instrument, …)` eingeführt — im Orderpfad lässt sich ein Auftrag nicht
mehr aus losen Feldern bauen.
### [K] #480 — Das Kapitalmodell rechnet Währungen zusammen
Solange jedes Instrument USD war, war die Frage gegenstandslos. Mit der ersten EUR-Position ist sie
es nicht mehr: Pool, Konzentrationslimit und die Summe der offenen Reservierungen addieren Beträge
verschiedener Währungen unverändert.
Bei ähnlichen Kursen fällt das nicht auf — **genau deshalb ist es gefährlich.** Und die Richtung
des Fehlers ist nicht einheitlich: bei einer starken Fremdwährung wird die Auslastung
*unterschätzt*, und ein Buch darf mehr aufmachen als es soll. Das Kapitalmodell sieht die Lösung in
§7 bereits vor (Buch-Cash und Reservierungen je Währung); umgesetzt ist sie bisher nur für die
Reservierungen und für Schicht C. Für die Pool-Rechnung fehlen Umrechnungskurse — die liefert #321.
### [H] #293 — Wie der Nachweis geführt wird
`--ibkr-check` liest nur. Für #293 gibt es deshalb `--verify-order SYMBOL` am Daemon: es geht durch
die **vollständige** Kette – Buchzuordnung, Risikoprüfung, Kapitalbindung, Order, Fill, Buchung,
Abschluss der Bindung – und schreibt hinterher hin, welche Tabellen zu prüfen sind.
Drei Sicherungen, weil der Schalter als Einziger im Repository absichtlich eine echte Order
auslöst: ohne `--confirm` ist er ein Trockenlauf; er verweigert den Dienst außerhalb des
Paper-Modus **und** außerhalb eines Paper-Ports (eines allein sagt nichts – ein Paper-Modus auf
einem Live-Port bewegt echtes Geld); und den globalen Handelsschalter übergeht er nicht, sonst
wäre der keiner.
**Geführt am 2026-09-04** gegen das Paper-Konto DUR371528: Kauf von 2 × `SAP:EUR` zu 185,86 EUR,
alle fünf Tabellen stimmen. Der Nachweis hat dabei **vier Fehler gefunden**, drei davon für
Unit-Tests unerreichbar — die falsche Notierung (#479), eine Bargeldaufschlüsselung, die gar nicht
ankam, eine Kursabfrage ohne Währung, und zwei Spalten der Buchführung, die zu eng waren bzw. leer
blieben. Das ist der eigentliche Ertrag: der Lauf gegen echte Gegenstellen prüft die Fugen zwischen
den Bausteinen, und dort saßen alle vier.
### [W] #309/#310 — Was steht, und was der Handelsbetrieb noch braucht
Gerüst und reine Strategie-Logik stehen: `ow_`-Schema mit fünf Tabellen, Zustandsautomat,
`StrikeSelector`, `RollDecider`, `PremiumMath`, Regelwerk – ohne Broker und ohne Datenbank
prüfbar. **Offen aus #309 bleibt das Modulfenster**; ohne Daten hätte es fünf leere Tabs.
`OptionsWheelModule.GetActivationBlocker` nennt den Grund, warum das Modul noch nicht handelt,
statt still nichts zu tun: **#311 ist ohne #299 und #294 nicht erreichbar.** Der `StrikeSelector`
braucht das Delta aus der Optionskette, und eine limitierte Optionsorder am Mittelkurs füllt
regelmäßig erst nach Minuten – mit dem heutigen synchronen Pfad gälte sie als fehlgeschlagen,
während sie bei IBKR weiterläuft. Deshalb registriert das Modul noch keine Worker: ein Gerüst, das
handelt, ohne den Fill mitzubekommen, wäre schlimmer als keines.
### [T] #297 — Entscheiden, welcher IBKR-Zugangsweg bleibt
Es gibt zwei parallele Wege: den TWS-API-Adapter (`Trading/Ibkr/`, der handelnde Pfad) und
`IBKRGatewayService` (Client Portal REST, versorgt Instrument-Sync, Kurshistorie und den
Watchdog-Heartbeat). Zwei Broker-APIs bedeuten zwei Fehlerbilder, zwei Authentifizierungen und
zwei Betriebsvoraussetzungen – und im Störfall die Frage, welcher der beiden gerade lügt.
Entweder die Historie auf `reqHistoricalData` umziehen und den REST-Weg aufgeben – oder die
Doppelung ausdrücklich begründen. Ein Entscheidungspunkt, keine Implementierungsaufgabe.
### [D] #317 — Erstes echtes Release fahren
Die Pipeline (`scripts/release.*`, `setup.json`) steht, ist aber nie gelaufen. Zwei Fallen liegen
beim **ersten** Lauf und lassen sich danach nicht mehr billig korrigieren:
Die `preservePatterns` müssen sofort stimmen. Ein Update, das `settings.json` überschreibt, nimmt
einer laufenden Installation Datenbank, Token und Flex-Zugang gleichzeitig.
Der erste Build muss bereits den `licenseKey` mitgeben, sonst fällt die Tür hinter dem ersten
Release zu – bei Predictalytics genau so passiert.
### [A] #322 — Steuerschicht: Jurisdiktionsprofil festlegen
Die Jurisdiktion (DE-Kapitalertragsteuer / US Form 8949) ist **nicht festgelegt**. Der neutrale
Ledger und die Abrechnung gelten unabhängig davon; die Steuer-Engine ist als klar abgetrennter
Platzhalter angelegt. Das Profil wird einmalig gesetzt und danach in der DB verankert.
**Keine Steuerberatung.**
### [T] #466 — TWS-Meldungen mit Umlauten kommen falsch dekodiert an
Am ersten Verbindungstag auf dem neuen Testserver stand im Log `verzögerte Marktdaten` – das Bild,
wenn UTF-8-Bytes als Latin-1 gelesen werden. Betroffen sind nur Texte **aus der TWS-API**; unsere
eigenen deutschen Logzeilen im selben Lauf sind sauber, Konsole und Logdatei scheiden als Ursache
damit aus.
Die Wirkung ist gering, aber nicht null: Fehlertexte der Gegenstelle sind das, was im Störungsfall
gelesen wird, und sie gehen so auch in den Fehler-Stream des Deploymentcenters – ein Text, der
schon beim Erfassen beschädigt ist, lässt sich später nicht mehr zuverlässig gruppieren.
Der schnelle Weg ist, TWS auf englische API-Meldungen zu stellen: englische Fehlertexte sind für
die Fehlersuche ohnehin die besseren, weil jede Fundstelle im Netz sie so zitiert. Das ist eine
Umgehung, keine Lösung – ob das TWS-API-Paket die Meldungen fest mit einer Kodierung liest, bleibt
zu prüfen.
### [H] #468 — DebugTrading-Modul: Dauerlast auf der Buchungskette
Alles, was den Handel absichert – Modul-Limits, Slippage-Prüfung, Kapitalpool und Reservierungen,
Abgleich gegen den Broker, Behandlung manueller Trades, Accounting-Ingest, Zeitstempel über
Zeitzonen hinweg – ist heute ausschließlich durch Unit-Tests mit gemockten Gegenstellen belegt. Im
laufenden Betrieb gab es fast keine Trades: das einzige Strategiemodul handelt selten und hing
zuletzt an der 429-Sperre. Ein Fehler in der Buchungskette fällt so erst auf, wenn eine echte
Strategie scharf geht – und das ist der teuerste Zeitpunkt, ihn zu finden.
Das Modul erzeugt deshalb absichtlich Last statt Rendite: kleine Positionen unter 1.000 USD, über
Handelsplätze und Währungen gestreut, mit gewürfelter Haltedauer von Minuten bis Tagen, die es
selbstständig wieder schließt. Die lange Spanne ist der Punkt – sie prüft, ob offene Positionen
Neustarts, Tageswechsel und den nächtlichen TWS-Neustart überstehen.
**Warum unter [H] und nicht als eigener Themenbereich:** Es ist kein Strategiemodul und darf nie
eines werden. Es ist das Prüfwerkzeug der Orderstrecke und hängt an ihr – ohne die gegen das
Paper-Konto verifizierte Order (#293) hat es nichts, worauf es aufsetzen könnte.
**Die Sicherung, die nicht verhandelbar ist:** Startverweigerung, wenn `Trading.Mode` nicht
`Paper` ist – hart im Modul, nicht als Einstellung. Ein Testmodul, das im Livebetrieb anläuft,
wäre der teuerste denkbare Fehler dieses Projekts. Dazu ein eigenes Tagesbudget, eine Obergrenze
gleichzeitig offener Testpositionen, ein Notaus und persistente Testpositionen in `dbg_position`,
damit ein Neustart keine Position vergisst.
---
## 🧊 Zurückgestellt – vorgehalten, aber nicht jetzt
*Bewusste Entscheidungen, keine Versäumnisse. Der Auslöser steht am Item im Deploymentcenter und
wird beim Zurückstellen erzwungen; hier steht, warum nicht jetzt.*
### [W] #327 — Trendfolge-/Momentum-Modul auf Tagesbasis als zweites Standbein
Die Datenlage ist komfortabel: zehn Jahre Tagesbars, dividendenbereinigt. Das Risiko liegt nicht
in den Daten, sondern in der Strategie. Aber ein zweites handelndes Modul **vor** dem Kapitalmodell
wäre fahrlässig – zwei Module an einem Konto ohne Eigentumsregeln und Reservierungen ist genau der
Zustand, den Stufe 4 verhindert.
### [M] #328 — Marktdaten-Abo US-Realtime (NYSE/AMEX/NASDAQ)
Schaltet Scanner und Realtime frei. Für Tages- und Prämienstrategien **nicht nötig** – unsere
Signale kommen aus abgeschlossenen Bars, die 15-Minuten-Verzögerung ist dabei irrelevant.
### [M] #329 — OPRA-Abo (Optionen-Realtime)
Verbessert die Ausführungsqualität beim Wheel. Für die Strike-Auswahl nachweislich nicht
erforderlich: die Greeks funktionieren mit verzögerten Daten, am 2026-08-04 gegen das
Paper-Gateway gemessen.
### [M] #330 — Refinitiv-Fundamentaldaten
Der Kandidat mit dem größten qualitativen Sprung: löst die Earnings-Sperre und öffnet fundamentale
Ansätze. Kostet aber Geld für ein System, das noch nie eine Order platziert hat. Deshalb wartet er
auf den Nachweis, dass der billige Behelf (`#312`) nicht reicht.
### [K] #331 — Self-Cross-Netting (Modul A kauft, Modul B verkauft dasselbe Symbol)
Bei unserer Handelsfrequenz unrealistisch. **Billige Vorstufe stattdessen:** ist im Order-Gateway
eine gegenläufige Order für dasselbe Symbol pending, wird protokolliert und gewarnt – der Lock ist
ohnehin da. Das liefert Daten darüber, ob das Problem je real wird, statt es zu vermuten.
### [K] #332 — Corporate Actions (Splits, Spin-offs) in der Buchzuordnung
Vorerst über den Flex-Abgleich als Break sichtbar, manuelle Zuordnung. Eine Automatik zu bauen,
bevor der erste Fall aufgetreten ist, heißt gegen eine ausgedachte Spezifikation zu entwickeln.
### [T] #333 — Web-UI über die interne REST-API
Die REST-API existiert. Ein Web-UI ist reine Zusatzarbeit ohne Betriebsnutzen, solange Shell und
Daemon reichen.
### [D] #334 — Desktop-Distribution der Shell über die Release-Pipeline
Die Vorlage nimmt genau eine `csproj` für alle Runtimes, und das Skript bleibt laut Anleitung
unverändert. Release-Kandidat ist deshalb `IBKRTrader.Daemon`.
### [M] #335 — Ungepruefte Datenfragen der TWS API klaeren
`reqNewsArticle` (Volltext), Reichweite der Nachrichtenhistorie, Markttiefe (`reqMktDepth`), leeres
`reqHistogramData`, Verlässlichkeit verzögerter Greeks außerhalb der Handelszeiten, Ratenbegrenzung
bei Historienabrufen. Keine dieser Fragen blockiert die geplanten Strategien – die Ratenbegrenzung
wird aber schon bei einem nächtlichen Watchlist-Abruf zur Frage.
---
## ❌ Verworfen – geprüft und entschieden
*Damit nichts davon in sechs Monaten erneut als gute Idee auftaucht. Ein neuer Vorschlag braucht
ein Argument, das hier noch nicht steht.*
### [K] #336 — Echte IBKR-Sub-Accounts (Advisor-/Family-Struktur) zur Trennung der Buecher
Erfordert einen Kontotypwechsel und eine feste Vorabaufteilung des Kapitals – deutlich unflexibler
als virtuelle Bücher, die denselben Zweck erfüllen.
### [T] #337 — InvariantGlobalization=true fuer ein schlankes Linux-Image
In der Portierungsanalyse noch empfohlen, **wäre ein Fehler gewesen**: ohne ICU fällt die Auflösung
von Windows-Zeitzonen-IDs aus und die feste `de-DE`-Formatierung des PDF-Exports kippt auf
invariant. Beides lautlos. Der Daemon setzt es ausdrücklich auf `false`.
### [W] #338 — Fundamentales Screening (Value, Quality, Growth)
Keine Fundamentaldaten über die TWS API.
### [W] #339 — Earnings-Strategien (Straddle vor Zahlen, Post-Earnings-Drift)
Keine Termine für Quartalszahlen erreichbar (Fehler 10358, Refinitiv-Abo nötig).
### [W] #340 — Marktweite Anomalie-Suche / Screener-getriebene Auswahl
Der Marktscanner ist ohne Realtime-Abo gesperrt. Jede Strategie arbeitet auf einer gepflegten
Watchlist.
### [W] #341 — Daytrading, Scalping, Orderbuch-Strategien
Verzögerte Kurse (~15 Min). Die Ausführung träfe den Markt zu spät.
### [W] #342 — Gap-Strategien auf Eroeffnung
Der Eröffnungskurs kommt verzögert – nur mit Realtime-Abo sinnvoll.
### [W] #343 — Strike-Wahl ueber prozentualen Abstand statt delta-basiert
Als Ersatzlösung gedacht, falls Greeks mit verzögerten Daten nicht funktionieren. Sie funktionieren
(am 2026-08-04 gemessen). Bleibt im `StrikeSelector` nur als Rückfalllinie.
### [S] #344 — Agent-zu-Agent-Orchestrierung im Supervisor
Bewusst nicht: Profile sind System-Prompt + Tool-Subset über *einer* Infrastruktur. Einfacher und
nachvollziehbarer.
### [A] #345 — Modulzuordnung als Korrektur des Steuerbuchs
Harte Regel: Das Managementbuch beeinflusst das Steuerbuch **niemals**. Die Zuordnung ist eine
optionale, nicht-autoritative Beistelltabelle – fehlt sie oder ist sie falsch, ändert sich am
Steuerergebnis exakt nichts.
---
## Fertig – der Weg bis hierher
*Kurzfassung. Die vollständigen Phasen-Checklisten stehen weiterhin in
[ARCHITECTURE.md](ARCHITECTURE.md). Diese Abschnitte wurden bei der Übernahme bewusst **nicht** zu
Items – erledigte Arbeit braucht keinen Bearbeiter.*
| Abschnitt | Inhalt | Fertig |
|---|---|---|
| **R1–R7** | Kurskorrektur auf das PolytraderSharp-Konzept: Multi-Projekt, Generic Host, EF Core, Trading-Kern, CongressTrading-Strategie, Security, Dashboard, TWS-Broker-Adapter | 2026-07 |
| **S-0–S-4** | Supervisor: Datenfundament (Entscheidungsjournal, Order-Events, `SignalId`, JSONL-Logs), Dossiers, OpenRouter-Agent mit read-only Tools, Berichte, MCP-Light | 2026-07-30 |
| **Accounting** | `acc_`-Schema, append-only Ingest, Klassifizierung, Abrechnung, FX, CSV-/PDF-Export – mit Offline-Null-Stubs | 2026-07-30 |
| **L0–L6** | Linux-Portierung: Avalonia statt WinForms, Betriebszeitzone, kopfloser Daemon, geteiltes Hosting, WinForms vollständig entfernt, Namensgebung bereinigt | 2026-08-07 |
| **DC 0–8** | Deploymentcenter: Lizenz mit Sperrbetrieb, Watchdog-Heartbeat, globale Ausnahmebehandler + Fehler-Stream, Update-Prüfung, `setup.json`, Release-Pipeline | 2026-08-23 |
| **Frühjahrsputz** | Toter Code entfernt, ungenutzte Symbole und Paketmuster raus, Dokumentenstand an die Wirklichkeit angeglichen | 2026-08-23 |
| **DC-Anbindung** | Roadmap ins Deploymentcenter übernommen, MCP-Adapter eingerichtet, Baustein A+B in `CLAUDE.md` (**#318**) | 2026-08-30 |
---
## Archiv
Die Quelldokumente sind **vollständig erhalten** und liegen unter [archiv/](archiv/). Sie werden
nicht mehr gepflegt – der Stand steht im Deploymentcenter –, aber sie tragen die Herleitung, die
Messwerte und die Begründungen, die eine Roadmap nicht fassen kann.
| Dokument | Was darin steht, das hier fehlt |
|---|---|
| [Kapital-und-Buchmodell.md](archiv/Kapital-und-Buchmodell.md) | Die vollständige Spezifikation: die drei Wahrheiten, Eigentumsregeln, Reservierungs-Lebenszyklus, Invarianten und Testkatalog. Referenz für `[K]`. |
| [KONZEPT-Modul-OptionsWheel.md](archiv/KONZEPT-Modul-OptionsWheel.md) | Zustandsautomat, Regelwerk mit Vorgabewerten, `ow_`-Datenmodell, Sicherungen. Referenz für `[W]`. |
| [KONZEPT-Datenlage-und-Strategien.md](archiv/KONZEPT-Datenlage-und-Strategien.md) | **Gegen das laufende Paper-Gateway gemessen**, nicht aus der Doku übernommen: was die TWS API liefert und welche Strategien das trägt. Grundlage der Zurückgestellt- und Verworfen-Listen. |
| [KONZEPT-Deploymentcenter-Integration.md](archiv/KONZEPT-Deploymentcenter-Integration.md) | Die bewussten Abweichungen vom DC-Leitfaden (Sperrbetrieb statt Prozessende, `exitCurrentApp: false`) samt Begründung, die Befunde P1–P6 und D1–D7. |
| [KONZEPT-Linux-Portierung.md](archiv/KONZEPT-Linux-Portierung.md) | Die Analyse vor dem Umbau: Fundstellenverzeichnis, Aufwandsschätzung und was anders kam als geschätzt. |
| [KONZEPT-Modul-Accounting.md](archiv/KONZEPT-Modul-Accounting.md) | Leitprinzipien (unabhängige Quelle, Idempotenz, append-only), Datenbeschaffung über Flex Query. |
| [KONZEPT-Modul-Supervisor.md](archiv/KONZEPT-Modul-Supervisor.md) | S-0 bis S-4 im Detail, Tool-Registry, Sicherheitsgrenzen des Agenten. |
**Weiter gepflegt** werden – sie sind Referenz, keine Planung:
[ARCHITECTURE.md](ARCHITECTURE.md) (Aufbau und Phasen-Historie),
[IBKR-Integration.md](IBKR-Integration.md) (Adapter-Design und Grenzen),
[TWS-Setup-Checkliste.md](TWS-Setup-Checkliste.md) (Einrichtung eines neuen Systems).
---
## Den Block auffrischen
Der erzeugte Block altert. Auffrischen ohne PHP auf dieser Maschine:
```bash
python scripts/roadmap_block.py
```
Das Skript holt `roadmap.php?action=render` und ersetzt den Bereich zwischen den Markern.
`DC_TOKEN` kommt aus der Umgebung oder aus `.mcp.json`.