Commit Graph
4 Commits
Author SHA1 Message Date
RichardandClaude Opus 5 e7e3970dec Orders, die beim Broker liegen, gelten nicht mehr als gescheitert
Am geschlossenen Markt gemessen: IBKR nimmt eine Order an und merkt sie fuer
die naechste Eroeffnung vor. Dazu schickt es Code 399 - eine Mitteilung, deren
Text mit "Warning" beginnt. Der Adapter las jede Meldung aus dem Fehler-Callback
als Ablehnung, meldete "Order abgelehnt", und das Kapitalmodell gab die Bindung
frei. Auf dem Testkonto lagen dadurch 67 Orders ueber 306 BAS, 140 SAP und 43 ALV
beim Broker, vorgemerkt fuer Montag 09:00, ohne eine einzige Reservierung dahinter.

OrderResult kannte nur "erfolgreich" und "gescheitert". Der haeufigste Fall
passte in keines von beiden. Es gibt jetzt einen dritten Ausgang - Working:
abgesendet, Ausgang offen. Die Trennlinie ist, ob BEWIESEN ist, dass beim Broker
nichts liegt; ohne Beweis bleibt das Kapital gebunden. Eine Bindung, die zu lange
steht, kostet Spielraum und faellt auf. Eine, die zu frueh verschwindet, kostet
Geld und faellt nicht auf.

- 399/404 sind Ordermeldungen, keine Ablehnungen; nur 201/202/203 u. a. beenden
  eine Order beweisbar. Ein Verbindungsabbruch beendet unsere Sicht, nicht die Order.
- IsDeadStatus ist enger als IsTerminalStatus: "Inactive" ist kein Beweis.
- ExecutionService haelt die Bindung bei Working (MarkSubmittedAsync statt
  CancelReservationAsync) und journalisiert Pending/OrderWorking statt Failed.
- Neu lesbar: das Orderbuch des Brokers (reqAllOpenOrders) samt Storno.
  --open-orders stellt Orderbuch und eigene Bindungen gegenueber,
  --cancel-order <ID>|all --confirm nimmt zurueck (Sammelstorno nur im Paper-Modus).
- Der Wiederanlauf-Abgleich lief bisher gegen eine leere Orderliste und haette
  ab jetzt jede gesunde Bindung in Quarantaene gestellt. Er sitzt jetzt im
  ReservationWatchdogWorker, hinter dem Beweis, dass der Broker antwortet.

457 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 12:27:32 +02:00
RichardandClaude Opus 5 9e0d3b229a Kursabfrage nimmt das Instrument statt nur das Symbol
Ohne Waehrung wird jeder Kontrakt als USD gesucht: ein Wert, der nur in
EUR notiert, ist dann "nicht aufloesbar", und die Ursache steht
nirgends. Beim Order-Nachweis gegen MIGA:EUR genau so aufgetreten - die
Kontraktaufloesung fuer die ORDER war bereits waehrungsfaehig, die fuer
den KURS nicht, und damit brach die Kette eine Stufe vorher ab.

Dieselbe Aenderung ist die Voraussetzung fuer Optionskurse (#299): ohne
Kontraktangaben laesst sich eine Option ueberhaupt nicht abfragen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 15:41:26 +02:00
RichardandClaude Opus 5 2a73172e27 Instrumente sind waehrungsfaehig
Die Waehrung gehoert zur Identitaet eines Instruments und nicht zu
seiner Beschreibung: derselbe Ticker kann an mehreren Plaetzen in
verschiedenen Waehrungen notieren, und ein Kauf darf nur aus Bargeld
derselben Waehrung finanziert werden (Kapitalmodell §4 Schicht C). Zwei
Notierungen als eine Position zu fuehren, wuerde Bestand und Deckung
vermischen.

USD bleibt im Instrumentenschluessel IMPLIZIT ("AAPL", nicht
"AAPL:USD"). Andernfalls waere jede Bestandszeile ab sofort ein anderes
Instrument als vorher und aus einer Position wuerden zwei. Trennzeichen
ist der Doppelpunkt und nicht der Punkt - Ticker enthalten Punkte
(BRK.B).

Neu: Currencies (kanonische Schreibweise an allen vier Stellen, die sie
gleich haben muessen), Currency an OptionSpec, InstrumentRef,
TradeSignal, OrderRequest und core_position. CapitalService nimmt die
Waehrung ab jetzt aus dem Instrument statt vom Aufrufer - wer sie
uebergeben koennte, koennte die Deckungspruefung gegen den falschen Topf
laufen lassen. --verify-order kennt --currency.

Anlass: das Paper-Konto haelt EUR 91.832 und USD -3.751. Ein
USD-Nachweis waere ein USD-Kredit gewesen und wurde von Schicht C
zu Recht abgelehnt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 15:39:30 +02:00
RichardandClaude Opus 5 084cd7ef77 Options-Fundament und Kapitalmodell im Core; Modul OptionsWheel
Build & Test / build (ubuntu-latest) (push) Canceled after 0s
Build & Test / build (windows-latest) (push) Canceled after 0s
Das OptionsWheel setzt auf Dingen auf, die es im Core nicht gab. Diese
Sitzung baut sie.

#298 Optionen als Instrument. InstrumentKind/OptionSpec und ein
druckbarer Instrumentenschluessel ("AAPL|20260918|C|150"); TradeSignal
und OrderRequest tragen ein optionales OptionSpec, ohne das sich der
Aktienpfad unveraendert verhaelt. Position.Notional rechnet ab jetzt mit
der Kontraktgroesse - vorher war jede Option um Faktor 100 zu klein
bewertet und damit jedes Risikolimit wirkungslos, lautlos und in die
gefaehrliche Richtung. Daneben neu BoundCapital: ein Short Put bindet
Strike x Kontraktgroesse, nicht die vereinnahmte Praemie.

#300 sell-to-open. Jeder Auftrag zerfaellt in einen schliessenden und
einen eroeffnenden Teil; der schliessende wird von keinem Limit
verhindert - auch nicht vom Kaufstopp, denn ein Rueckkauf baut eine
Verpflichtung ab. Deckungspruefung im Core, nicht im Modul: Short Call
nur mit freien Aktien, Short Put nur mit reservierbarem Bargeld.

#302-#305 Kapital- und Buchmodell. Buecher mit reservierten Namen und
Eigentumsregeln, Pool mit Caps und Headroom, Margin-Sperre in vier
Schichten, core_reservation mit Lebenszyklus, Frist, Idempotenz ueber
(SignalId, ContractKey) und Quarantaene beim Start.

#309/#310 Modul OptionsWheel: ow_-Schema mit fuenf Tabellen,
Zustandsautomat, StrikeSelector, RollDecider, PremiumMath - vollstaendig
ohne Broker testbar. Der Handelsbetrieb bleibt gesperrt, solange #299
und #294 fehlen; das Modul sagt das ueber GetActivationBlocker, statt
still nichts zu tun.

#293 --verify-order am Daemon: eine Order durch die vollstaendige Kette
(Buch, Risiko, Bindung, Order, Fill, Buchung, Abschluss). Ohne --confirm
ein Trockenlauf; Abbruch ausserhalb von Paper-Modus UND Paper-Port.

Drei Widersprueche in den Konzepten sind dabei entschieden worden:
Schicht B heisst ab jetzt "kein UNGEDECKTER Short" (der Grund der Regel
war der Kredit, nicht der Short), die Hausreserve wird einmal abgezogen
statt zweimal, und der Positionsschluessel ist eine Spalte statt eines
Sechser-Verbunds (MySQL verlangt NOT NULL fuer Schluesselspalten).
Begruendungen stehen in docs/ROADMAP.md.

Enthaelt ausserdem die noch nicht committete Arbeit aus der vorigen
Sitzung: die Fehlerbehebungen aus Epic X (WorkerBase-Intervall,
BackupWorker, --check gegen die Datenbank, CapitolTrades-429, SIGTERM)
samt DatabaseEndpoint, MysqlDumpTool und der Roadmap-Umstellung. Sie lag
im Arbeitsbaum und liess sich nicht abtrennen, weil beide Staende
dieselben Dateien beruehren.

213 -> 369 Tests, Build ohne Warnung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 09:35:38 +02:00