Commit Graph
35 Commits
Author SHA1 Message Date
RichardandClaude Opus 5 87194bfc48 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>
2026-08-22 10:44:41 +02:00
RichardandClaude Opus 5 c176b05ea1 L6: IBKRTrader.App.Avalonia -> IBKRTrader.App; letzte WinForms-Spuren raus
Build & Test / build (ubuntu-latest) (push) Waiting to run
Build & Test / build (windows-latest) (push) Waiting to run
Das Suffix ".Avalonia" gab es nur, weil daneben ein WinForms-IBKRTrader.App
stand. Das ist seit L5 weg, also faellt auch das Suffix. Git erkennt alle
Dateien als Umbenennung; Assembly, Wurzel-Namensraum und die
avares://-Ressourcen-URI sind mitgezogen.

Nebeneffekt der Umbenennung: die global::Avalonia-Qualifizierungen entfallen.
Sie waren noetig, weil der Namensraum IBKRTrader.App.Avalonia das
Avalonia-Paket verdeckt hat - ein Ueberbleibsel genau der Namensgebung, die
jetzt weg ist.

Inhaltlich falsch gewordene Aussagen berichtigt - das waren die eigentlichen
Ueberbleibsel, nicht die Kommentare:
- .agents/rules/grundregeln.md schrieb weiterhin "C# .NET 10 WinForms",
  RichTextBox-Logging, LauncherForm und PropertyGrid vor. Das ist die Regel,
  nach der kuenftig gearbeitet wird - sie haette die Portierung Stueck fuer
  Stueck rueckgaengig gemacht. Jetzt: Avalonia, keine Plattform-Suffixe, die
  11er-Pinnung mit Begruendung, dazu die beiden Regeln, die uns in L1b am
  meisten gekostet haben (UTC persistieren + AppTimeZone statt DateTime.Now;
  jede Formatierung mit ausdruecklichem IFormatProvider).
