Abweichung wird je Instrument bestimmt, Sperren auch kopflos setzbar
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>
This commit is contained in:
@@ -248,4 +248,56 @@ public class PositionManagerTests
|
||||
overview.Positions[0].Lock.Should().Be(PositionLock.CloseOnly);
|
||||
overview.Positions[0].IsRestricted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Overview_DoesNotCallASplitPositionADivergence()
|
||||
{
|
||||
// Am 2026-09-06 auf der Test-VM aufgefallen: 2 Stück SAP in DIAG, 2 in UNASSIGNED, Broker
|
||||
// führt 4 - alles richtig. Zeilenweise verglichen meldete die Ansicht zwei Fehlbestände.
|
||||
// Der Broker kennt unsere Bücher nicht; vergleichbar ist nur die Summe.
|
||||
var sut = CreateSut(out _);
|
||||
|
||||
_portfolio.GetAllPositionsAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Position>>(
|
||||
[
|
||||
new Position("DIAG", Sap, 2, 185m),
|
||||
new Position(BookId.Unassigned.Value, Sap, 2, 187m)
|
||||
]));
|
||||
|
||||
_broker.GetPositionsAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<BrokerPosition>>(
|
||||
[new BrokerPosition { Symbol = "SAP", SecType = "STK", Currency = "EUR",
|
||||
ConId = 1, Quantity = 4, AvgCost = 186m, Instrument = Sap }]));
|
||||
|
||||
var overview = await sut.GetOverviewAsync();
|
||||
|
||||
overview.Positions.Should().HaveCount(2);
|
||||
overview.Positions.Should().OnlyContain(p => !p.Diverges, "2 + 2 sind die 4 des Brokers");
|
||||
overview.Positions.Should().OnlyContain(p => p.OwnTotalQuantity == 4);
|
||||
overview.Positions.Should().OnlyContain(p => p.IsSharedAcrossBooks);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Overview_StillFindsARealDivergenceAcrossBooks()
|
||||
{
|
||||
// Die Gegenprobe: Summiert wird, aber nicht weggerechnet. Fehlt beim Broker ein Stück,
|
||||
// muss es auffallen - sonst hätte die Zusammenfassung die Prüfung abgeschafft.
|
||||
var sut = CreateSut(out _);
|
||||
|
||||
_portfolio.GetAllPositionsAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Position>>(
|
||||
[
|
||||
new Position("DIAG", Sap, 2, 185m),
|
||||
new Position(BookId.Unassigned.Value, Sap, 2, 187m)
|
||||
]));
|
||||
|
||||
_broker.GetPositionsAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<BrokerPosition>>(
|
||||
[new BrokerPosition { Symbol = "SAP", SecType = "STK", Currency = "EUR",
|
||||
ConId = 1, Quantity = 3, AvgCost = 186m, Instrument = Sap }]));
|
||||
|
||||
var overview = await sut.GetOverviewAsync();
|
||||
|
||||
overview.Positions.Should().OnlyContain(p => p.Diverges, "wir führen 4, der Broker 3");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user