Files
IBKRTrader/.agents/rules/grundregeln.md
T
RichardandClaude Opus 5 7299148dc4 API-First als Regel ausgeschrieben, Anleitung fuer die WebUI-Umsetzung
Die Regel galt seit dem Umbau auf Avalonia, stand aber nirgends: Der Ausgabeweg
ist waehlbar - Desktop, Web oder beides gleichzeitig -, und daraus folgt genau
eine harte Vorgabe: Fachlichkeit lebt in einem Core-Dienst, nie in einer Ansicht.
Ein Fenster und ein Endpunkt sind zwei Zugaenge auf denselben Dienst.

In den Grundregeln steht jetzt die Prueffrage dazu (koennte ein zweiter
Ausgabeweg dasselbe tun, ohne diese Zeile zu kopieren?), die Vorgabe, dass Dienst
und Endpunkt im selben Zug wie das Fenster entstehen, und der Daemon als
Gegenprobe: Was sich kopflos nicht bedienen laesst, haengt zu sehr am Fenster.

docs/ANLEITUNG-WebUI.md richtet sich an den Agenten, der #490 uebernimmt.
Enthaelt den gemessenen Bestand, die Reihenfolge der drei Bloecke, die Tabelle
der 24 Endpunkte mit ihren Diensten, die beiden nicht-mechanischen Stellen
(Logs als Push, Settings mit Zugangsdaten) und die Grenzen - vor allem: keine
Fachlogik anfassen, keine schreibenden Endpunkte ohne Anmeldung.

Ein Punkt darin ist Architektur und keine Geschmacksfrage: Der Core darf die
Module nicht kennen, also koennen Modul-Routen nicht im Core registriert werden.
Sie gehoeren ins Hosting-Projekt, das die Module ohnehin kennt - so wie die
Modulfenster zentral in App/Shell/ModuleViews.cs stehen und nicht im Modul.

473 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 13:23:31 +02:00

5.4 KiB
Raw Blame History

trigger
trigger
always_on

Projektname: IBKRTrader Ziel: Modulares, hochperformantes C# Trading-Framework (.NET 10) für automatische Aktien-Strategien mit Interactive Brokers API. Vorbild-Konzept: Polytrader (Core + unabhängige Module + Launcher, der die Fenster der einzelnen Module öffnet). Strikte Architektur-Regeln (immer einhalten):

Harter Core + beliebig viele unabhängige Module Module dürfen Core oder andere Module niemals beeinflussen DB-Tabellen-Namensschema: {ModulKürzel}_Tabellenname → Core = core_xxx → CongressTrading = ct_xxx Vollständig modulare Worker-Engine: Jeder Worker ist komplett unabhängig, hat eigenen Zeitplan, ist einzeln aktivierbar/deaktivierbar/manuell startbar Keine gegenseitigen Blockierungen – alles thread-sicher und performant

Technik (fest):

C# .NET 10, Avalonia für die Oberfläche – plattformneutral (Windows und Linux). KEIN WinForms und kein System.Drawing: beides bindet an Windows. Alle Projekte sind net10.0 ohne Plattform-Suffix; ein net10.0-windows irgendwo ist ein Fehler. Avalonia bleibt auf der 11er-Linie (11.3.19 / DataGrid 11.3.13), bis LiveCharts2 Avalonia 12 unterstützt – sonst brechen die Diagramme der kommenden Module. MySQL – Zugangsdaten NUR in settings.json (gitignored), NIE im Repo/Code/Doku hinterlegen IBKR TWS/Gateway API (Paper: Port 4002, Live: Port 4001 – Umschaltung über TradingSettings.Mode) Interne REST-API + lokaler Webserver (für späteres Web-UI) Settings: settings.json (Vorlage: settings.example.json) Logging: LoggingService meldet Einträge über das Ereignis EntryWritten (die Oberfläche hängt sich ein und färbt selbst) + Dateien unter Logs/[Modul]/[Level]-dd-MM-yy.txt sowie Logs/[Datum].jsonl Zeit: Zeitstempel IMMER in UTC persistieren. Für Anzeige, Tagesgrenzen und Zeitpläne AppTimeZone verwenden, NIE DateTime.Now oder DateTimeKind.Local – wir betreiben Instanzen in EU und US, die Ortszeit darf nicht am Rechner hängen. Kultur: Jede Zahl-/Datumsformatierung und jedes Parsen braucht einen ausdrücklichen IFormatProvider (i. d. R. InvariantCulture). Ohne ihn hängt das Ergebnis an der Kultur des Hosts. Tests: eigenes Projekt IBKRTrader.Tests (xUnit + NSubstitute + FluentAssertions), NUR Unit-Tests, alles Externe (DB/IBKR/Scraper) gemockt. DoD jeder Phase: dotnet test grün + Build sauber.