- Core: LogEntry ("wird in RichTextBox geschrieben"), IWorker/WorkerEngine/
  WorkerInfo ("DataGridView-Zeile"/"-Binding"), ModuleView ("die
  WinForms-Shell castet auf Form").
- Doku: ARCHITECTURE (Modul-Ui-Ordner, "designbare Forms mit Initialize"),
  KONZEPT-Modul-Accounting ("UI (WinForms, ein Fenster mit Tabs)").

BEWUSST STEHEN GEBLIEBEN sind die Kommentare, die WinForms nur als
Begruendung nennen - warum LoggingService ein Ereignis hat statt einer
RichTextBox, warum ModuleView Func<object> liefert, warum es benannte
Record-Zeilentypen gibt, warum die Einstellungsmaske aus Attributen entsteht.
Das ist die Herleitung des heutigen Entwurfs; ohne sie sieht spaeter jede
dieser Stellen nach Umstaendlichkeit ohne Grund aus.

KONZEPT-Linux-Portierung.md bekommt einen Statusvermerk: umgesetzt, die
Pfadangaben im Fundstellenverzeichnis beziehen sich auf den alten Aufbau.
Zwei Abweichungen von der Schaetzung sind dort festgehalten - der geringere
Aufwand dank der PolytraderSharp-Vorlage, und dass die dort empfohlene
InvariantGlobalization ein Fehler gewesen waere.

Verifiziert: Build 0 Fehler/0 Warnungen, 193 Tests gruen, Smoke-UI
konstruiert alle 7 Ansichten + Launcher + Dialog, Daemon-Prueflauf OK,
publish -r linux-x64 fuer beide Einstiegspunkte fehlerfrei.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 21:16:48 +02:00
RichardandClaude Opus 5 d86a083438 L5: WinForms vollstaendig entfernt - das Projekt ist plattformneutral
Die Avalonia-Shell hatte in L4 Funktionsgleichheit erreicht, damit ist die
WinForms-Fassung ueberfluessig. Entfernt: IBKRTrader.App.csproj, Program.cs,
LauncherForm.cs, UI/ (14 Dateien) und Properties/Resources.* - zusammen rund
1.900 Zeilen. Rueckfallpunkt bleibt der Tag winforms-final.

Resources/ mit den 24 PNG-Symbolen bleibt: die Avalonia-Shell bindet sie
ueber AvaloniaResource ein und nutzt dieselben Symbolschluessel.

Kein Projekt traegt mehr eine Plattformbindung. Verifiziert: alle acht
Projekte bauen einzeln fuer linux-x64, und die gesamte Projektmappe baut
ohne Fehler und ohne Warnung.

Die CI kann damit vereinfacht werden: der Behelf aus L4 - unter Linux die
Projekte einzeln statt der Mappe zu bauen, weil IBKRTrader.App dort nicht
baubar war - entfaellt. Beide Plattformen bauen und testen jetzt dieselbe
Mappe.

Doku nachgezogen: README (Architektur-Uebersicht, Start- und Pruefbefehle),
ARCHITECTURE (Ziel-Architektur auf den Ist-Stand, neuer Abschnitt L0-L5 in
der Phasen-Checkliste, AppTimeZone ergaenzt). Der Hinweis "UI-Contract liegt
im Core" war nach L1a falsch - WindowMenu ist dort raus, der Contract ist
jetzt toolkit-neutral.

Verifiziert: Build 0 Fehler/0 Warnungen, 193 Tests gruen, Smoke-UI
konstruiert alle 7 Ansichten + Launcher + Dialog, Daemon-Prueflauf OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:35:01 +02:00
RichardandClaude Opus 5 3513a0b2d9 L4: Modul-Fenster auf Avalonia - Funktionsgleichheit mit der WinForms-Shell
Die drei Modul-Fenster sind portiert; die Avalonia-Shell zeigt jetzt
dieselben sieben Ansichten wie die WinForms-Shell.

- CongressTradingWindow: Kennzahlen als Kacheln, manueller Scrape-Ausloeser,
  offene Positionen des Moduls.
- SupervisorWindow: Analyse mit Live-Anzeige der Tool-Aufrufe, Dossier-
  Browser mit Splitter, Berichte, Hinweise. Der Hinweistext nennt jetzt die
  Betriebszeitzone, weil die Tagesbericht-Stunde in ihr gilt und nicht in
  der Zeitzone des Rechners.
- AccountingWindow: gemeinsame Filterleiste, Uebersicht/BWA, Ledger, Steuer
  (Platzhalter), Export und Abruf/Status.

Ersetzte WinForms-Bausteine:
- SaveFileDialog -> IStorageProvider.SaveFilePickerAsync (asynchron, anderer
  Zuschnitt). Betrifft die drei Exporte des Accounting-Moduls.
- MessageBox bei Fehlern -> Statuszeile im Fenster. Ein modaler Dialog fuer
  einen fehlgeschlagenen Ladevorgang war ohnehin zu laut.
- Anonyme Typen an DataGridView.DataSource -> benannte Records. Kompilierte
  Bindings pruefen die Spalten dadurch beim Kompilieren; ein Tippfehler in
  einer Spaltendefinition (Binding="{Binding Profile}}") ist beim Build
  aufgefallen statt im Betrieb.

Accounting-Betraege werden beim Laden gegen InvariantCulture formatiert, das
Delta eines Ingest-Laufs ist nullable behandelt (ohne Saldo-Anker gibt es
keins) - vorher waere dort eine NullReferenceException moeglich gewesen.

CI-Matrix (Gitea Actions, Actions-kompatibel): ubuntu-latest und
windows-latest. Sie ist der Waechter gegen Rueckfaelle - ein neues
DateTime.Now, ein ToString ohne Formatanbieter oder eine WinForms-Referenz
im Core faellt auf dem Entwicklungsrechner nicht auf, hier schon. Der
Linux-Lauf baut bewusst NICHT die ganze Mappe, weil IBKRTrader.App
(net10.0-windows) dort nicht baubar ist; die Aufzaehlung entfaellt, sobald
die WinForms-Shell aus dem Build genommen wird.

Der Smoke-UI-Lauf ist Teil der CI - mit Avalonia braucht er kein
Anzeigegeraet mehr (SetupWithoutStarting). Mit WinForms war das auf einem
Build-Server nicht moeglich.

Verifiziert: Build 0 Fehler/0 Warnungen, 193 Tests gruen, Smoke-UI
konstruiert alle 7 Ansichten + Launcher + Dialog, publish -r linux-x64
liefert 32 MB mit ELF-Launcher. Die WinForms-Shell ist unveraendert
lauffaehig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:25:54 +02:00
RichardandClaude Opus 5 afae3c9c4a L3: Avalonia-Shell und Core-Ansichten - die Oberflaeche laeuft auf Linux
Neues Projekt IBKRTrader.App.Avalonia (net10.0, plattformneutral) mit
Launcher, Fenster-Menue, Beenden-Abfrage und den vier Core-Ansichten
Dashboard, Workers, Logs und Settings. Nutzt denselben AppHostBuilder wie
der Daemon; ShellServices ergaenzt nur, was ohne Oberflaeche nicht existiert.

Versionen bewusst auf der 11er-Linie: Avalonia 11.3.19, DataGrid 11.3.13.
LiveCharts2 2.0.5 ist gegen Avalonia 11 gebaut und bricht unter 12
(Gestures.PinchEvent gibt es dort nicht mehr). Diagramme kommen mit den
neuen Modulen - bis LiveCharts2 Avalonia 12 unterstuetzt, darf hier nicht
angehoben werden. Erfahrung aus PolytraderSharp, im csproj vermerkt.

Ersatz fuer WinForms-Bausteine ohne Gegenstueck:
- PropertyGrid -> SettingsModelBuilder erzeugt die Maske aus den bereits
  vorhandenen Category-/DisplayName-/Description-Attributen von AppSettings.
  Eine neue Einstellung erscheint damit automatisch, ohne dass jemand die
  Oberflaeche anfasst - genau der Vorteil des PropertyGrid. Kennwortfelder
  (DB-Passwort, Flex-Token) werden verdeckt. Gemessen: 11 Abschnitte,
  41 Felder.
- MessageBox.Show -> ShutdownConfirmWindow (Avalonia bringt keinen
  Meldungsdialog mit). Schliessen ueber das X zaehlt als Abbruch, damit ein
  versehentlicher Klick nie den Handelsbetrieb stoppt.
- RichTextBox mit SelectionColor -> eingefaerbte Elemente je Logzeile, mit
  Filter, Auto-Scroll und Zeilenbegrenzung (im Dauerbetrieb waere die Liste
  sonst unbegrenzt gewachsen).
- ToolStrip/StatusStrip -> zentrale Stilklassen in App.axaml (toolbar,
  statusbar, kpi, section). Die neuen Module setzen darauf auf.

Gemeinsame Bausteine bewusst jetzt schon zentral, weil die neuen Module
direkt in Avalonia entwickelt werden sollen.

Kompilierte Bindings sind aktiv (x:DataType je Datenkontext) - Tippfehler in
Bindings fallen damit beim Kompilieren auf statt erst zur Laufzeit. Dafuer
brauchte es benannte Record-Zeilentypen statt der anonymen Typen, die
DataGridView.DataSource frueher bekommen hat.

--smoke-ui laeuft jetzt ueber SetupWithoutStarting, also OHNE Anzeigegeraet
und ohne laufende Dienste. Das war mit WinForms nicht moeglich und macht die
Konstruktionspruefung erstmals CI-tauglich. Der Host wird dabei bewusst nicht
gestartet, sonst liefen Worker und Broker-Verbindungen gegen die echten
Endpunkte an.

AVLN3001 unterdrueckt: die Fenster haben absichtlich keinen parameterlosen
Konstruktor. Einer wuerde sie ohne ihre Dienste konstruierbar machen und
genau den Fehler verdecken, den die Konstruktionspruefung finden soll.

Verifiziert: Build 0 Fehler/0 Warnungen, 193 Tests gruen, Avalonia-Smoke-UI
konstruiert alle 6 Fenster, publish -r linux-x64 liefert 32 MB mit
ELF-Launcher samt libSkiaSharp.so/libHarfBuzzSharp.so und ohne
Windows-Abhaengigkeiten. Die WinForms-Shell ist unveraendert lauffaehig.

Offen fuer L4: die drei Modul-Fenster (ModuleViews ist noch leer).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:18:44 +02:00
RichardandClaude Opus 5 9c7e19149c L2: Kopfloser Linux-Dienst - der Trading-Kern laeuft ohne Oberflaeche
Meilenstein: Trading, Worker, Accounting, Supervisor, REST und MCP laufen
als systemd-Dienst auf Linux. Nur noch IBKRTrader.App ist Windows-gebunden.

Neu IBKRTrader.Hosting: die komplette Host-Zusammenstellung, aus der
WinForms-Program.cs herausgezogen. Bewusst ein eigenes Projekt - laege sie
weiter in der Shell, muesste sie fuer den Daemon dupliziert werden, und
beide wuerden auseinanderlaufen. Ein Modul, das nur in einer Variante
registriert ist, faellt sonst erst im Betrieb auf. RunStartupChecks buendelt
die Startschritte in fester Reihenfolge (Zeitzone vor dem ersten Logeintrag,
Master-Key vor jeder Entschluesselung).

Neu IBKRTrader.Daemon: kopfloser Einstiegspunkt mit SIGTERM-Behandlung,
--check (Trockenlauf: Host bauen, Startpruefungen, keine Boersenverbindung -
fuer Deployment und CI) und --db-version.

AppPaths: Logs, Backups, settings.json und master.key lagen neben der
Binaerdatei. Unter /opt hat der Dienstbenutzer dort keinen Schreibzugriff -
der Dienst waere beim ersten Logeintrag gescheitert. Aufloesung jetzt:
Umgebungsvariable, sonst Binaerverzeichnis WENN beschreibbar (haelt Windows
und die Entwicklung unveraendert), sonst FHS. Der Schreibtest ist ein echter
Schreibversuch - Attributpruefung traegt nicht, weil unter Linux
Besitzer/Gruppe/Modus und unter Windows die ACL entscheiden.

Rechtepruefung fuer master.key/openrouter.key auf Unix: Windows-ACLs
uebertragen sich beim Kopieren auf einen Linux-Host nicht, eine key-Datei mit
644 waere dort fuer jeden lokalen Nutzer lesbar. Nur eine Warnung.

InvariantGlobalization ausdruecklich auf false. Der naheliegende Griff zum
schlanken Image waere hier ein Eigentor gewesen und haette genau die zwei
Punkte aus L1b lautlos rueckgaengig gemacht: ohne ICU faellt die Aufloesung
von Windows-Zeitzonen-IDs aus (Rueckfall auf UTC im Container) und
CultureInfo.GetCultureInfo("de-DE") liefert die invariante Kultur, womit die
PDF-Betraege wieder das Format wechseln.

systemd: Unit mit Type=notify plus UseSystemd() im Host - ohne sd_notify
haette systemctl start bis zum Timeout gehangen. Unit mit Absicherung
(ProtectSystem=strict, ReadWritePaths), deploy/README.md mit Voraussetzungen,
Verzeichnissen, Zeitzonen-Festlegung und dem, was der Daemon NICHT loest
(IB Gateway headless bleibt eine eigene Baustelle).

Verifiziert: 193 Tests gruen (+5), Build 0 Fehler/0 Warnungen, --smoke-ui
konstruiert alle 7 Fenster, --check laeuft durch, und publish -r linux-x64
liefert 11 MB mit ELF-Launcher, ohne eine einzige Windows-Abhaengigkeit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:09:33 +02:00
RichardandClaude Opus 5 8b9b993d1d L1b/2: Kultur und Dateisystem plattformunabhaengig machen
Kultur - Ausgaben und Parsen haengen nicht mehr am Host:

- PdfExporter formatierte Betraege mit ToString("N2") ohne Formatanbieter,
  also CurrentCulture. Auf dem deutschen Desktop "1.234,56", in einem
  Container mit LANG=C "1,234.56" - dieselbe Zahl, fuer einen Leser eine
  andere. Fuer ein ausdruecklich pruefbares Dokument jetzt fest de-DE.
- CapitolTradesScraper.ParseDate nutzte DateOnly.TryParse ohne
  Formatanbieter. Das ist nicht theoretisch: gemessen wurde aus
  "2026-08-04" unter th-TH das Jahr 1483 (buddhistischer Kalender), unter
  fa-IR das Jahr 2647 (persischer Kalender), unter ar-SA schlug das Parsen
  ganz fehl. de-DE und en-US kommen mit ISO klar - genau deshalb faellt so
  etwas auf dem Entwicklungsrechner nie auf. Jetzt TryParseExact mit
  InvariantCulture; ein Formatwechsel der Quelle faellt damit auf, statt
  still ein falsches Datum zu erzeugen. Regressionstest ueber vier Kulturen.
- IBKRGatewayService baute den Query-Parameter mit .ToString().ToLower()
  (Tuerkisch-I) - jetzt fest "true"/"false".

PDF-Schriften: PDFsharp 6 loest auf Nicht-Windows-Plattformen nichts von
selbst auf, "Segoe UI" gibt es dort nicht - der Export waere zur Laufzeit
gescheitert. Neuer DocumentFontResolver: unter Windows bleibt die Plattform
zustaendig (unveraenderte Optik), auf Linux wird eine freie Systemschrift
gesucht (DejaVu/Liberation/Noto/FreeSans). Bewusst keine Schrift im Repo -
das erspart eine Lizenzfrage; fehlt sie, nennt die Fehlermeldung das zu
installierende Paket.

BackupWorker:
- Suchte "mysqldump.exe" in C:\Program Files\... und splittete PATH mit ';'.
  Auf Linux ist das Trennzeichen ':' - der gesamte PATH waere als ein
  Eintrag gelesen worden. Jetzt Path.PathSeparator, plattformabhaengige
  Suchpfade und zusaetzlich "mariadb-dump" (MariaDB hat mysqldump ab 10.5
  umbenannt).
- Das DB-Passwort stand als Kommandozeilenargument im Prozessbaum. Unter
  Linux ist /proc/<pid>/cmdline fuer jeden lokalen Nutzer lesbar - das waere
  eine neue Offenlegung gewesen, die es unter Windows so nicht gab. Jetzt
  ueber MYSQL_PWD, nur an den Kindprozess vererbt. Argumente einzeln statt
  als Zeichenkette (kein Quoting-Problem bei Pfaden mit Leerzeichen).

Verifiziert: 188 Tests gruen (+5), Build 0 Fehler/0 Warnungen, Core + 3
Module + Tests bauen fuer linux-x64, --smoke-ui konstruiert alle 7 Fenster.

Offen aus L1b und nach L2 verschoben: IAppPaths (Logs/Backups/settings.json/
master.key liegen neben der Binaerdatei; unter /opt ist das nicht schreibbar).
Gehoert zum Daemon, wo die Pfade tatsaechlich gebraucht werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:58:10 +02:00
RichardandClaude Opus 5 d8273c3a1e L1b/1: Betriebszeitzone statt Rechnerzeit - EU- und US-Instanzen sauber trennen
Wir betreiben Instanzen in zwei Regionen. Bisher hing jede Ortszeit an der
Zeitzone des Rechners (DateTime.Now, DateTimeKind.Local): derselbe Code
haette auf einem Windows-Desktop mit Europe/Berlin und in einem
Linux-Container mit UTC lautlos unterschiedliche Werte geliefert - ohne
Fehler, nur um Stunden verschoben, mitten in Buchungszeitstempeln.

AppTimeZone (Core/Time): Betriebszeitzone der Instanz, einmalig aus
Trading.ApplicationTimeZoneId gesetzt, IANA- und Windows-Schreibweise tragen
beide, unbekannter Wert weicht auf die Systemzone aus und warnt. Wird laut
Festlegung vor den ersten Trades gesetzt und danach nie gewechselt - ein
Wechsel verschoebe rueckwirkend alle Tagesgrenzen. Persistenz bleibt UTC,
damit die Daten beider Instanzen vergleichbar sind.

IbkrMapping.ParseExecutionTime verwirft die von TWS gemeldete Zeitzone nicht
mehr, sondern rechnet gegen sie nach UTC; ohne Zonenangabe gilt die
Betriebszeitzone. Das ist der Kern: eine NYSE-Ausfuehrung darf nicht mit
demselben nackten Zeitwert in die Buecher wie eine an der Eurex.
Rueckgabe ist jetzt immer Kind=Utc.

DailyReportService.NextRun -> NextRunUtc(nowUtc, hour, zone): der Bericht
laeuft zu einer festen ORTSZEIT. Sommerzeitumstellung wird behandelt - bei
der uebersprungenen Stunde weicht er aus, statt den Tag ausfallen zu lassen.

LoggingService fuehrt Anzeigezeit und UTC getrennt: Dateinamen und Anzeige in
Ortszeit (Tagesgrenzen gehoeren zur Instanz, der Supervisor liest die
JSONL-Dateien ueber diese Namen), das ts-Feld im JSONL in UTC. Beides musste
getrennt werden, weil die umgerechnete Ortszeit Kind=Unspecified traegt und
ein ToUniversalTime() darauf sie als Zeit des HOSTS gedeutet haette.

Verbleibende DateTime.Now in Worker-Zeitplaenen und Statuszeilen ebenfalls
auf AppTimeZone.Now umgestellt.

Verifiziert: 183 Tests gruen (+20), darunter EU/US-Versatz, Winter-/Sommerzeit,
unbekannte Zone und die uebersprungene Stunde bei der Zeitumstellung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:52:23 +02:00
RichardandClaude Opus 5 123f38ab6f L1a: Core und Module von WinForms entkoppeln - net10.0 statt net10.0-windows
Core, alle drei Module und das Testprojekt tragen keinen UI-Code mehr und
bauen fuer linux-x64. Nur noch IBKRTrader.App ist Windows-gebunden.

UI-Contract toolkit-neutral (Vorbild: PolytraderSharp):
- ModuleView.CreateForm (Func<Form>) -> CreateView (Func<object>)
- ModuleView.Icon (System.Drawing.Image) -> IconKey (string).
  System.Drawing.Common ist seit .NET 7 Windows-only und wirft auf Linux.
- WindowMenu.cs war reine WinForms-Umsetzung -> in die Shell verschoben.

LoggingService haelt keine RichTextBox mehr, sondern meldet Eintraege ueber
event EntryWritten. Einfaerbung und UI-Thread-Wechsel liegen jetzt im
LogPanelController der Shell. Nebenbei: ToUpper() -> ToUpperInvariant()
(tr-TR haette aus "info" ein "İNFO" gemacht) und \r\n -> Environment.NewLine.

Die drei Modul-Fenster liegen jetzt unter UI/Views/Modules/; RegisterUi der
Module ist bewusst leer, die Shell registriert sie zentral ueber
UI/ModuleViews.cs (nur fuer tatsaechlich geladene Module). ViewIcons loest
IconKey gegen die PNG-Ressourcen auf - dieselben Schluessel bekommt spaeter
die Avalonia-Shell.

UiConstructionTests entfernt: die Konstruktionspruefung deckt --smoke-ui ab,
das Testprojekt braucht dafuer keine UI-Referenz mehr. Der Test
RegisterUi_RegistersMainView haelt jetzt das Gegenteil fest - das Modul darf
nichts registrieren, sonst waere es wieder toolkit-gebunden.

Verifiziert: Build 0 Fehler/0 Warnungen, 163 Tests gruen, --smoke-ui
konstruiert alle 7 Fenster, und Core + 3 Module + Tests bauen fuer linux-x64.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:38:01 +02:00
RichardandClaude Opus 5 18b1059fa9 L0: NuGet.config reparieren - Restore gegen leeren Paketordner
Drei Pakete hatten kein passendes packageSourceMapping-Muster; mit
<clear/> und Allowlist bedeutet das NU1100. Auf dem Entwicklungsrechner
unsichtbar, weil alle drei laengst im globalen Cache liegen - ein frischer
Klon (und damit jeder Linux-Host) konnte nicht wiederherstellen.

- PDFsharp*                     : gar kein Muster vorhanden
- Microsoft.EntityFrameworkCore : der Glob "…EntityFrameworkCore.*" matcht
                                  das Basispaket ohne Suffix nicht
- Microsoft.CodeAnalysis.*      : transitiv ueber EntityFrameworkCore.Design

Verifiziert: dotnet restore der Projektmappe gegen einen leeren
--packages-Ordner stellt jetzt alle sechs Projekte wieder her.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:30:32 +02:00
RichardandClaude Opus 5 27577ef1b2 @ Doku: Analyse Linux-Portierung (Avalonia + net10, Aufwand, Fundstellen)
Bestandsaufnahme gegen b96a207, kein Code geaendert. Kernbefunde:

- Der nicht-UI-Teil ist portabel: kein DllImport, keine Registry, kein WMI,
  kein DPAPI, keine Windows-Zeitzonen-IDs. WinForms-Kopplung im Core sind
  genau 3 Dateien, je Modul genau eine Form-Datei.
- Daraus die Empfehlung: erst headless (~6,5 PT), dann Avalonia (~12 PT).
  LiveCharts2 ist Feature-Neubau, kein Migrationsposten (kein Diagramm im
  Bestand).
- Kritisch: ParseExecutionTime verwirft die Zeitzone (Kind=Unspecified) und
  DailyReportService nutzt DateTimeKind.Local - auf einem UTC-Host liefert
  derselbe Code lautlos andere Werte.
- NuGet.config ist bereits heute kaputt: PDFsharp-MigraDoc,
  Microsoft.EntityFrameworkCore (Glob matcht nicht ohne Suffix) und
  Microsoft.CodeAnalysis.CSharp.Workspaces fehlen im packageSourceMapping.
  Gegen leeren Paket-Ordner verifiziert (NU1100).
- Weiter: mysqldump.exe + PATH-Split(';') im BackupWorker, "Segoe UI" und
  kulturabhaengige Betragsformatierung im PdfExporter, Schreibzugriff neben
  der Binaerdatei (FHS), Fundstellenverzeichnis mit Datei+Zeile im Anhang.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:26:49 +02:00
RichardandClaude Opus 5 b96a20788c R10: Lesender Bestandsabgleich (IBrokerPortfolioReader) + Datenlage-Konzepte
Eigener Seam neben IBrokerClient: Wer handelt, braucht ihn nicht; wer die
eigene Buchfuehrung gegen den Broker abstimmt, braucht nur ihn. Zuteilung
und Verfall aendern Positionen ohne Order von uns - ohne Abgleich laeuft
das Managementbuch zwangslaeufig auseinander.

- IBrokerPortfolioReader mit GetPositionsAsync/GetExecutionsAsync;
  implementiert von IbkrBrokerClient und NullBrokerClient (DI registriert
  beide Rollen auf derselben Instanz).
- IbkrConnection: reqAccountUpdates statt reqPositions (nur dieser Weg
  liefert Marktwert und unrealisierten G/V), reqExecutions inkl. Zuordnung
  der verspaetet eintreffenden commissionReport-Callbacks ueber die ExecId.
- BrokerPosition/BrokerExecution als Broker-Wahrheit neben Position;
  IbkrMapping: ParseSide, ParseExecutionTime, FormatExecutionFilterTime
  (UTC wegen TWS-Warnung 2174) - mit Unit-Tests.
- Verifiziert gegen Paper-Konto DUR371528: 2 Positionen, 2 Ausfuehrungen
  inkl. Kommissionen.

Doku: Kapital- und Buchmodell (drei Wahrheiten, Kapitalzuteilung),
KONZEPT-Datenlage-und-Strategien (gemessen, was die API auf diesem Konto
liefert). Options-Wheel: Greeks bei verzoegerten Daten funktionieren
(Feld 83); Earnings-Termine sind ueber die TWS API nicht erreichbar
(Fehler 10358) - Behelf ueber IV-Filter statt Fremddatenquelle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:51:51 +02:00
RichardandClaude Opus 5 80afcd49c1 R9: Echter IbkrBrokerClient über die TWS API
Broker-Adapter gegen TWS/IB Gateway, aktivierbar über IBKRSettings.UseTwsApi;
NullBrokerClient bleibt Default. TradingEnabled bleibt als zweite, unabhängige
Sicherung bestehen – ohne ihn platziert der ExecutionService keine Order.

Aufteilung (src/IBKRTrader.Core/Trading/Ibkr/):
- IbkrMapping      – reine Abbildung Core <-> TWS (Kontrakt, Order, Kurs, Port-
                     und Statusregeln), vollständig unit-getestet
- IbkrConnection   – Socket-Lebenszyklus, Reader-Thread, reqId-Korrelation über
                     TaskCompletionSource
- IbkrBrokerClient – implementiert IBrokerClient, übersetzt Fehler in leere
                     Ergebnisse (Konto 0 lässt die Risikoprüfung alles ablehnen)

Bewusste Entscheidungen:
- Träges Verbinden mit Wiederholung statt Verbindungsaufbau beim Start: TWS ist
  nach einem Neustart minutenlang nicht bereit.
- Port wird gegen den Handelsmodus geprüft; Paper-Modus auf Live-Port (oder
  umgekehrt) lässt den Broker inaktiv, statt auf dem falschen Konto zu handeln.
- MarketDataType Default 4: Paper-Konten ohne Datenabo bekommen sonst keine Kurse.
- Fehlercode 10167 ist ein Statushinweis (verzögerte Daten folgen), kein Fehler.
  Als Fehler behandelt scheiterte jede einzelne Kursabfrage.

Verifiziert gegen Paper-Konto DUR371528: Verbindung, Konto (100.105,50 EUR),
Kurse (AAPL/MSFT/NVDA, verzögert), Fehlerpfade. Orderpfad bis zur Broker-Annahme
per What-If-Order geprüft (Aktie + Option, ohne Ausführung); dabei zugleich die
Optionsberechtigung des Kontos bestätigt. Offen: echte Ausführung (Fill ->
Buchung) und asynchrone Fill-Verfolgung – beides in IBKR-Integration.md notiert.

Doku: TWS-Setup-Checkliste.md (Einstellungen für Neuinstallation) neu,
IBKR-Integration.md / ARCHITECTURE.md / README.md nachgezogen.

154/154 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 17:40:00 +02:00
RichardandClaude Opus 4.8 2a312ca035 R8: Accounting- + Supervisor-Modul + Core-Datenfundament (S-0)
Portierung der beiden fehlenden Grundbausteine aus PolytraderSharp (voller Ausbau).

Core S-0 (Datenfundament fuer Analyse/Forensik):
- core_decision_journal + core_order_events (+ ReasonCode/Decision/OrderEvent-Enums),
  IDecisionJournal/IOrderEventLog mit fehlertoleranten EF-Impls (Handel bricht nie).
- SignalId-Durchreichung TradeSignal -> ExecutionService -> core_trade_history;
  ExecutionService schreibt an jeder Verzweigung Journal/Order-Events.
- JSONL-Log-Sink (LogJson + Dual-Sink), pure Analytik: RealizedPnlEngine (FIFO),
  TradeAnalytics, DossierBuilder. Migration AddAnalysisFoundation.

Accounting-Modul (acc_): unabhaengiger IBKR-Kontoauszug (Activity Flex Query) hinter
Interfaces mit Offline-Null-Stubs -> append-only Ledger + Periodenabrechnung/BWA + FX
(USD/EUR) + CSV/PDF (PDFsharp/MigraDoc). Steuerschicht bewusst offen (Platzhalter-Tab).
Kein Handel. Migration InitialAccounting.

Supervisor-Modul (sup_): read-only OpenRouter-Agent (Function-Calling-Loop) + read-only
Tool-Registry (8 Tools) + Profile + Dossier-Browser + Counterfactual-Job (Stub) +
Tagesbericht/MCP-Light (opt-in). Migration InitialSupervisor.

Verdrahtung: Program.cs (beide Module + Icons), slnx/App/Tests-Referenzen,
provision-db.ps1, AppSettings-Sektionen, docs/konzepte, README.

Tests: 79 -> 117 gruen (FIFO/KPIs/Dossier/JSONL, Classifier/Engine/FX/Idempotenz,
OpenRouter/Registry/Agent/MCP, STA-Konstruktion beider neuen Fenster).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-31 09:25:18 +02:00
Richard cbbedb2e0e @
Doku: Projekt-README (Architektur, Build/Test, Konfiguration, DB-Setup, Status)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-30 10:32:07 +02:00
Richard 72e07d0c6b @
Doku: IBKR-Integration festgelegt (TWS API / IB Gateway)

- docs/IBKR-Integration.md: Entscheidung (TWS API via IB Gateway) + Setup (Ports 4002/4001,
  IBC/2FA), Regionen (US<->IE gleiche Codebasis), Lib (IB.TWS.CSharpApi), Design des
  IbkrBrokerClient (async-Wrapper ueber EWrapper/EClient), To-dos bei Gateway-Zugang
- ARCHITECTURE.md: Broker-Anbindung als naechsten Meilenstein verankert (blockiert bis Paper-Zugang)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-30 10:09:13 +02:00
Richard c5ff4e17aa @
DB-Provisioning-Skripte (Drop-Alt-Tabellen + EF-Migrationen anwenden)

- scripts/drop-app-tables.sql: entfernt alte (snake_case) core_/ct_-Tabellen + EF-Historie,
  damit die EF-Migrationen kollisionsfrei angewendet werden koennen
- scripts/provision-db.ps1: liest Connection aus appsettings.Local.json, setzt IBKRTRADER_MYSQL,
  wendet CoreDbContext- + CongressTradingDbContext-Migrationen an (dotnet ef database update)
- scripts/README.md: Ablauf + Sicherheitshinweise (Passwort rotieren, Master-Key)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-29 09:47:06 +02:00
Richard e6bffdb70d @
R7: Dashboard-View + DashboardService (Abschluss Feinschliff)

- Core/Trading/DashboardService: aggregiert Positionen/Exposure/Trades via EF (DashboardSnapshot)
- UI/Views/DashboardView: Trading-Modus, aggregierte Kennzahlen, geladene Module (+ Aktivierungs-Status)
- core.dashboard-View registriert (Order 5) mit dashboard-Icon
- Tests: DashboardService (leer + Aggregation, InMemory) -> 58/58 gruen; smoke-ui deckt alle 5 Views ab

Kurskorrektur R1-R7 abgeschlossen: IBKRTrader folgt dem PolytraderSharp-Konzept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 20:01:55 +02:00
Richard 9effc43206 @
R6: Security - Master-Key + AES-256-GCM at-rest + TLS-Warnung

- Core/Security/SecretProtection: AES-256-GCM at-rest, Master-Key aus env IBKRTRADER_MASTER_KEY
  bzw. gitignorierte master.key; selbstheilendes enc:v1:-Format; Passthrough ohne Key (mit Warnung)
- Core/Security/EncryptedStringConverter (EF-ValueConverter, bereit fuer kuenftige Credentials)
- Program: ConfigureSecretProtection (Master-Key laden) + WarnIfDbTlsNotEnforced (SslMode) beim Start
- master.key gitignored
- Tests: SecretProtection (Round-Trip/Idempotenz/Passthrough/Tamper/Key-Fehler) -> 56/56 gruen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 19:53:21 +02:00
Richard 331623d4f3 @
R5: CongressTrading als Strategie (Signal -> ExecutionService) + Positionen im Modul-Fenster

- CongressTradingStrategy: neuer Scrape-Trade -> TradeSignal (buy/sell-Mapping, sonst ignoriert)
  -> Core-IExecutionService; CongressScrapeWorker ruft sie je neuem Trade (try/catch-isoliert)
- Modul-Fenster: offene Positionen des Moduls via IPortfolioService.GetPositionsAsync("CT")
- Tests: CongressTradingStrategy (Mapping/Ausfuehrung, gemockter ExecutionService) -> 51/51 gruen
- Handel bleibt sicher aus (TradingEnabled=false + NullBrokerClient), bis Broker+Freigabe
- Build + smoke-ui + App-Start ok

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 19:14:21 +02:00
Richard 19dac18050 @
R4: Worker von WorkerEngine auf IHostedService (Generic Host)

- WorkerBase implementiert IHostedService (StartAsync/StopAsync mit CancellationToken,
  eigener CTS, Guard auf Info.Active); IWorker auf Metadaten + TriggerAsync reduziert
- Worker via AddHostedService registriert (Core + Modul); AppHost.Start() startet sie,
  AppHost.StopAsync() stoppt sie
- WorkerEngine auf leichte Registry reduziert (WorkerInfos fuer UI + TriggerWorkerAsync)
- LauncherForm startet/stoppt keine Worker mehr (Host-getrieben)
- Hosting.Abstractions im Core; Tests angepasst -> 43/43 gruen; smoke-ui + App-Start ok

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 18:39:14 +02:00
Richard 475c0b41cb @
R3 Slice 4: IBKR-Marktdaten auf EF; Dapper vollstaendig entfernt

- 3 IBKR-Entities (IBKRInstrument/IBKRMarketBar/IBKRExternalIdentifier) im CoreDbContext
  (core_ibkr_instruments/_market_data/_external_identifiers); Migration AddIbkr
- IBKRMarketDataRepository von Dapper auf EF (IDbContextFactory<CoreDbContext>);
  Cross-Modul-Query (ct_trade) via Database.SqlQueryRaw
- DatabaseService, IBKRMigrations, Dapper-Package entfernt; Laufzeit-Migrationen komplett weg
  (Schema extern via dotnet ef database update)
- Tests: +4 IBKRMarketDataRepository (EF-InMemory) -> 43/43 gruen; Build + smoke-ui + App-Start ok

R3 abgeschlossen: Persistenz vollstaendig auf EF Core.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 18:29:00 +02:00
Richard 6c8e36dc3c @
R3 Slice 3: CongressTrading-Modul + Worker-Log + core_settings auf EF Core

- Modul: CongressTradingDbContext (ct_congressMember/ct_trade) + Design-Time-Factory;
  CongressRepository von Dapper auf EF; CongressTrade.DetailsFetched ergaenzt; Dapper entfernt
- Core: CoreSettingsService (core_settings via EF); WorkerBase-Log auf EF (core_worker_log);
  7 Worker-Ctors DatabaseService -> IDbContextFactory<CoreDbContext>
- CoreMigrations + CongressMigrations (Dapper) entfernt; core_-Schema nun rein EF
- EF-Migration InitialCongressTrading; AddCorePersistence-Fallback fuer leeren Connection-String
  (App startet ohne DB); Connection aus appsettings.Local.json (gitignored)
- Tests: +4 CongressRepository (EF-InMemory) -> 39/39 gruen; Build + smoke-ui + App-Start ok

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 11:34:42 +02:00
Richard 7e3791b82d @
R3 Slice 2: Trading-Buchführung auf EF Core (+ InMemory-Tests)

- BudgetService, TradeHistoryService, PortfolioService von Dapper/DatabaseService auf
  IDbContextFactory<CoreDbContext> (EF Core) umgestellt
- Positionen/Budget/Trade-Historie ueber CoreDbContext (core_position/core_budget/core_trade_history)
- Tests: EF-InMemory-Provider im Testprojekt; 5 PortfolioService-Tests (Buy/Sell/Avg/Exposure/Isolation)
- 35/35 Tests + Build + smoke-ui gruen; WorkerBase-Log/Modul/Dapper-Entfernung folgen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 10:45:54 +02:00
Richard 261032f9f9 @
R3 Slice 1: EF-Core-Infrastruktur im Core + InitialCore-Migration

- Pomelo.EntityFrameworkCore.MySql 8.0.3 + EF Core Design 8.0.11 (Core), NuGet-Allowlist erweitert
- Configuration/DatabaseOptions + DatabaseServerVersion (MariaDB 11.8.6 gepinnt)
- Persistence/Entities: CorePosition, CoreTrade, CoreBudget, CoreWorkerLog, CoreSetting
- Persistence/Ef/CoreDbContext (core_-Tabellen) + Design-Time-Factory (env IBKRTRADER_MYSQL)
- DependencyInjection/AddCorePersistence (AddDbContextFactory), in Program verdrahtet
  (Connection aus appsettings.Local.json)
- EF-Migration InitialCore erzeugt (5 core_-Tabellen)
- Consumer noch auf Dapper (folgt in Slice 2); Build + 30/30 Tests + smoke-ui gruen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 10:40:09 +02:00
Richard 48c662a699 @
R3-Vorbereitung: --db-version-Diagnose + EF-Strategie festgelegt

- Program: --db-version gibt die DB-Serverversion aus (fuer EF-ServerVersion-Pin)
- Bestaetigt: MariaDB 11.8.6 -> Pin wie PolytraderSharp (MariaDbServerVersion 11.8.6)
- docs/ARCHITECTURE.md: R3-Strategie fixiert (EF-Migrationen extern, Verbindung aus appsettings.Local.json)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 10:32:05 +02:00
Richard 218247b5f6 @
Launcher: ToolStrip-Fensterleiste + Icons (aus PolytraderSharp)

- Fenster-Buttons in einem ToolStrip (Icon ueber Text, 32x32) statt Einzel-Buttons
- 24 Icon-PNGs aus PolytraderSharp uebernommen (Resources/) + Properties/Resources.resx
  (ResXFileRef) + Resources.Designer.cs
- Program.AssignViewIcons: Icons je View-ID zugewiesen (Workers=system_time, Logs=error_log,
  Settings=setting_tools, CongressTrading=cross_reference); Icons auch im Fenster-Menue
- Button-Checked spiegelt Offen-Status
- Build + 30/30 Tests + smoke-ui gruen; Screenshot geprueft

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 10:25:14 +02:00
Richard 8f44c0fd82 @
R2: Generic Host + Modul-Vertrag + Shell-UI (PolytraderSharp-Konzept)

- Core/Modularity: neuer IModule (Name, DbPrefix, RegisterServices(services,config),
  RegisterUi(host,sp), StartAsync/StopAsync, GetActivationBlocker) + ModuleView
  + IModuleUiHost + WindowMenu. Alte IModule/ModuleRegistry/WindowManager/ModuleFormBase entfernt.
- Program.cs: Host.CreateDefaultBuilder + IConfiguration (appsettings.json/.Local.json);
  Core-Services registriert, Module via RegisterServices, Views via RegisterUi.
- UI: ShellUiHost (Einzelinstanz-Fenster + Fenster-Menue), LauncherForm als Shell
  (Buttons je View), Core-Views Logs/Settings/Workers als eigene Fenster.
- CongressTrading auf neuen Vertrag; Worker als IWorker registriert.
- --smoke-ui Headless-Test (konstruiert jede View + Launcher).
- appsettings.Local.json gitignored.
- Tests angepasst -> 30/30 gruen; Build + Smoke-UI + App-Start verifiziert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 00:24:00 +02:00
Richard c20538c8d8 @
R1: Umbau auf Multi-Projekt-Struktur (Vorbild PolytraderSharp)

Kurskorrektur: Vorbild ist PolytraderSharp (C#), nicht die veraltete Python-Version.
Reiner Strukturumbau, Verhalten unveraendert.

- src/IBKRTrader.Core (classlib): Core-Code + UI-Contract (ModuleFormBase, WindowManager)
- src/IBKRTrader.Modules.CongressTrading (classlib, referenziert nur Core)
- Root: IBKRTrader.App (WinExe) referenziert Core + Modul
- tests/IBKRTrader.Tests: Referenzen auf Core + Modul
- Neue .slnx; ungenutztes HtmlAgilityPack entfernt
- docs/ARCHITECTURE.md: korrigierter Ziel-Stand + R-Phasenplan
- Build + 38/38 Tests gruen; App startet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 20:26:25 +02:00
Richard 2ad4b55db1 @
Phase 3: Trading-Kern (Risk, Execution, Portfolio) mit sicherem Broker-Default

- Core/Trading/TradingModels: Signal, Order(Request/Result), RiskContext/Decision,
  Account, Position, Quote, ExecutionResult, Enums (Side/OrderType/Mode)
- IBrokerClient + NullBrokerClient (sicherer Default, handelt NIE bis IBKR-Adapter verifiziert)
- RiskService (+IRiskService): Sizing nach MaxTrade%, Modul-Limit, Slippage; Buy/Sell
- PortfolioService (+IPortfolioService): core_position + core_trade_history + core_budget
- ExecutionService (+IExecutionService): Signal -> Kurs -> Konto -> Risiko -> Order -> Buchung
- TradingSettings in AppSettings (Paper/Live, TradingEnabled, Risikoparameter)
- CoreMigrations: core_position; DI-Registrierung der Trading-Services
- Tests: RiskService (11) + ExecutionService (6, NSubstitute) -> 38/38 gruen

Offen (bewusst gekapselt): echter IbkrBrokerClient gegen Client-Portal-Gateway (manuell verifizieren).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 11:33:59 +02:00
Richard d0bc833235 @
Phase 2: Launcher-UI + eigenstaendige Modul-Fenster

- Form1 -> LauncherForm (Dateien via git mv, Designer/resx angepasst)
- Modul-Tab: Karten aus ModuleRegistry mit "Fenster oeffnen"-Button je Modul
- UI/WindowManager: Fenster-Tracking (Key->Form), Re-Open fokussiert, CloseAll
- UI/ModuleFormBase: Basisklasse fuer eigenstaendige Modul-Fenster
- CongressTradingForm: DB-Kennzahlen + manueller Scrape-Trigger (Phase-4-Ausbau folgt)
- WindowManager in DI; Launcher schliesst Modul-Fenster beim Beenden
- Tests: WindowManager (6) -> 21/21 gruen; Launcher-Start verifiziert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 10:39:50 +02:00
Richard 5815d3258f @
.gitattributes: Zeilenenden-Normalisierung (stoppt LF/CRLF-Warnungen)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 10:09:46 +02:00
Richard af398353f0 @
Phase 1: Modul-System formalisiert (IModule + ModuleRegistry)

- Core/Modules/IModule.cs: Vertrag (Key, DisplayName, Description, Version,
  RegisterServices, InitializeAsync, GetWorkers, CreateWindow)
- Core/Modules/ModuleRegistry.cs
- CongressTradingModule auf IModule umgestellt (instanzbasiert, Platzhalter-Fenster)
- Program.cs iteriert ueber IModule[] + Registry; Form1 initialisiert Module ueber Registry
- Testbarkeit: WorkerBase DB-Log-Seam (virtuell); CapitolTradesScraper.ParseTradesFromHtml
  extrahiert (offline gegen ct_raw.html testbar)
- Tests: ModuleRegistry, CongressTradingModule, WorkerBase, CapitolTradesScraper -> 15/15 gruen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 10:07:47 +02:00
Richard 9abad277c2 @
Phase 0: Test-Fundament & Architektur-Doku

- IBKRTrader.Tests (xUnit + NSubstitute + FluentAssertions), nur Unit-Tests
- Repo-lokale NuGet.config: Test-Pakete in Allowlist ergaenzt
- Hauptprojekt: Test-Unterordner aus SDK-Globbing ausgeschlossen
- docs/ARCHITECTURE.md: Plan + Phasen-Checkliste
- grundregeln.md: .NET 10, Launcher-Modell; DB-Passwort entfernt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 09:58:49 +02:00
RichardandClaude Opus 4.8 ebeb035e92 Initial commit: IBKRTrader
.NET WinForms-Anwendung (Core, Modules/CongressTrading, UI).
Enthaelt .gitignore und settings.example.json als Konfigurationsvorlage.
Echte settings.json mit Zugangsdaten ist bewusst ausgeschlossen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 18:19:47 +02:00