Files
IBKRTrader/docs/archiv/Kapital-und-Buchmodell.md
T
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

24 KiB
Raw Blame History

📩 Archiviert am 2026-08-23

Dieses Dokument wird nicht mehr gepflegt. Was davon noch offen ist, steht in der Roadmap (Stufe 4) – dort und nur dort wird der Stand nachgefĂŒhrt.

Es bleibt erhalten, weil es die vollstaendige Spezifikation ist, gegen die die Umsetzung geprueft wird – die drei Wahrheiten, Eigentumsregeln, Reservierungs-Lebenszyklus, Invarianten und Testkatalog. Zum Nachschlagen also weiterhin richtig, als Aufgabenliste nicht mehr.


Kapital- und Buchmodell

Status: Konzept (2026-08-03) – noch nicht implementiert. Dieses Dokument beschreibt, wie mehrere Strategien gleichzeitig auf einem IBKR-Konto mit einem Guthaben arbeiten können, ohne sich gegenseitig zu stören, und wie das gegen die steuerliche BuchfĂŒhrung abgegrenzt ist. Es dient als Referenz, gegen die die spĂ€tere Umsetzung geprĂŒft wird.

0. Problemstellung und Abgrenzung

TWS lĂ€sst sich pro Rechner nur einmal betreiben – wir sind an ein Konto mit einem Guthaben gebunden. Trotzdem sollen mehrere Strategie-Module parallel handeln. Daraus folgen vier Anforderungen:

  1. Jedes Modul bekommt eine klar begrenzte Kapitalmenge, die es binden darf.
  2. Jede Position hat einen eindeutigen EigentĂŒmer. Kein Modul darf die Position eines anderen Moduls oder eine manuell angelegte Position anfassen.
  3. Das Konto darf durch Modul-Handel niemals ins Minus oder in Margin laufen.
  4. Die steuerliche BuchfĂŒhrung ist davon vollstĂ€ndig unabhĂ€ngig und muss zu 100 % stimmen.

Nicht Gegenstand dieses Dokuments: Strategielogik, Signalerzeugung, Marktdatenversorgung.


1. Die drei Wahrheiten

Es gibt drei Datenquellen mit unterschiedlicher AutoritĂ€t. Sie dĂŒrfen sich nicht vermischen.

Ebene Quelle Autoritativ fĂŒr Latenz
Steuerbuch (acc_) Flex Query Geld, Steuer, GuV – alles gegenĂŒber der Steuerbehörde T+1
Depot-Ist TWS-API-Snapshot Was jetzt real im Konto liegt Sekunden
Managementbuch (core_) eigene Order-Events + Abgleich Zuordnung von Positionen zu BĂŒchern live

Harte Regel: Das Managementbuch beeinflusst das Steuerbuch niemals – weder korrigierend noch ergĂ€nzend. Der Accounting-Ingest liest Flex Query, klassifiziert und bucht; ob dabei eine BookId bekannt ist, ist ihm gleichgĂŒltig. Die Modulzuordnung ist eine optionale, nicht-autoritative Beistelltabelle (Flex-Trade-ID ↔ BookId). Fehlt sie oder ist sie falsch, Ă€ndert sich am Steuerergebnis exakt nichts.

Umgekehrt gilt: Das Managementbuch bezieht Korrekturen aus dem Steuerbuch (GebĂŒhren, Dividenden, Splits), nie andersherum.


2. BĂŒcher (Books)

Ein Buch ist ein Kapitaltopf mit zugeordneten Positionen. BĂŒcher sind:

Buch Bedeutung Handelt Limits gelten
je Strategie (CT, 
) ein Modul, ggf. ein Parametersatz ja ja
MANUAL von Hand in TWS/IBKR angelegt nein (nur extern) nein, zÀhlt aber mit
UNASSIGNED am Broker gefunden, keinem Buch zugeordnet nein zÀhlt mit
HOUSE nicht allokierte Reserve, FX, Ausgleichsposten nein –

BookId ist ein eigenes Konzept, nicht der Modulname. Default BookId == Modulname, aber die Trennung erlaubt spĂ€ter mehrere BĂŒcher desselben Moduls und macht MANUAL/UNASSIGNED/HOUSE sauber modellierbar. Jetzt kostenlos, spĂ€ter teuer nachzurĂŒsten.

