IBKR: Zeitkontext einer Verbindung nachvollziehbar machen
ResolveExecutionTime liefert neben dem UTC-Zeitpunkt jetzt die Herkunft der verwendeten Zeitzone (gemeldet / angenommen / unbekannt / unlesbar). Bisher war im Nachhinein nicht unterscheidbar, ob ein Buchungszeitpunkt von TWS stammte oder eine Annahme war - genau der Fehler, der beim Umzug zwischen EU- und US-Host lautlos entsteht. IbkrConnection schreibt beim Verbinden einmalig Betriebszeitzone, Systemzeitzone und den Versatz zur TWS-Serverzeit ins Log; ab 5 s Abweichung gilt die Uhr des Hosts als verstellt. TWS-Setup-Checkliste um den Linux-Abschnitt ergaenzt (Betrieb und Umgebung unterscheiden sich, das Protokoll nicht). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -165,6 +165,71 @@ public class IbkrMappingTests
|
||||
private static readonly TimeZoneInfo Berlin = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
|
||||
private static readonly TimeZoneInfo NewYork = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
|
||||
|
||||
// ─── Herkunft der Zeitangabe (Beobachtbarkeit) ────────────────────────────
|
||||
//
|
||||
// Ohne die Herkunft lässt sich später nicht mehr unterscheiden, ob ein Buchungszeitpunkt von
|
||||
// TWS gemeldet oder von uns angenommen wurde. Genau daran hängt die Diagnose, wenn eine
|
||||
// Instanz von einem EU- auf einen US-Host umzieht.
|
||||
|
||||
[Fact]
|
||||
public void ResolveExecutionTime_MitZone_MeldetGemeldeteHerkunft()
|
||||
{
|
||||
var stamp = IbkrMapping.ResolveExecutionTime("20260804 09:30:00 America/New_York", Berlin);
|
||||
|
||||
stamp.Source.Should().Be(IbkrMapping.ExecutionTimeSource.ReportedZone);
|
||||
stamp.IsAssumed.Should().BeFalse();
|
||||
stamp.ReportedZone.Should().Be("America/New_York");
|
||||
stamp.ZoneUsed.Should().Contain("New_York");
|
||||
stamp.Utc.Should().Be(new DateTime(2026, 8, 4, 13, 30, 0, DateTimeKind.Utc));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveExecutionTime_OhneZone_MeldetAnnahme()
|
||||
{
|
||||
// Der Normalfall bei execDetails - und damit die Stelle, die beobachtet werden muss.
|
||||
var stamp = IbkrMapping.ResolveExecutionTime("20260804 17:39:18", Berlin);
|
||||
|
||||
stamp.Source.Should().Be(IbkrMapping.ExecutionTimeSource.FallbackZone);
|
||||
stamp.IsAssumed.Should().BeTrue();
|
||||
stamp.ReportedZone.Should().BeNull();
|
||||
stamp.ZoneUsed.Should().Be(Berlin.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveExecutionTime_UnbekannteZone_IstAlsAnnahmeErkennbar()
|
||||
{
|
||||
// Weicht auf die Betriebszeitzone aus - aber unterscheidbar von "TWS meldete nichts",
|
||||
// denn hier hat TWS etwas gemeldet, das dieses System nicht kennt.
|
||||
var stamp = IbkrMapping.ResolveExecutionTime("20260804 17:39:18 Gibt/EsNicht", Berlin);
|
||||
|
||||
stamp.Source.Should().Be(IbkrMapping.ExecutionTimeSource.UnknownZoneFallback);
|
||||
stamp.IsAssumed.Should().BeTrue();
|
||||
stamp.ReportedZone.Should().Be("Gibt/EsNicht");
|
||||
stamp.ZoneUsed.Should().Be(Berlin.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveExecutionTime_Unlesbar_IstAlsDefektErkennbar()
|
||||
{
|
||||
var stamp = IbkrMapping.ResolveExecutionTime("Unsinn", Berlin);
|
||||
|
||||
stamp.Source.Should().Be(IbkrMapping.ExecutionTimeSource.Unparsable);
|
||||
stamp.Utc.Should().BeNull();
|
||||
// Unlesbar ist keine Annahme, sondern ein Defekt - die Warnung im Log ist eine andere.
|
||||
stamp.IsAssumed.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveExecutionTime_UsHost_LiefertDenselbenZeitpunktWieEuHost()
|
||||
{
|
||||
// Der eigentliche Regressionsschutz fuer den geplanten Umzug: Meldet TWS die Zone, darf die
|
||||
// Betriebszeitzone der Instanz das Ergebnis NICHT mehr veraendern.
|
||||
const string raw = "20260804 09:30:00 America/New_York";
|
||||
|
||||
IbkrMapping.ResolveExecutionTime(raw, Berlin).Utc
|
||||
.Should().Be(IbkrMapping.ResolveExecutionTime(raw, NewYork).Utc);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseExecutionTime_OhneZone_RechnetGegenDieBetriebszeitzone()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user