API-First (gilt seit dem Umbau auf Avalonia, seit 2026-09-06 ausgeschrieben):

Der Ausgabeweg ist wählbar – Desktop-UI, Web-UI oder beide gleichzeitig. Daraus folgt genau eine harte Regel: Fachlichkeit lebt in einem Core-Dienst, nie in einer Ansicht. Ein Fenster und ein REST-Endpunkt sind zwei Zugänge auf denselben Dienst, und beide dürfen nur formatieren. Prüffrage vor jedem UI-Code: Könnte ein zweiter Ausgabeweg dasselbe tun, ohne diese Zeile zu kopieren? Lautet die Antwort nein, gehört die Zeile in den Core. Jede neue Funktion bekommt ihren Core-Dienst UND ihren Endpunkt, im selben Zug wie ihr Fenster. Nicht nachträglich: Endpunkte, die später in einem Block nachgezogen werden, kosten mehr und weichen ab. Vorbild ist Core/Positions/PositionManager.cs – ein Dienst, drei Zugänge (Shell-Fenster, Daemon-Schalter, GET /api/positions). Der Daemon ist die Gegenprobe: Lässt sich eine Funktion kopflos nicht bedienen, hängt zu viel am Fenster. Der Testbetrieb läuft als systemd-Dienst – dort gibt es keines. Schreibende Endpunkte erst mit Anmeldung. Ohne sie wäre ein Eingriff in die Bücher möglich, den niemand belegen kann; solange keine steht, bleibt die REST-Schnittstelle lesend.

UI-Grundmodell (Launcher-Prinzip nach Polytrader):

LauncherWindow = Basis-Fenster mit einer Schaltfläche je registrierter Ansicht und dem gemeinsamen Fenster-Menü. Die Inhalte (Dashboard, Workers, Logs, Settings, Modul-Fenster) sind eigenständige Fenster, keine Tabs; je Ansicht höchstens eines, erneutes Öffnen fokussiert. Layout deklarativ in .axaml, nicht zur Laufzeit im Code. Kompilierte Bindings sind aktiv, jeder Datenkontext braucht ein x:DataType – dadurch fallen Bindungsfehler beim Kompilieren auf. Module tragen KEINEN UI-Code: sonst müssten sie Avalonia referenzieren und wären nicht mehr kopflos lauffähig. Ihr RegisterUi bleibt leer, die Fenster registriert die Shell zentral in src/IBKRTrader.App/Shell/ModuleViews.cs. Workers-Ansicht, Spalten: Aktiv | Typ | Modul | Worker | Letzter Lauf | Nächster Lauf | Intervall | Info Type = "Worker" oder "Service" (Service = permanent laufend)

Betriebsformen (beide aus derselben Host-Zusammenstellung, src/IBKRTrader.Hosting):

src/IBKRTrader.App – mit Oberfläche; --smoke-ui prüft die Fenster-Konstruktion ohne Anzeigegerät src/IBKRTrader.Daemon – kopflos für Linux/systemd; --check fährt die Startprüfungen ohne Dienste

Core-Worker (müssen zuerst):

Backup (alle 30 min) Webserver (Service) WebAPI (Service)

Erstes Modul: CongressTrading → Scrapt https://www.capitoltrades.com/trades?pageSize=96 → Tabellen: ct_congressMember + ct_trade → Zuerst alle Trades der letzten 3 Jahre, danach Worker alle 30 min neue Trades Entwicklungs-Regeln:

Immer extrem saubere, modulare, wartbare Architektur Build-Ordner muss absolut clean sein (nur notwendige Dateien) Arbeite streng schrittweise: zuerst Core fertig, dann Module Jede neue Funktion zuerst als Worker/Service im Core oder im jeweiligen Modul anlegen

Diese Rule hat immer höchste Priorität. Bei jedem Prompt und jedem Neustart gelten diese Vorgaben.