Eigentumsregeln (im Core erzwungen, nicht per Konvention)

  1. Ein Verkaufssignal von Buch b kann nur Positionen von b reduzieren, gedeckelt auf Menge(b, Symbol). DarĂŒber hinaus wird gekappt – niemals wird ein Short erzeugt.
  2. MANUAL und UNASSIGNED senden keine Signale und empfangen keine.
  3. Ein Modul kann seine BookId nicht selbst wĂ€hlen. Sie stammt aus der Modul-Registrierung und wird serverseitig gesetzt; TradeSignal.SourceModule aus dem Modul ist nicht vertrauenswĂŒrdig.
  4. Module bekommen IBrokerClient nicht per DI – ausschließlich IExecutionService. Sonst ist die gesamte BuchfĂŒhrung umgehbar.
  5. Ein Kill-Switch/Supervisor darf alles liquidieren – als explizite Core-AutoritĂ€t mit eigener Konfiguration, standardmĂ€ĂŸig unter Ausschluss von MANUAL.

3. Kapitalmodell: ein Pool, Obergrenzen

Es gibt keinen Kapitaltransfer zwischen BĂŒchern. Kein Buch-Cash, keine Rebalancing-LĂ€ufe, keine Ausgleichsforderungen. Stattdessen ein gemeinsamer Cash-Pool und pro Buch eine Obergrenze:

Verteilbar   = FreiesCash(gehaircuttet) + Σ Modul-Positionswert − HouseReserve

Cap(b)       = konfigurierter Anteil × Verteilbar        (Default: Gleichverteilung)
Gebunden(b)  = Marktwert der Positionen von b + offene Reservierungen von b
Headroom(b)  = min( Cap(b) − Gebunden(b),  freies Pool-Cash )

