cec8b91ebd32250feba494a58dbb5c5ddd0ed785
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
72ad38518b |
EZB-Tageskurse selbst abrufen, Kopfleiste umbrechen lassen
Behebt #532 und #533. #532 — Kopfleiste bricht um statt zu scrollen Mit elf Ansichten brauchte die Leiste 1623 px. Darunter scrollte sie seitlich weg, ohne dass ein Hinweis darauf sichtbar war: Wer einen rechten Tab anklickte, verlor "Dashboard" aus dem Blick und fand den Weg zurueck nicht mehr. Statt overflow-x nun flex-wrap auf Leiste und Kopfzeile. Geprueft von 1920 bis 768 px — nichts wird mehr abgeschnitten, der Koerper scrollt nie waagerecht. #533 — Kurse holen, statt EUR still auf null zu setzen Die Tabelle acc_fx_rates gab es seit A-2, befuellt hat sie nie jemand. Deshalb war EUR nicht verfuegbar, und der PDF-Export machte daraus wortlos einen Beleg mit lauter Nullbetraegen. Neu holt EcbFxRateSource die amtlichen Referenzkurse ueber die EZB-Daten-API (Reihe EXR/D.USD.EUR.SP00.A, CSV). FxRateSyncService stoesst das beim ersten Ingest-Lauf des Tages an: erstmalig 400 Tage rueckwirkend, danach nur noch der Rand. Die Kurse werden gespeichert, nicht bei Bedarf geholt — eine Abrechnung fuer einen vergangenen Monat muss den Kurs von damals nehmen und beim naechsten Aufruf dasselbe Ergebnis liefern. Zwei Fallen, die dabei zu umgehen waren: - Die Reihe liefert USD je EUR (1 EUR = 1,1652 USD), FxRate.UsdToEur meint die Gegenrichtung. Wer das verwechselt, bekommt eine Abrechnung, die um rund 35 % danebenliegt und trotzdem plausibel aussieht. Gespeichert wird der Kehrwert. - Die CSV-Antwort enthaelt in TITLE_COMPL ein Komma innerhalb von Anfuehrungszeichen; naives Splitten verschoebe die Spalten. Die Warnung erscheint, sobald der verwendete Kurs mehr als drei Tage vor dem Stichtag liegt. Drei Tage, weil genau so gross die planmaessige Wochenendluecke ist: Der Freitagskurs gilt bis Montag und ist dabei kein Mangel. Der Beleg bleibt trotzdem erzeugbar — die Warnung steht sichtbar darauf und im WebUI ueber der Abrechnung. Nur ohne jeden Kurs lehnt der Export jetzt mit 400 ab, statt Nullbetraege auszugeben. PDF und CSV laufen deshalb nicht mehr ueber window.open: Eine nackte JSON-Fehlermeldung in einem neuen Reiter ist keine Antwort. downloadExport() holt die Datei, meldet Fehler im Klartext und stoesst sonst den Download an. Nebenbei im Testlauf gefunden und behoben: Der manuelle Anstoss aus dem WebUI und die stuendliche Schleife trafen sich in derselben Sekunde — im Log standen "280 Kurse uebernommen" und "53 Kurse uebernommen" untereinander, beide hatten die EZB gefragt. SyncDailyAsync serialisiert jetzt und prueft den Tag ein zweites Mal innerhalb der Sperre. Geprueft auf der Linux-Test-VM gegen die echte EZB-API: 280 Kurse vom 06.08.2025 bis 09.09.2026 uebernommen, Umrechnung stimmt (1/1,1652 = 0,858222), eine Maerz-Abrechnung nimmt den Kurs vom 31.03. und nicht den heutigen, das Warnbanner erscheint ab dem vierten Tag, der Export verweigert ohne Kurs und liefert sonst ein gueltiges PDF. 551 von 551 Tests bestanden (18 neue). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6218a04fe4 |
Eine Roadmap statt fuenfzehn Plandokumente; Altbestand ins Archiv
Der Status des Projekts stand verstreut in elf Umsetzungsplaenen, drei Konzepten, der Linux-Analyse und dem Projektstand - teils widersprechend, teils wochenlang veraltet. Ab jetzt gibt es genau eine Statusquelle. docs/ROADMAP.md (neu): - Alle Vorhaben in vier Stufen A bis D, plus technische Schuld und Verlauf. Die Stufen sind eine Reihenfolge, keine Termine: jede schafft die Voraussetzung fuer die naechste. - Statuszeichen: erledigt / offen / blockiert (mit Ursache) / bewusst zurueckgestellt / Idee, nicht beschlossen. Damit ist das, was wir NICHT bauen wollen, sichtbar vorgehalten statt unauffindbar in einem Plan zu schlummern. - Inhaltlich getragen, nicht nur verlinkt: je Vorhaben Ziel, Phasen, Akzeptanzkriterien, offene Entscheidungen und Leitplanken aus den Quelldokumenten. - Sichtbar gemacht, was vorher zwischen den Dokumenten verborgen lag: CopyTrading Phase 1 ist der Engpass der gesamten Roadmap (MarketMaking und BundleArbitrage haben harte Voraussetzungen darauf), und die Sniper-Metriken aus Phase 3.2 sind ein Spezialfall des StrategieDrift-Fingerprints - zusammen bauen statt doppelt. Archiv (docs/archiv/): - 15 Dokumente verschoben (11 Umsetzungsplaene, 3 Konzepte, ANALYSE-Linux-Portierung). Sie bleiben die Bauanleitungen mit Code-Bezuegen, Risikotabellen und Begruendungen - eingefroren ist nur ihr Status. - archiv/README.md ordnet jedes Dokument seinem Roadmap-Punkt zu. Verweise nachgezogen - der eigentliche Aufwand: - 25 Markdown-Links repariert. 15 davon verschiebungsbedingt (eine Ebene tiefer), der Rest war schon vorher falsch: die Ideensammlung verlinkte Quellcode relativ zum Repo-Wurzelverzeichnis statt zu docs/. - 12 Dateien ausserhalb von docs/ verwiesen in Kommentaren auf die Plaene (csproj, props, setup.json, sechs Quelldateien) - alle auf archiv/ umgebogen. - Verweise auf Dateien, die der Fruehjahrsputz geloescht hat (Ui/, Program.cs, WindowMenuBar), zu Klartext entschaerft statt tote Links zu lassen. - Gegenprobe: 85 Links geprueft, 0 kaputt. Build gruen, 476 Tests gruen. PROJEKTSTAND.md entdoppelt: Abschnitt "Offen" verweist jetzt auf die Roadmap. Arbeitsteilung ist damit klar - Projektstand sagt was IST, Roadmap was KOMMT. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
53546ceeeb |
P1c+P4: Module und Tests auf net8.0 - WinForms nur noch in PolyTrader.App
Variante B (Entscheidung Richard): Modul-UI entfernt statt in Zwischenprojekte ausgelagert. Avalonia ist plattformuebergreifend, die neuen Ansichten kommen spaeter direkt in die Modul-Projekte zurueck - kein Zwischenschritt, keine Wegwerfarbeit. - 23 WinForms-Dateien aus den 4 Modulen entfernt (Spezifikation steht in docs/UI-SPEZIFIKATION-WinForms.md, Originalcode im Tag winforms-final). - RegisterUi ist jetzt je Modul ein dokumentierter No-Op: View-ID, Titel, Gruppe, Order und der Tab-Aufbau stehen als XML-Doku drin, damit der Avalonia-Nachbau die stabilen IDs und die Struktur uebernimmt. - Alle 4 Modulprojekte + Testprojekt: net8.0 statt net8.0-windows, UseWindowsForms raus. - P4 vorgezogen (war durch den Testprojekt-Wechsel faellig): PDFsharp-MigraDoc-GDI -> PDFsharp-MigraDoc (Core-Build). Der Core-Build findet keine Systemschriften, daher neu Logic/PdfFontResolver.cs: durchsucht die Schriftverzeichnisse des OS nach Segoe UI/DejaVu/Liberation/Noto/Arial/FreeSans. Keine Schriftdateien im Repo noetig; fehlt auf Linux alles, kommt eine klare Meldung mit apt-Hinweis statt eines kryptischen Renderer-Fehlers. Verifiziert: Core, alle 4 Module und das Testprojekt publishen fuer linux-x64, und zwar ohne ein einziges Windows-spezifisches Paket in den deps.json. 442 Tests gruen (inkl. PDF-Rendering) auf net8.0. Windows-App laeuft weiter mit den Core-Fenstern. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ad1593bfc1 |
P1a: PolyTrader.Core auf net8.0 - UI-Contract toolkit-neutral
Der Core traegt keine WinForms-/System.Drawing-Abhaengigkeit mehr und baut als plattformneutrales net8.0 (verifiziert: publish -r linux-x64 erfolgreich). - ModuleView.CreateForm (Func<Form>) -> CreateView (Func<object>): die Shell kennt ihr Toolkit und castet, der Core nicht. Avalonia kann denselben Contract nutzen. - ModuleView.Icon (System.Drawing.Image, seit .NET 7 Windows-only) -> IconKey (string). Aufloesung Schluessel->Bildressource neu in Ui/ViewIcons.cs, ersetzt Program.AssignMenuIcons. - WindowMenu.cs (reine WinForms-Logik) aus dem Core nach Ui/ verschoben. - WindowMenuTests entfernt: testet die eingefrorene WinForms-Menuelogik, die das Testprojekt nach dem Core-Schnitt nicht mehr erreicht. Im Tag winforms-final erhalten; das Avalonia-Gegenstueck bekommt eigene Tests (P6/P9). Module und App bleiben vorerst net8.0-windows - ihre UI zieht erst mit der Avalonia-Portierung um. Windows-App unveraendert lauffaehig (--smoke-ui gruen). 442 Tests gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
42a599a3a3 |
Accounting A-2: neutrale Periodenabrechnung + BWA-Uebersicht + FX + CSV-Export
Alles laenderneutral, ohne steuerliche Einordnung (A-3 US-Steuerschicht bleibt bewusst offen, haengt an den CPA-Fragebogen-Antworten). Konzept: docs/konzepte/KONZEPT-Modul-Accounting.md, A-2. Pure Logik (unit-getestet): - AccountingEngine.BuildStatement: aggregiert Ledger-Saetze eines Zeitraums (x Account/alle) zu Anfangs-/Endsaldo, Ein-/Auszahlungen, Handelsvolumen, Redeems, Rewards, Fees und Netto-Handelsergebnis (Cash-Basis, EXKL. Ein-/Auszahlungen); Invariante Endsaldo-Anfang = Ergebnis + Einz. - Ausz. BuildMonthlyBreakdown: Monatsvergleich mit verketteten Anfangssalden. - FxConverter: USDC->USD (dokumentierte 1:1-Annahme) + USD->EUR ueber amtliche Tageskurse (acc_fx_rates, Nearest-on-or-before fuer Wochenend-/Feiertage). - CsvExporter: Ledger + Statement als RFC-4180-CSV, kulturinvariant (Punkt-Dezimal, ISO-Datum). Infrastruktur: - acc_fx_rates (FxRate, PK Datum) + EfFxRateRepository (Upsert je Datum). Migration AddFxRates angewendet. - ILedgerRepository.GetUpTo (alle Saetze <= to fuer die Abrechnung inkl. Anfangssaldo). - AccountingReportService: baut Abrechnungen + Waehrungs-View (USDC/USD immer, EUR wenn Kurse geladen). UI (designerfaehig, partial + .Designer.cs): neuer erster Tab 'Uebersicht / BWA' mit KPI-Kacheln (Netto-Handelsergebnis gruen/rot, Endsaldo, Ein-/Auszahlungen, Fees, Rewards, Volumen, #Trades), Monatsvergleich-Grid, Zeitraum-Picker (Standard laufender Monat), Konto- und Waehrungswahl, CSV-Export via SaveFileDialog. Tests: +6 (Periodenaggregation+Invariante, Monatsverkettung, FX-Umrechnung/Nearest-Kurs, CSV-Quoting). Build 0 Fehler, 385 Tests gruen, --smoke-ui alle 6 Views gruen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a3c145c0ed |
Accounting A-1: Ingest-Fundament (unabhaengiger Ledger, idempotent, read-only)
Neues Modul PolyTrader.Modules.Accounting (IPolyTraderModule, acc_-Praefix, nur Core-Referenz, KEIN Handel). Konzept: docs/konzepte/KONZEPT-Modul-Accounting.md, Phase A-1. Buchungsgrundlage ausschliesslich aus unabhaengigen Polymarket-/On-Chain-Abrufen (nie unsere Trading-DB), append-only, prueffaehig: - Modelle: LedgerEntry (+ LedgerEventType), IngestRun (mit Balance-Anker), RawSnapshot, RawActivity/RawTransfer (normalisierte Eingaben, entkoppeln pure Logik von der API-Feldbenennung). - AccountingClassifier (Logic/, pur+getestet): Activity->Buchungssatz (Typ/Vorzeichen: BUY=Cash raus inkl. Fee, SELL=Cash rein minus Fee, Redeem/Reward +, Split/Merge/Conversion geldneutral), stabiler Idempotency-Key; Transfer-Klassifikation trennt intern (System-Contract-Whitelist) von externen Deposits/Withdrawals. SumNet fuer den Balance-Anker-Abgleich. - AccountingDbContext (acc_ledger append-only + Unique-Index Idempotency, acc_ingest_runs, acc_raw; Autoincrement-PKs). Migration InitialAccounting generiert UND angewendet. Repos mit idempotentem Upsert (true=neu/false=Duplikat). - AccountingIngestService (BackgroundService): testbarer IngestAccountAsync - Activity + On-Chain- Transfers klassifizieren + idempotent buchen, Rohschnappschuss ablegen, Lauf inkl. Balance-Anker- Delta protokollieren; Backfill vs. inkrementell (Lookback-Ueberlappung gegen API-Lag). - Quellen hinter Interfaces (IActivitySource/ITransferSource/IBalanceAnchorSource) mit Null-Stubs: Modul laeuft offline und bucht korrekt nichts. Live-Abruf + System-Contract-Whitelist = Zielland. - UI designerfaehig (partial + .Designer.cs): Tabs Ledger (filterbar) + Abruf/Status (Ingest-Laeufe, Balance-Anker, manueller Backfill/Inkrement). - Program.cs (beide Modul-Listen) + sln + App/Tests-Referenzen. A-2 (Abrechnung/BWA/FX), A-3 (US-Steuerschicht FIFO/Form-8949), A-4 (CSV/PDF via PDFsharp/MigraDoc) folgen. Tests: +12 (Klassifikation, intern/extern-Transfer, Ingest-Idempotenz, Balance-Anker, Inkrement-Fenster). Build 0 Fehler, 379 Tests gruen, --smoke-ui alle 6 Views gruen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |