Der erste Lauf gegen die Testmaschine zeigte den Fehler sofort: 2 Stueck SAP in
DIAG, 2 in UNASSIGNED, der Broker fuehrt 4 - alles richtig, aber zeilenweise
verglichen meldete die Ansicht zwei Fehlbestaende. Der Broker kennt unsere
Buecher nicht; vergleichbar ist nur die Summe ueber alle. ManagedPosition traegt
jetzt OwnTotalQuantity, und Diverges misst daran. Zwei Tests halten beide
Richtungen fest: eine aufgeteilte Position ist keine Abweichung, eine echte
verschwindet nicht in der Summe.
Dazu --lock und --instrument-rule fuer den kopflosen Betrieb. Beide mit
Trockenlauf; die Stufe "Locked" schreibt vor dem Setzen aus, dass sie auch das
SCHLIESSEN durch Module verhindert - das gehoert dorthin, wo entschieden wird,
nicht in den Stoerungsfall.
Auf der Testmaschine durchgespielt: GOOG von UNASSIGNED nach MANUAL umgebucht
(Menge und Einstand unveraendert), dann auf CloseOnly gesetzt - beides steht in
der Uebersicht.
473 Tests gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Erster Teil von #485. Der PositionManager im Core beantwortet drei Fragen, die
sich beim Debuggen sofort stellen: Wem gehoert eine Position, was sagt der Broker
dazu, und was ist gesperrt.
Drei Zugaenge auf denselben Dienst - das Fenster der Shell, --positions und
--reassign im kopflosen Betrieb, GET /api/positions. Der Testbetrieb laeuft als
systemd-Dienst; ein Werkzeug, das nur in der Oberflaeche existiert, fehlt genau
dann, wenn man es braucht.
Entscheidungen, die im Code begruendet stehen:
- BrokerQuantity ist nullable und heisst "nicht bekannt", nicht "null Stueck".
Ohne Verbindung sieht ein leergeraeumtes Konto genauso aus wie eine Stoerung;
aus dem einen darf nicht auf das andere geschlossen werden.
- Umbuchen aendert die Zuordnung, nie die Menge. Eine Umbuchung, die eine
Stueckzahl bewegt, waere ein Handel ohne Order und stuende in keiner Historie.
- Gegen eine entgegengesetzte Position wird abgelehnt: Das waere eine
Glattstellung und gehoert ueber eine Order gemacht, mit Preis und Historie.
- Das Quellbuch ist Pflicht - Schutz gegen die falsche Zeile -, ebenso eine
Begruendung, sonst ist der Eingriff spaeter nicht mehr erklaerbar.
- Das Cap des Zielbuchs sperrt NICHT. Die Position existiert bereits; sie zu
benennen erzeugt kein neues Risiko. Wuerde die Grenze das verhindern, bliebe
jede zu grosse Position fuer immer in UNASSIGNED.
- Der REST-Endpunkt ist lesend. Der Listener kennt keine Anmeldung; ein
schreibender Zugriff waere ein Eingriff in die Buecher, den niemand belegen kann.
Beim ersten Testlauf gefunden: (Module, ContractKey) ist der Primaerschluessel
von core_position, das Buch laesst sich in der Zeile nicht ueberschreiben.
Umgebucht wird deshalb durch Loeschen und Neuanlegen.
471 Tests gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>