Eigenschaften, die bewusst so sind

  • Gewinne verteilen sich von selbst. Realisiert ein Buch einen Gewinn, wĂ€chst der gemeinsame Pool; da alle Caps aus Verteilbar abgeleitet werden, steigt der Headroom aller BĂŒcher. Diversifikation ohne einen einzigen Zwangsverkauf.
  • Ein Buch darf ĂŒber seinem Cap liegen. Steigen die Positionen im Wert, passiert nichts – außer dass nicht mehr nachgekauft werden darf. Der Zustand â€žĂŒber Cap" ist legal, wird angezeigt und gemeldet, aber nie geheilt. Es wird niemals eine Position geschlossen, nur um eine Zielquote herzustellen.
  • ÎŁ Caps ≀ 100 % − Reserve wird beim Start validiert. Sonst könnte ein schnelles Buch ein langsames aushungern („wer zuerst kommt").
  • Die Modul-Welt sieht nie den NAV, sondern nur ihr eigenes Kapital plus freies Cash. Manuelle Positionen – auch kreditfinanzierte – sind eine Black Box, die nur ĂŒber das freie Cash wirkt.

KapitalfĂŒhrung ≠ Performance-Messung

Die KapitalfĂŒhrung ist ein Pool plus Caps. Die GuV pro Buch ist eine reine Auswertung ĂŒber die Trade-Historie (fĂŒr Supervisor und Reporting) und steuert nichts. Diese Entkopplung ist beabsichtigt.


4. Keine Margin – die Sperre

Modul-Handel ist strikt cash-only. Manueller Handel darf Margin nutzen. Der Kontotyp ist Cash-Konto; brokerseitig kann trotzdem Margin verfĂŒgbar sein, deshalb ist die Software-Sperre zwingend und testpflichtig.

Schicht A – richtige Bemessungsgrundlage

BuyingPower und AvailableFunds sind auf einem Margin-Konto bereits gehebelt gerechnet und als Basis unbrauchbar. Maßgeblich ist:

FreiesCash = min(TotalCashValue, AvailableFunds) − HouseReserve − Σ offene Reservierungen

TotalCashValue ist das echte Bargeld. Eröffnest du manuell eine Margin-Position, sinkt es, und die Modul-Kaufkraft schrumpft automatisch mit. Bei TotalCashValue ≀ 0 ist die Modul-Kaufkraft null – ohne Sonderlogik. Module können einen manuellen Kredit strukturell nicht ausweiten.

Schicht B – kein Short

VerkÀufe werden auf die Buchmenge gekappt. Shorts sind implizit Margin.

Schicht C – WĂ€hrung

Ein Kauf in WĂ€hrung X darf nur aus Cash in WĂ€hrung X finanziert werden. Andernfalls entsteht ein Sollsaldo in X – ein Margin-Kredit, auch wenn das Konto in Summe positiv aussieht. Buch-Cash und Reservierungen werden deshalb pro WĂ€hrung gefĂŒhrt (siehe Abschnitt 7).

Schicht D – Watchdog

Ein Hosted Service prĂŒft Cash und Margin-Kennzahlen laufend. Bei Unterschreitung: globaler Kauf-Stopp + Alarm – und niemals automatisches Verkaufen zur Heilung. Ein Selbstheilungs-Amoklauf ist gefĂ€hrlicher als der Zustand, den er beheben soll.


5. Reservierungen (Order-Lebenszyklus)

Verhindert, dass zwei Module gleichzeitig dasselbe Geld ausgeben. Persistent in der DB, nicht im RAM.

INTENT → RESERVED → SUBMITTED → FILLED | PARTIAL | CANCELLED | REJECTED | EXPIRED
  • Reservierungshöhe: Menge × Referenzpreis × (1 + Puffer) + geschĂ€tzte Kommission. Puffer klein bei Limit-Orders (das Limit ist die Obergrenze), grĂ¶ĂŸer bei Market (Slippage), zusĂ€tzlich FX-Puffer bei wĂ€hrungsĂŒbergreifenden VorgĂ€ngen.
  • Atomar gegen Buch-Headroom und Pool-Cash, in einer DB-Transaktion hinter einem globalen Order-Lock. Bei einer TWS-Verbindung reicht ein einfacher SemaphoreSlim; feingranulare Locks wĂ€ren hier nur eine zusĂ€tzliche Fehlerquelle.
  • Freigabe beim Terminalzustand; Differenz zwischen Reservierung und echtem Fill fließt zurĂŒck.
  • TTL zwingend. Erreicht eine Reservierung ohne Terminalzustand ihr Ablaufdatum oder den Handelsschluss → Alarm, keine stille Freigabe. Eine hĂ€ngende Order, deren Reservierung freigegeben wird, gibt das Geld zweimal aus.
  • Idempotenz ĂŒber SignalId bzw. eine Client-Order-ID, damit ein Reconnect keine Doppelorder erzeugt.
  • Crash-Recovery: beim Start alle nicht-terminalen Reservierungen gegen die offenen Broker-Orders abgleichen; Waisen → QuarantĂ€ne + Alarm.

6. Limits und Feedback an die Module

Konzentrationslimit pro Einzelwert

SymbolExposure(s) = ÎŁ_b Marktwert(b, s)              ← ĂŒber ALLE BĂŒcher, inkl. MANUAL
PrĂŒfung: SymbolExposure(s) + geplanter Kauf ≀ MaxSymbolPercent × NAV
  • NAV als Nenner, nicht der Positionswert – sonst wird das Limit bei viel Cash absurd eng und bei wenig Cash absurd weit.
  • MANUAL ist von der PrĂŒfung befreit, zĂ€hlt aber voll in den ZĂ€hler. HĂ€ltst du 50 % AAPL von Hand, sind die Module bei AAPL vollstĂ€ndig gesperrt. So gewollt.
  • VerkĂ€ufe sind nie limitiert. Ein Limit darf niemals das Schließen einer Position verhindern.

Feedback-Kontrakt

Das Gate ist hart. Das Modul entscheidet nur, wie es auf die Ablehnung reagiert – nicht, ob das Limit gilt. Ein erneut gesendetes zu großes Signal wird wieder abgelehnt. Der Core trimmt nicht selbststĂ€ndig; die Entscheidung liegt auf Strategieebene.

record LimitBreach(
    LimitKind Kind,        // SymbolConcentration | BookCap | CashAvailable
                           // | FxBuffer | CurrencyNotAllowed | VenueNotAllowed
    string    Scope,       // "AAPL" | "CT" | "USD"
    decimal   Current,
    decimal   Limit,
    int       MaxQuantity, // was jetzt noch ginge
    decimal   MaxNotional);

ErgÀnzend eine Vorab-Query GetHeadroom(book, symbol), damit ein gut gebautes Modul gar nicht erst gegen die Wand fÀhrt und seine Order gleich richtig dimensioniert.

Drossel: Ein Modul, das dasselbe Signal wiederholt gegen dieselbe Wand schickt, wird nach N Versuchen pro SignalId gedÀmpft und protokolliert. Sonst produziert eine schlecht geschriebene Strategie Logfluten und TWS-Last.


7. WÀhrungen und HandelsplÀtze

KontobasiswĂ€hrung: konfigurierbar, bei Ersteinrichtung festgelegt, danach gesperrt (siehe Abschnitt 11 – eine Änderung nach dem ersten Trade macht alle historischen Bewertungen, Caps und GuV-Zahlen ungĂŒltig).

  • Produktion (US LLC): USD
  • Test/Paper (EU): EUR

Contract-Auflösung ist Pflicht

Eine Order mit nacktem Symbol-String ĂŒber SMART kann bei mehrdeutigen Tickern still an einer Börse in einer anderen WĂ€hrung landen. Deshalb:

  • Vor jeder Order wird der Contract ĂŒber reqContractDetails aufgelöst; currency, exchange, primaryExchange und conId werden geprĂŒft.
  • Whitelist auf zwei Achsen: WĂ€hrung ∈ AllowedCurrencies und Handelsplatz ∈ konfigurierter Liste. Verstoß → harte Ablehnung, unabhĂ€ngig vom Modul.
  • Das Ergebnis wird gecacht; die conId wird in der Position gespeichert. Sie ist IBKRs eindeutige Instrumenten-ID und deutlich sicherer als ein Ticker.

FX-Marge als Sicherheitspuffer, nicht als Exposure-Deckel

Bei ĂŒberwiegendem Handel in KontobasiswĂ€hrung wĂ€re ein FX-Exposure-Limit meist verletzt und damit nutzlos. Sinnvoll wirkt die Marge an drei anderen Stellen:

  1. Bewertungs-Haircut: FremdwĂ€hrungs-Cash geht mit Abschlag in Verteilbar ein → das eigene Kapital wird nie ĂŒberschĂ€tzt.
  2. Reservierungspuffer bei wĂ€hrungsĂŒbergreifenden KĂ€ufen, zusĂ€tzlich zum Slippage-Puffer.
  3. FX-Exposure als Kennzahl mit Alarmschwelle – sichtbar und meldepflichtig, ohne Handelssperre.

Kein Auto-FX im Order-Pfad

Fehlt Cash in der ZielwĂ€hrung, scheitert der Modul-Kauf mit LimitKind.CashAvailable. Konvertiert wĂŒrde der Order-Pfad selbst, könnte ein Modul indirekt FX-Kosten und FX-Timing auslösen, und die Reservierungslogik mĂŒsste zwei WĂ€hrungen gleichzeitig sperren. FX bleibt ein expliziter Vorgang auf HOUSE-Ebene.


8. Abgleich (Reconciliation)

Weil jederzeit manuell in TWS eingegriffen werden kann, ist der Abgleich kein Zusatz, sondern das Fundament. Zwei Stufen:

Stufe 1 – Ledger ↔ TWS (minĂŒtlich): Handelssicherheit. Stimmen StĂŒckzahlen und Cash?

Befund Bedeutung Reaktion
Broker > Ledger manuell gekauft, oder ein Fill kam nach Überschuss → UNASSIGNED
Broker < Ledger manuell verkauft / Corporate Action Break: betroffene BĂŒcher und Symbol fĂŒr neue Orders sperren, Alarm
Cash weicht ab GebĂŒhren, Zinsen, FX Differenz gegen HOUSE, ab Schwelle Break

Bei „Broker < Ledger" wird bewusst nicht automatisch korrigiert. Anteiliges WegkĂŒrzen zerstört die Zurechenbarkeit – Halt-and-alert, der Mensch entscheidet.

Stufe 2 – Ledger ↔ Flex Query (tĂ€glich, nach Ingest): QualitĂ€tssicherung. Hier kommen GebĂŒhren, Dividenden, Quellensteuer, FX-Differenzen und Splits an – Dinge, die die TWS-API gar nicht oder schlecht liefert.

GebĂŒhren gehören dem verursachenden Buch. Sonst subventioniert HOUSE die vieltradenden Module und die Performance-Zahlen lĂŒgen. Beim Fill wird geschĂ€tzt, beim Flex-Abgleich exakt nachjustiert.


9. Unzugeordnete Positionen und Eskalation

ZustĂ€nde: New → Notified → Acknowledged → Assigned(Book), mit DetectedAt-Zeitstempel.

  • Ein Watchdog meldet alles, was lĂ€nger als 30 Minuten unbearbeitet liegt.
  • Backoff: nach 30 min, dann 2 h, dann tĂ€glich – sonst wird der Kanal unbrauchbar.
  • Abgestufte Sperrwirkung: Eine UNASSIGNED-Position zĂ€hlt voll in Exposure und Konzentrationslimit, bremst die Module also automatisch, sperrt aber nicht hart. Hart gesperrt wird nur der gefĂ€hrliche Fall aus Abschnitt 8 (Broker < Ledger).

10. Benachrichtigungen

Im Code existiert derzeit kein Benachrichtigungssystem (die Treffer zu „Notification" im Supervisor-MCP sind JSON-RPC-Notifications, etwas anderes). Sauberer Start.

INotificationSink     Name, SendAsync(Notification, ct)
Notification          Severity, Category, Title, Body, DedupKey, Data
NotificationService   Fan-out ĂŒber alle registrierten Sinks

Drei Eigenschaften mĂŒssen von Anfang an drin sein, weil sie spĂ€ter schwer nachzurĂŒsten sind:

  • Outbox in der DB (core_notification): erst persistieren, dann zustellen, Retry bei Fehler. Solange kein Zielkanal existiert, sammeln sich Meldungen sichtbar an und werden zugestellt, sobald ein Sink da ist. Nichts geht verloren.
  • Dedup/Throttling ĂŒber DedupKey (z. B. unassigned:AAPL).
  • Severity-Routing: Info → Log/UI, Warning → Chat, Critical → alle KanĂ€le.

Ausbaureihenfolge: LogSink + UiSink sofort → MatrixSink, sobald der Server steht → TelegramSink optional als Backup.

Matrix ist reines HTTP, keine Library nötig: PUT /_matrix/client/v3/rooms/{roomId}/send/m.room.message/{txnId} mit dem Access-Token eines Bot-Users. Die txnId ist Matrix' eingebauter Idempotenz-SchlĂŒssel und passt exakt auf die Outbox-ID. Das Token gehört in SecretProtection.


11. Steuerbuch: Jurisdiktionsprofil

Pro Deployment gibt es genau eine Jurisdiktion, und sie wechselt nie. Ein Kontowechsel zwischen LĂ€ndern findet nicht statt – die Option „spĂ€ter auch in Deutschland" bedeutet ausdrĂŒcklich: anderer Server, andere Datenbank, anderes IBKR-Konto. Daraus folgt: keine Migration, keine MehrmandantenfĂ€higkeit, kein Umschalten zur Laufzeit.

Das Profil ist kein WĂ€hrungs-Flag, sondern ein Austausch der gesamten Lot- und Klassifikationslogik:

Aspekt US LLC (Hauptziel) DE privat (Option) DE GmbH (Option)
BerichtswÀhrung USD, keine Umrechnung EUR, Umrechnung pro Vorgang EUR, Umrechnung pro Vorgang
Lot-Matching FIFO Standard, Specific ID wÀhlbar FIFO zwingend Bilanzierung
Wash Sale (30 Tage) ja, Basis-Anpassung kein Äquivalent kein Äquivalent
Haltefrist short/long term ab 1 Jahr irrelevant irrelevant
Verlustverrechnung Carryforward mit Deckel getrennte Töpfe wieder anders
Quellensteuer – Anrechnung nach DBA Anrechnung
Ausgabe 1099-B-Abgleich / K-1 Anlage KAP Bilanz/GuV

Die Wash-Sale-Regel ist die einschneidendste: sie verĂ€ndert Anschaffungskosten rĂŒckwirkend. Eine Engine, die nur FIFO kann, lĂ€sst sich dafĂŒr nicht nachrĂŒsten. Deshalb muss die Lot-Verwaltung von Anfang an lot-basiert sein und Basis-Anpassungen als eigene Buchungsart kennen – auch wenn das erste Profil sie noch nicht nutzt.

Die konkreten steuerlichen AusprÀgungen (u. a. ob die LLC als Disregarded Entity oder Partnership behandelt wird, was das Reporting Àndert) sind mit dem Steuerberater abzustimmen. Hier steht nur, was die Software mechanisch abbilden können muss.

Profile und Umgebungen

Test/Paper (EU)    BaseCurrency EUR   TaxProfile None
Produktion (US)    BaseCurrency USD   TaxProfile UsLlc
Option DE          BaseCurrency EUR   TaxProfile DePrivat | DeGmbh

Das Profil None/Paper fĂŒhrt vollstĂ€ndig Buch, rechnet aber keine Steuer und ist in UI und allen Exporten sichtbar als solches markiert. Deutsche Steuerregeln auf Paper-Trades zu rechnen wĂ€re sinnlos und produziert Zahlen, die jemand spĂ€ter fĂŒr echt halten könnte.

Wo der Lock hingehört

Nicht in appsettings.json. Eine Datei lĂ€sst sich editieren, und dann rechnet die Engine ab morgen nach anderen Regeln ĂŒber denselben Bestand – der schlimmstmögliche Fehler, weil er sich still auswirkt.

Der Lock gehört in die Datenbank, neben die Daten, die er regiert: eine Stempelzeile im Accounting-Schema mit Jurisdiktion, BerichtswĂ€hrung, KontobasiswĂ€hrung und Einrichtungszeitpunkt. Beim Start wird die Konfiguration dagegen geprĂŒft; bei Abweichung startet das Accounting-Modul nicht, sondern meldet einen Konflikt. Gesetzt wird der Stempel bei der Ersteinrichtung, geĂ€ndert nur durch eine leere Datenbank.

Was deshalb nicht gebaut wird

Die EZB-Kursanbindung (Kursquelle, Stichtagsregeln, Kursarchivierung) ist fĂŒr das Hauptziel nicht nötig: USD-Konto, USD-Reporting, keine Umrechnung. Also nur die Naht bauen (IFxRateSource, im US-Profil eine No-Op), nicht die Implementierung. Wird die DE-Option je gezogen, geschieht das ohnehin auf einem anderen Server – dann wird sie dort ergĂ€nzt.

Falls doch: EZB-Referenzkurse autoritativ, IBKR-Bewertungskurse nur als KontrollgrĂ¶ĂŸe; verwendeter Kurs, Quelle, Stichtag und Abrufzeitpunkt werden mitgespeichert, nicht nur der umgerechnete Betrag.


12. Datenmodell-Deltas

Heute Delta
core_position (PK Module+Symbol) Module → BookId; ConId, Currency, Exchange ergĂ€nzen
core_budget (Total/Used/MaxPerTrade) ersetzen durch core_book: Cap-Regel, Flags (ReadOnly, Active), MindestordergrĂ¶ĂŸe
– core_reservation (Zustandsmaschine, TTL, WĂ€hrung)
– core_broker_snapshot + core_reconciliation_break
– core_notification (Outbox)
– core_instrument (aufgelöste Contracts, conId-Cache, Whitelist-Status)
– acc_jurisdiction (Stempel, Abschnitt 11)
Buch-Cash, Transfers, Rebalance-Lauf entfĂ€llt – ein Pool plus Caps (Abschnitt 3)
RiskContext.NetLiquidation → Verteilbar und Headroom(b), nicht NAV
IbkrConnection: NetLiquidation,AvailableFunds + TotalCashValue, SettledCash, Margin-Kennzahlen, pro WĂ€hrung
IBrokerClient + GetPositionsAsync, + ResolveContractAsync
ExecutionService (Check-then-Act ohne Lock) Order-Gateway davor: Serialisierung + Reservierung
ExecutionResult.Reason (string) + strukturiertes LimitBreach (Abschnitt 6)

13. Invarianten und Testkatalog

Die No-Margin-Bedingung wird als eine ausfĂŒhrbare Invariante formuliert, die an drei Stellen dieselbe Codebahn nimmt:

∀ WĂ€hrung c:  FreiesCash(c) ≄ 0
            ∧ ÎŁ offene Reservierungen(c) ≀ FreiesCash(c)
∀ Buch b, Symbol s:  Menge(b, s) ≄ 0
∀ Symbol s:  Σ_b Menge(b, s) = BrokerMenge(s)
  1. als Assert am Ende jedes Trading-Tests (gemeinsamer Testhelfer, nicht pro Test neu geschrieben)
  2. als Property-Test ĂŒber zufĂ€llige Sequenzen aus Reservierung / Fill / Teilfill / Cancel / Slippage / manuellem Eingriff
  3. als LaufzeitprĂŒfung im Watchdog – identische Implementierung, damit Test und Produktion nicht auseinanderlaufen

PflichtfÀlle

Fall Erwartung
Zwei parallele Reservierungen, zusammen > freies Cash zweite abgelehnt
N nebenlÀufige Tasks (Stresstest) Σ Reservierungen nie > freies Cash
Fill teurer als reserviert, innerhalb Puffer ok, Restfreigabe korrekt
Fill jenseits des Puffers Alarm, Cash bleibt ≄ 0
Manuelle Margin-Position taucht auf, Cash < Reserve alle Modul-KĂ€ufe gesperrt
Cash in ZielwĂ€hrung = 0, andere WĂ€hrung vorhanden abgelehnt – kein stiller FremdwĂ€hrungskredit
Verkaufssignal ĂŒber Buchmenge hinaus gekappt, kein Short
Reservierung erreicht TTL Alarm, keine stille Freigabe
Neustart mit offenen Reservierungen aus DB rekonstruiert, keine Doppelausgabe
Modul setzt fremde BookId im Signal serverseitig ĂŒberschrieben
Verkaufssignal gegen MANUAL abgelehnt
Contract löst auf fremde WÀhrung/Börse auf abgelehnt vor Ordersendung

14. Bewusst verschoben

  • Self-Cross-Netting (Modul A kauft, Modul B verkauft dasselbe Symbol gleichzeitig). Bei der erwarteten Handelsfrequenz unrealistisch und allenfalls eine Ausnahmeerscheinung. Billige Vorstufe jetzt: Ist im Order-Gateway eine gegenlĂ€ufige Order fĂŒr dasselbe Symbol pending, wird das protokolliert und gewarnt. Der Lock ist ohnehin da – das kostet fast nichts und liefert Daten darĂŒber, ob das Problem je real wird.
  • Corporate Actions (Splits, Spin-offs) in der Buchzuordnung – vorerst ĂŒber den Flex-Abgleich als Break sichtbar, manuelle Zuordnung.
  • Echte Sub-Accounts bei IBKR (Advisor/Family-Struktur) als brokerseitige Trennung. Erwogen und verworfen: erfordert Kontotypwechsel und feste Vorabaufteilung des Kapitals, deutlich unflexibler als virtuelle BĂŒcher.

15. Offene Punkte

  • MindestordergrĂ¶ĂŸe pro Buch: ein Wert in KontobasiswĂ€hrung, FremdwĂ€hrungsorders per Tageskurs dagegen geprĂŒft. Konkreter Wert beim Bauen festzulegen.
  • Konkrete Limitwerte (MaxSymbolPercent, HouseReserve, FX-Haircut, Slippage-Puffer, TTL) – Startwerte beim Bauen festzulegen und in settings.example.json dokumentieren.
  • Handelsplatz-Whitelist: konkrete Börsenliste je WĂ€hrung.
  • Umsetzungsreihenfolge – noch nicht besprochen.

Zusammenfassung der getroffenen Entscheidungen

# Entscheidung
1 Cash-Konto; Modul-Handel strikt cash-only, manueller Handel darf Margin nutzen
2 Kein Kapitaltransfer zwischen BĂŒchern – ein Pool plus Obergrenzen; niemals aktives Schließen zum Balancieren
3 Limit-Verletzung: hartes Gate, strukturiertes Feedback; die Reaktion entscheidet die Strategie
4 KontobasiswÀhrung USD (Produktion) / EUR (Test), bei Ersteinrichtung gesetzt und danach gesperrt
5 Nur USD und EUR handelbar; Contract-Auflösung mit WÀhrungs- und Handelsplatz-Whitelist ist Pflicht
6 Steuerbuch strikt getrennt, Flex Query als einzige Quelle, Jurisdiktionsprofil einmalig und in der DB verankert
7 Unzugeordnete Positionen: QuarantÀne + Eskalation nach 30 Minuten mit Backoff
8 Benachrichtigungen ĂŒber Outbox + Sink-Abstraktion; Matrix als Zielkanal, Telegram optional