Commit Graph
142 Commits
Author SHA1 Message Date
RichardandClaude Opus 4.8 c9eb11afe4 RF-Slice 1: ResolutionFarming-Modul-Skelett + geldkritische pure Logik + Tests
Neues Strategiemodul PolyTrader.Modules.ResolutionFarming (IPolyTraderModule,
Name=ResolutionFarming, DbPrefix=rf_), in Solution/App/Tests + beide Modul-Listen
in Program.cs eingebunden. Skelett laedt (RegisterServices/UI noch no-op).

Geldkritische Entscheidungslogik pur und vollstaendig unit-getestet:
- FarmingRiskEngine: Netto-Edge nach Fees (NetEdge/NetEdgePct/HasEdge), Positionsgroesse
  unter Markt-/Cluster-/Gesamt-Exposure-Limits (AllowedPositionUsd), Kill-Switch, Tages-Drossel.
- FarmingScanner: Preisband, Kategorie-Whitelist, Blacklist, Cluster-Key (korrelierte
  Favoriten teilen einen Cluster), Kandidaten-Score.
- FarmingFillModel: Shares fuer Budget (2-Dezimal-Floor), Resolve-PnL (Auszahlung - Kosten -
  Entry-Fee, Maker/Taker), Einstiegskosten inkl. Fee. Nutzt Core.FeeModel.
- RfSettings (rf_settings) mit konservativen Defaults + PropertyGrid-Attributen.

39 neue Tests. Build 0 Fehler, 283 Tests gruen, --smoke-ui ok.
Persistenz (DbContext/Migration/Repos), Scanner-/Monitor-Jobs, Execution und UI folgen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 21:43:34 +02:00
RichardandClaude Opus 4.8 2f5270a2f3 RF-Slice 0: FeeModel nach Core (geteilte Markt-Infrastruktur)
Vorbereitung fuer das ResolutionFarming-Modul: FeeModel von
PolyTrader.Modules.CopyTrading.Logic nach PolyTrader.Core.Trading verschoben, damit
mehrere Strategiemodule dieselbe Fee-Logik nutzen koennen (Module duerfen nicht
voneinander abhaengen -> geteiltes gehoert in den Core). CopyTrading-Referenzen +
FeeModelTests auf den Core-Namespace umgestellt. Rein mechanisch, verhaltensneutral.

Build 0 Fehler, 244 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 21:35:11 +02:00
RichardandClaude Opus 4.8 c091e79869 Docs: Testabdeckung + K3-Korrektur im Plan vermerkt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 19:42:00 +02:00
RichardandClaude Opus 4.8 2377dc7adb K1a-Testabdeckung: Cleanup schont aktive Leiter (Floor-Deadlock)
Verifiziert den kritischen K1a-Fix mit Integrationstests statt nur per Review
(nach dem K3-Fehlplatzierungs-Fund):
- TraderMonitorService._clob -> IClobClient (verhaltensneutral); CleanupStaleOpenOrdersAsync
  internal. FakeCopyTradeLogRepository ergaenzt.
- 2 Tests: Stale Order mit aktiver Leiter wird NICHT gecancelt; ohne Leiter WIRD sie
  storniert (Kontrast, beweist Nicht-Vacuositaet).

Build 0 Fehler, 244 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 19:41:09 +02:00
RichardandClaude Opus 4.8 f4045f08e1 Engine-Testabdeckung (Guards) + K3-Korrektur am echten Bug-Ort
Testabdeckung fuer den geldkritischen Engine-Pfad (bisher 0 Tests), da die
Fable-Guards zwischen Services entstehen und Unit-Tests sie nicht fangen:
- Engine._clob -> IClobClient (verhaltensneutral, DI registriert IClobClient bereits);
  ProcessAccountOrderAsync internal. FakeMarketRepository/FakeAccountRepository ergaenzt.
- 7 Integrationstests (CopyTradingEngineTests) ueber gemockten CLOB: H3 BUY-Skip bei
  ExitPending, Doppel-SELL-Guard, K3 System-Close (TraderId==0) schliesst Fremd-Position,
  Fremd-Trader-SELL bleibt abgewiesen, H2 Cleanup schont Leiter (+ Kontrast ohne Leiter).

DABEI ECHTEN BUG GEFANGEN: Der K3-Fix aus Slice 3 sass an der falschen Stelle
(IsAuthorizedSell nach dem Position-Remove, Zeile ~643) – der eigentliche Ownership-Check
ist der fruehe inPortfolio-Lookup (Zeile 437, p.SourceTraderId == signal.TraderId), der
System-Signale schon vorher mit early return abwies. Fix jetzt am richtigen Ort; der
downstream-Check bleibt als Defense-in-depth. Ohne den Engine-Test waere das unentdeckt geblieben.

Build 0 Fehler, 242 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 19:38:11 +02:00
RichardandClaude Opus 4.8 782c08a860 Slice 6 (Fable-Fixes): Totcode/Demo-Balance/Settings-Validierung + Plan-Abschluss
- Totcode: services/SnapshotService.cs entfernt (nirgends registriert).
- Demo-Balance/PnL-Reconciliation: Demo-BUY zieht jetzt die Entry-Fee ab, Demo-Close
  schreibt netto (exitUsd - Exit-Fee) gut -> Summe(Balance-Aenderungen) = Summe(PnL)
  statt um die Fees zu driften (Demo als Validierung konsistent).
- Settings-Validierung: SellLogic.IsLadderConfigInverted (Max-Preisabstand >= SELL-Floor
  -> Leiter startet am Floor) + Warnung beim Settings-Laden (StartupHydration).

Bewusst als Follow-up dokumentiert (Live-Verifikation/Risiko): M3-Autoincrement-Migration,
PersistenceService-Dedup-Zeitfenster, Perf (UpsertLive-Dirty-Check, Leiter-Parallelitaet).

Tests: +3 (IsLadderConfigInverted). Build 0 Fehler, 236 gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 18:45:52 +02:00
RichardandClaude Opus 4.8 84b2b276d9 Slice 5 (Fable-Fixes): H3 – BUY-Skip waehrend ExitPending
Entscheidung Richard (Variante A): Re-buyt der Master, waehrend unsere SELL-Leiter
die Position abverkauft, wird der BUY uebersprungen statt zugekauft. Sonst stockte
der BUY die Position auf, die die Leiter danach inkl. neuer Shares zum alten Floor
verkauft (oekonomisch widerspruechlich). Die Leiter fuehrt den Exit sauber zu Ende.

Guard am Anfang des Engine-BUY-Pfads (spiegelt den bestehenden SELL-ExitPending-Guard).
Build 0 Fehler, 233 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 18:41:26 +02:00
RichardandClaude Opus 4.8 bdcd3641e4 Slice 4 (Fable-Fixes): H4/M1/M2/M3-min/M4/M6 + Doku
H4 – Rundungs-Dust-Reject-Schleife:
- SellLogic.RoundToTick (0.001, AwayFromZero, wie CalculateExactOrderAmounts). Die
  Leiter platziert Preise gerundet -> usdc = size × Preis geht exakt auf (kein Dust).
- ProcessLadderAsync bricht ab, wenn pos.Size < MinShares (Dust-Rest gehalten,
  ExitPending=false), statt endlos Sub-Minimum-Orders zu schicken.

M1 – GlobalPnl-Doppelzaehlung: in beiden Live-Close-Bloecken jetzt NUR innerhalb des
_processedClosures-Dedup-Guards gebucht (API-Lag zaehlte sonst doppelt).
M2 – TokenId in beiden Live-Close-Records gesetzt (sonst greift die Dedup nach Neustart nicht).
M3 (Minimum) – TradeId-Init: serverseitiges GetMaxTradeId() statt Full-Table-Find(_=>true).Max();
  Fehlschlag wird laut geloggt statt still geschluckt. (Autoincrement-Migration bewusst als
  Follow-up aufgeschoben – Schema-Aenderung an der Trade-Persistenz erst im Zielland live verifizieren.)
M4 – MongoExportParser ProfitTarget-Default 50 -> 9999 (Take-Profit bleibt dormant).
M6 – Fee-Satz (real oder Kategorie-Fallback, FeeModel.ResolveBps) in alle signierten Orders:
  Engine-BUY, SELL-Leiter (Start/Step/Floor), PreRedeem (WSS + REST). API-gated, im Zielland verifizieren.
Doku – stale [Description]: ProfitTarget/SellFloorPct als IMPLEMENTIERT markiert.

Tests: +10 (RoundToTick, Dust-Abbruch, ResolveBps). Build 0 Fehler, 233 gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 14:03:00 +02:00
RichardandClaude Opus 4.8 8252219163 Slice 3 (Fable-Fixes): K3 Demo-Resolution + M5 Demo-Score/Auto-Pause
K3 – Demo-Auto-Close bei Marktauflösung funktioniert wieder:
- System-SELLs (TraderId==0) sind vom Ownership-Check ausgenommen. Regel in reine
  CopyTradingRisk.IsAuthorizedSell(signalTraderId, positionSourceTraderId) extrahiert
  (System ODER Besitzer) und in der Engine genutzt. Vorher lehnte der Check jedes
  System-Close ab (Copy-Positionen haben SourceTraderId>0) -> Demo-Positionen
  schlossen bei Resolution nie, 30s-Loop feuerte endlos.
- Resolved-Cache (_resolvedDemoMarkets) in PollDemoExpirationsAsync: aufgeloeste
  Maerkte werden nicht erneut angefragt (kein Log-Spam / keine unnoetige API-Last).

M5 – Auto-Pause in der Demo-Phase nicht mehr wirkungslos:
- Anzeige-Spalten (CopyPnl30d etc.) zeigen Live-Kennzahlen, sobald vorhanden, sonst
  Demo-Kennzahlen -> Demo-Validierung ist sichtbar statt leer.
- Harte Auto-Pause wirkt bewusst NUR auf Live-Ergebnissen.
- Kadenz: stuendlicher Light-Check (Auto-Pause) statt nur alle 12h; schwere
  History-Analyse bleibt 12h (schliessen sich pro Tick aus, kein Doppellauf).

Tests: 5 neue (IsAuthorizedSell). Build 0 Fehler, 223 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 13:33:24 +02:00
RichardandClaude Opus 4.8 a3d3d50681 Docs: Fortschritt Slices 0-2 im Plan vermerkt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 13:20:26 +02:00
RichardandClaude Opus 4.8 98109b78f6 Slice 2 (Fable-Fixes): K2 – Neustart-Reconciliation
Ruhende GTC-Leiter-/MakerEntry-Orders ueberleben Neustarts auf dem CLOB, der
Verwaltungszustand (ExitLadders/ExitPending/PendingOrderTimestamps) ist transient.
Ohne Bereinigung liefe die Engine gegen Waisen-Orders (Doppel-Leiter, Kaskaden).

- StartupOrderReconciliationService (IHostedService): storniert beim Start je
  Live-Account alle offenen CLOB-Orders; danach entscheidet die Engine sauber neu.
  Registriert als ERSTER Modul-HostedService (nach Hydration, vor Monitor/Engine),
  pro Account fehlertolerant.
- GetOpenOrdersAsync: assetId jetzt optional (default "") -> ohne Filter ALLE
  offenen Orders des Accounts. Signaturneutral (HMAC geht ueber Pfad ohne Query),
  rueckwaertskompatibel fuer die bestehenden per-Asset-Aufrufer. IClobClient +
  FakeClobClient nachgezogen.

Hinweis: "/data/orders ohne asset_id = alle Orders" ist API-gated und im Zielland
live zu verifizieren (wie M6).

Tests: 3 neue (cancelt alle Orders je Live-Account, ueberspringt Demo/credential-los,
no-op ohne offene Orders). Build 0 Fehler, 218 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 13:20:03 +02:00
RichardandClaude Opus 4.8 0200a726e7 Slice 1 (Fable-Fixes): Leiter-Ownership – K1/H2/H1
Wer darf die ruhende Leiter-Order anfassen? Nur die Leiter selbst.

- H1 (Race): StartLadderAsync macht ZUERST einen atomaren Claim
  (ExitLadders.TryAdd). Master-SELL (Engine) und Profit-Target (Sync) sind
  damit idempotent – kein Doppel-GTC / keine Fehlerkaskade. Verliert ein
  Aufrufer den Claim, wird die (evtl. von der Engine entfernte) Position als
  ExitPending zurueckgestellt – kein Waise. Order-Fehler gibt den Claim zurueck.
- K1a (Floor-Deadlock): CleanupStaleOpenOrdersAsync ueberspringt Keys mit
  aktiver Leiter (ExitLadders.ContainsKey) – cancelt die Floor-Order nicht mehr.
- K1b (Floor-Robustheit): ProcessLadderAsync prueft am Floor via GetOpenOrders,
  ob die SELL-Order noch ruht; falls nicht (Cleanup/extern/Teil-Fill), neu
  platzieren statt bis zum Neustart unverkaeuflich zu haengen.
- H2 (Engine-Cancel): Pre-Signal-CancelConflictingOrders wird uebersprungen,
  wenn fuer den Markt eine Leiter aktiv ist – zerschiesst die Leiter-Order nicht.

Tests: 8 neue Integrationstests (SellLadderService ueber gemockten IClobClient):
atomarer/paralleler Claim, Waisen-Schutz, Claim-Rueckgabe, Floor-Neuplatzierung,
Floor-Halten bei ruhender Order, Leiter-Ende bei gefuellter Position.
Verifikation: Build 0 Fehler, 215 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 12:43:17 +02:00
RichardandClaude Opus 4.8 ad8f7b0d03 Slice 0 (Fable-Fixes): IClobClient-Seam fuer testbare CLOB-Interaktionen
Verhaltensneutrale Testinfrastruktur als Grundlage fuer Slice 1/2:
- IClobClient-Interface (Core) ueber die von Leiter/Reconciliation genutzten
  CLOB-Methoden (Place/CancelConflicting/GetOpenOrders/CancelOrder).
- PolymarketClobClient implementiert IClobClient (Signaturen unveraendert).
- DI-Seam im Modul: IClobClient -> PolymarketClobClient-Singleton.
- SellLadderService haengt jetzt an IClobClient (statische CalculateExactOrderAmounts
  bleibt am konkreten Typ).
- InternalsVisibleTo(PolyTrader.Tests) + FakeClobClient-Test-Double.

Verifikation: Build 0 Fehler, 207 Tests gruen, --smoke-ui Container-Aufbau ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 11:53:12 +02:00
RichardandClaude Opus 4.8 bb929fa23a Docs: Umsetzungsplan Fable-Review-Fixes (Slices 0-6)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 11:29:41 +02:00
RichardandClaude Opus 4.8 429a05f885 Phase 4.1: Maker-Einstieg (dormant, per-Master-Flag)
- Ist TrackedTrader.MakerEntry gesetzt, wird der BUY OHNE Preisaufschlag als
  ruhendes GTC-Limit am Master-Preis platziert (statt teurem Taker-Fill via GTD),
  spart Fees/Spread bei langsamen Mastern. Nutzt die getestete
  CopyTradingRisk.CalculateBuyOrderPrice (0 % Aufschlag). Default aus -> dormant.
  (Ohne Orderbuch ist der Master-Preis die Naeherung fuer den Bid; echte
  Bid-Platzierung + Nichtfill-Eskalation folgen mit dem Market-Channel/Zielland.)

207 Tests gruen. Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 19:14:50 +02:00
RichardandClaude Opus 4.8 54ed1a414e Phase 4.2 / 0.2: realistischer Demo-Modus (Exit-Slippage + Fees)
- DemoModel (pure, getestet): ExitFillPrice (Signalpreis minus halber Spread,
  geclamped) + CloseWithFees (Erlös zum Fill-Preis minus Round-Trip-Fee).
- CopyTradingEngine Demo-Close nutzt es: ExitPrice = realistischer Fill statt
  Signalpreis, RealizedPnl netto nach Fees, ClosedTrade.TotalFees befuellt.
  -> Demo-PnL ist nicht mehr systematisch geschoent (Master-Validierung brauchbar).
- DemoModelTests (Fill-Clamping, Round-Trip-Fee, 0-Fee).

207 Tests gruen. Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 18:49:38 +02:00
RichardandClaude Opus 4.8 b259f310d3 Phase 2 (Fundament): proportionale Teilverkauf-Logik pure + getestet
- SellLogic.SharesToSell (pure): spiegelt die Verkaufsquote des Masters. 0 =
  ignorieren (< MinSellRatioPct = Rauschen), = ourShares = Voll-Exit (Master ganz
  raus oder Rest/Teil unter Polymarket-Minimum -> kein Dust), sonst proportional.
- 7 Tests (Teilverkauf, Rausch-Schwelle, Voll-Exit-Faelle, Dust-Grenzen).

Wiring in die Engine bewusst zurueckgestellt: braucht Partial-Fill-Handling
(Phase 1.1 CLOB User-Channel, API-abhaengig -> Zielland). Aktuelles Voll-Exit-
Verhalten unveraendert.

200 Tests gruen. Build gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 18:21:42 +02:00
RichardandClaude Opus 4.8 4619edbb99 Phase 3: Copy-Score + Auto-Pause-Kill-Switch (Trader-Intelligence)
Aus UNSEREN geschlossenen Trades (nicht der externen Data-API) berechnet -> jetzt machbar.

- TraderScore (pure, getestet): Compute (CopyPnl/ProfitFactor/AvgPnlPerTrade/Count
  aus realisierten PnLs) + ShouldAutoPause (enabled & count>=minTrades & pnl<=-threshold).
- TrackedTrader: CopyPnl30d/CopyProfitFactor/CopyAvgPnlPerTrade/CopyTradeCount30d
  (mit Erklärungen) + Migration AddTraderCopyScore (auf MySQL angewendet).
- CopyTradingState: globale Auto-Pause-Config (AutoPauseMinTrades 10,
  AutoPauseDrawdownUsd 10). Per-Master-Schalter TrackedTrader.AutoPauseEnabled.
- MasterTraderAnalyticsJob.UpdateCopyScoresAndAutoPauseAsync (entkoppelt von der
  flakigen Master-History-API): Copy-Score je Master (30T), harte Auto-Pause bei
  Verlust über Schwelle (IsActive=false, Reasoning+Zeitstempel, Threema; Reaktivierung
  nur manuell). Injiziert ICopyTradeLogRepository + ThreemaService.
- MasterTradersView: 4 Copy-Score-Spalten.

193 Tests gruen. Build/Smoke gruen.
OFFEN (3.2, API-abhaengig, Zielland): Sniper-Metriken (MedianHold/SellWithin5Min)
aus der Data-API (Portierung analyze_snipers.py).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 18:19:41 +02:00
RichardandClaude Opus 4.8 cda5b055aa Phase 0.2: Fee-Modell-Fundament (FeeModel + MarketData.TakerFeeBps + BUY-Fee-Log)
- FeeModel (pure, getestet): Kategorie-Fallback-Bps (Sports 75 / Politics-Finance
  100 / Crypto 180 / Geopolitics 0 / Default 100) + FeeUsd(notional, bps).
- MarketData.TakerFeeBps (Core) + Migration AddMarketTakerFeeBps (auf MySQL
  angewendet). Speichert den echten API-Satz, sobald verfuegbar; 0 = Fallback.
- CopyTradingEngine loggt beim BUY die erwartete Taker-Fee (TakerFeeBps aus
  MarketCache, sonst Kategorie-Fallback) -> Akzeptanz "Fee im TradeReasoning".
- FeeModelTests (Kategorie-Mapping case-insensitive, FeeUsd, 0-Faelle).

183 Tests gruen. Build/Smoke gruen.

OFFEN (API-abhaengig, erst im Zielland verifizierbar): echtes fee_rate_bps-Feld
aus der CLOB/Gamma-API lesen; Fee-basierter Edge-Discard; PnL-Fee-Korrektur.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:58:59 +02:00
RichardandClaude Opus 4.8 395caad11a Phase 0.3: ProfitTarget-Take-Profit implementiert (dormant bei 9999)
- SellLogic.IsProfitTargetReached (pure, getestet): currentPrice >= entry*(1+pct/100);
  pct<=0 oder Default 9999 = inaktiv.
- Ladder-Start-Logik konsolidiert: SellLadderService.StartLadderAsync ist jetzt die
  gemeinsame Quelle fuer Master-SELLs (Engine) UND eigene Exits (Profit-Target).
  SellLadderService als Singleton+Hosted registriert; Engine + TraderMonitor
  injizieren es. Engine-SELL-Block ruft nur noch StartLadderAsync (verhaltensgleich).
- TraderMonitorService.CheckProfitTargetsAsync im 30s-Live-Sync: erreicht eine
  Live-Position ihre Schwelle, Exit ueber die Leiter (Startlimit = aktueller Preis,
  ExitReason "Profit Target"). PreRedeemLimit hat Vorrang. Dormant, da ProfitTarget
  projektweit 9999.

169 Tests gruen. Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:54:21 +02:00
RichardandClaude Opus 4.8 b378bc3499 Phase 0.4: Konsistenz-Fixes (Spam-Blockade, GlobalPnl, Demo-TokenId)
- SELL-Spam-Blockade greift nur noch bei kürzlichem SELL: PendingOrderTimestamps
  bekommt eine Side ("BUY"/"SELL"); ein vorheriger BUY blockiert einen legitimen
  schnellen SELL des Masters nicht mehr (alle Schreibstellen aktualisiert).
- GlobalPnl: PollClosedAccountsAsync addiert den realisierten PnL jetzt auch
  (wie PollLiveAccountsAsync) -> Anzeige driftet nicht mehr.
- Demo-ClosedTrade erhält TokenId (der _processedClosures-Preload filtert darauf;
  fehlte -> Duplikat-/Dedup-Risiko nach Neustart).

163 Tests gruen. Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:46:26 +02:00
RichardandClaude Opus 4.8 e22a6e3091 Phase 0.1: SELL-Eskalationsleiter statt Market-Dump (CLOB-kritisch)
Behebt die April-Verlustquelle: SELLs wurden als Market-Order mit 0.01-Limit ins
oft leergeraeumte Orderbuch geworfen -> wir wurden zur Exit-Liquidity. Jetzt:
GTC-Limit nahe am Master-Exit, stufenweises Nachpreisen bis zum Floor.

- Position.ExitPending (runtime-only, EF-ignoriert): Position wird bei SELL NICHT
  mehr optimistisch entfernt, sondern als ExitPending zurueckgestellt (kein
  Doppel-SELL, Limits rechnen korrekt; Sync schliesst nach bestaetigtem Fill).
- CopyTradingState.ExitLadders + ExitLadderState (transienter Leiter-Zustand).
- SellLogic (pure, getestet): FirstLimit (HF-fest/prozentual), Floor (SellFloorPct),
  NextPrice (relative Stufe, auf Floor geclamped), IsAtFloor, LadderStepPct (3%),
  LadderIntervalSeconds (HF 20s / sonst 120s).
- SellLadderService (BackgroundService): senkt offene Exit-Limits stufenweise
  (cancel via CancelConflictingOrdersAsync -> tiefer neu platzieren), am Floor ohne
  Fill Position halten + Threema-Benachrichtigung. Fills erkennt der bestehende Sync.
- CopyTradingEngine SELL-Live-Pfad ruft die Leiter; Demo-Pfad unveraendert.
  Doppel-SELL-Guard ueber ExitPending. Umfangreiches Logging (kein Live-Test moeglich).

163 Tests gruen. Build/Smoke gruen. Backup-Rollback: Commit 1dffc9e.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:40:40 +02:00
RichardandClaude Opus 4.8 1dffc9e253 Testnetz: geldkritische Trade-Mathematik extrahiert (TradeMath) + getestet
- Neue pure Klasse TradeMath (Logic/): ExitValue, RealizedPnl, PnlPercent
  (Null-Guard), WeightedAverageEntryPrice (Div-durch-0-Schutz).
- CopyTradingEngine ruft sie jetzt im Demo-Close-PnL und bei der Positions-
  Aufstockung (Demo + Live, gewichteter Einstiegspreis) – verhaltensneutral.
- TradeMathTests (6 Faelle: Gewinn/Verlust, %-Basis, 0-Kapital/0-Size-Guards).

Gesamt 160 Tests gruen. Build/Smoke gruen. (Phase-0.1-SELL-Wiring weiterhin
bewusst zurueckgestellt bis zum Server-Test; pure Leiter liegt getestet bereit.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:09:41 +02:00
RichardandClaude Opus 4.8 581755029a Testnetz: Micro-Order-Minimum + SELL-Proportionalität extrahiert; SELL-Leiter (Phase 0.1) vorbereitet
Weiter im Muster extrahieren->testen (verhaltensneutral, clob.md):
- CopyTradingRisk.IsBelowPolymarketMinimum (Shares < 5.5 || USDC < 0.10) –
  BUY-Micro-Order-Filter verdrahtet + Tests.
- SellLogic.SellProportion (signalSize/(remaining+signalSize), Denominator<=0 -> 0)
  + Konstante MinSignificantSellRatio (0.30); SELL-Proportionalitätscheck der
  Engine ruft sie jetzt (Charakterisierung, sichert Phase-2-Umbau ab).
- SellLogic-Eskalationsleiter (Phase 0.1, NOCH NICHT verdrahtet): FirstLimit
  (HF-fest/prozentual), Floor (SellFloorPct), NextPrice (relative Stufe, auf Floor
  geclamped), IsAtFloor. Reine Grundlage fuer das spaetere SELL-Wiring.
- Tests: CopyTradingRisk-Minimum (5 Faelle) + SellLogicTests (Proportion +
  Leiter). Gesamt 154 gruen.

Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:03:44 +02:00
RichardandClaude Opus 4.8 6a8ecbc80a MaxBuyPrice-Skala korrigiert + Blockchain-Abo-Logik extrahiert & getestet
- Fix (Richard): MaxBuyPrice-Skalen-Korrektur analog PreRedeemLimit
  (Migration FixMaxBuyPriceScale: Werte > 1 wie 98.0/99.0 -> /100 = 0.98/0.99;
  auf MySQL angewendet). Cap greift bei den betroffenen Accounts jetzt wieder.
  Beschreibung des Feldes um den Skalen-Hinweis ergaenzt.

- Testnetz erweitert: reine Klasse BlockchainSubscription (Logic/) fuer das
  Alchemy-Abo (PadAddress + Filter-Batching in 3er-Chunks, Buy=Topic3/Sell=Topic2
  je Chunk). AlchemyWebsocketService ruft sie jetzt (verhaltensneutral;
  Konstanten + lokale Methoden entfernt). BlockchainSubscriptionTests: 13 Faelle
  (Padding, Chunk-Anzahl 0/1/3/4/6/7, Topic-Zuordnung, CTF-Adresse/Topics).

Gesamt 137 Tests gruen. Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 10:54:46 +02:00
RichardandClaude Opus 4.8 360f264ed8 CLOB-Sicherheitsnetz: BUY-Risikologik extrahiert + breit getestet; PreRedeemLimit-Skala korrigiert
Ziel (Richard): vor den CLOB-Eingriffen ein umfangreiches Testnetz, damit künftige
Änderungen keine neuen Fehler einschleusen. Reiner, verhaltensneutraler Umbau –
alte Version liegt als Rollback in Git (Commit 38f609e), siehe .agents/rules/clob.md.

- Neue pure Klasse CopyTradingRisk (Logic/): CalculateBuyOrderPrice (HF-fest /
  prozentual, gedeckelt durch MaxBuyPrice + harte 0.99), ResolveTimeBucket/
  TimeLimitPct/TimeBucketLabel/IsPositionInBucket (Zeitfenster-Exposure),
  MaxPerMarket (Markt-Budget inkl. Low-Balance-Bypass-Stufen).
- CopyTradingEngine BUY-Pfad ruft diese Funktionen jetzt statt Inline-Mathematik
  (1:1-Semantik, dedupliziert die doppelte Order-Preis-Berechnung).
- CopyTradingRiskTests: 38 Fälle über alle Zweige/Grenzwerte (HF vs. normal,
  MaxBuy-/0.99-Deckel, Bucket-Grenzen 6/24/72h, null/expired Expiry,
  Balance-Stufen 150/500). Gesamt 124 Tests grün.

Fix: PreRedeemLimit-Skalen-Korrektur (Migration FixPreRedeemLimitScale): Alt-Werte
> 1 (z. B. 99.5) werden /100 (0.995); 0 bleibt deaktiviert. Auf MySQL angewendet.

Build/Smoke grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 10:03:53 +02:00
RichardandClaude Opus 4.8 38f609ed31 CopyTrading Slice 1: Settings-Fundament + detaillierte Erklärungen
Umsetzung des Fable-Plans, Start mit dem risikoarmen Settings-Fundament
(kein Hot-Path/CLOB-Verhalten geändert):

- Alle Copytrading-Settings (alt + neu) haben jetzt [Description]/[DisplayName] ->
  im PropertyGrid als Erklärung sichtbar (Richards Vorgabe). Test erzwingt, dass
  jede einstellbare Option eine Beschreibung trägt.
- ProfitTarget-Default -> 9999 (praktisch deaktiviert); Migration setzt zusätzlich
  bestehende Zeilen per SQL auf 9999 (Entscheidung 2). Take-Profit-LOGIK folgt.
- Neue Account-Settings (noch nicht verdrahtet, für Phase 0.1/1.3/2):
  SellFloorPct (15), MaxSpreadPct (5), MinSellRatioPct (10).
- Neue Master-Trader-Settings: AutoPauseEnabled (Default AN, per Master abschaltbar,
  Entscheidung 3) + MakerEntry (Default aus, Entscheidung 4).
- EF-Migration AddCopytradingBehaviorSettings (neue Spalten + sinnvolle Defaults
  fuer Bestandszeilen) erstellt und auf MySQL angewendet.
- Erklärung dokumentiert einen gefundenen Skalen-Verdacht: PreRedeemLimit wird
  gegen den 0-1-Preis verglichen; Alt-Werte 99.5 triggern nie (-> ggf. 0.995).

Tests: 86 gruen. Build/Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 09:44:50 +02:00
RichardandClaude Opus 4.8 92a88e8be8 Phase 7: Mapping-Randfälle + Parser-/Repo-Randfälle (78 Tests)
- DbContextModelTests: feinkörnige Modell-Invarianten - Dezimal-Präzision (18,6)
  auf Geldfeldern (Core + Settings), MaxLength auf Strings, manuell gesetzte Keys
  (ValueGeneratedNever), AssignedAccountIds hat Value-Converter + text-Spalte,
  MarketData JSON-Spalten = text, Indizes (TradeRecord.ClosedAt,
  MasterTraderHistory TraderId/ClosedAt).
  (GetColumnType() wirft unter InMemory -> Spaltentyp via Relational:ColumnType-
  Annotation ausgelesen.)
- MongoExportParserTests erweitert: numerische statt String-Dezimale, unbekannte
  Felder ignoriert, mehrere Dokumente in Reihenfolge, AssignedAccountIds als
  String-Zahlen, IsActive-Default.
- RepositoryEdgeCaseTests: GetAll leer != null, Update-Alias, Factory-Isolation,
  History-Exists/GetByTraderSince inklusive an den Grenzen.

Alle 78 gruen. (Copytrading-Service-Logik bewusst noch nicht getestet - wird
parallel ueberarbeitet.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 09:16:03 +02:00
RichardandClaude Opus 4.8 b8d2c8094b Feinschliff: restliche Copytrading-Services ins Modul + EF-Logging gedrosselt
- MasterTraderAnalyticsJob + PersistenceService von services/ nach
  src/PolyTrader.Modules.CopyTrading/Services/ verschoben und in
  CopyTradingModule.RegisterServices registriert (reiner Move). Beide sind
  copytrading-spezifisch (Master-Trader-Historie bzw. Persistenz der
  geschlossenen Copytrades ueber den Modul-Channel; Dual-Write in Core-Log bleibt).
- Program.cs: die zwei Hosted-Service-Registrierungen entfernt.
- appsettings.json: Logging-Sektion ergaenzt -> EF-Core-Command-Logging auf
  Warning (kein SQL-Spam mehr; --smoke-ui zeigt 0 "Executed DbCommand"-Zeilen).

Damit liegt die gesamte Copytrading-Logik im Modul; App/Core enthalten nur noch
generische Infrastruktur + Startup-Hydration + CLI-Tools.

Build gruen, 48 Tests gruen, --smoke-ui gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 19:47:15 +02:00
RichardandClaude Opus 4.8 3456fd9768 Modularisierung: WSS-/Alchemy-Listener ins Copytrading-Modul verschoben
Beide Listener sind copytrading-spezifisch (überwachen die getrackten Master-
Trader bzw. Auto-Redeem nach Copytrading-Settings) und werden jetzt vom Modul
besessen statt von der App. Reiner Move, keine Logikänderung.

- services/AlchemyWebsocketService.cs + services/PolymarketWssClient.cs
  -> src/PolyTrader.Modules.CopyTrading/Services/ (Namespace bleibt transitional).
- CopyTradingModule.RegisterServices registriert nun beide Hosted Services sowie
  IBlockchainWssClientFactory->AlchemyWssClientFactory (Core-WSS-Infra, nur vom
  Copytrading-Blockchain-Listener genutzt).
- Program.cs: die drei Registrierungen entfernt (WSS-Factory + 2 Hosted Services)
  + ungenutztes using PolyTrader.Core.Streaming.
- WSS-Verbindungsinfrastruktur (AlchemyWssClient/BlockchainWss) bleibt in Core.

DI-Auflösung unverändert (gleicher Container). Build grün, --smoke-ui grün.
Laufzeit-Verifikation der WSS-Verbindungen: Server-Test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 18:44:49 +02:00
RichardandClaude Opus 4.8 1b51872f00 Phase 7: Tests erweitert + Mongo-Parser extrahiert (testbar)
Tests (jetzt 48 grün):
- DbContextMappingTests: sichert core_/mod_-Tabellennamen, Position-Composite-Key,
  TrackedTrader-Key, ClosedTradeRow nicht gemappt, AccountState.OpenPositions ignoriert.
- PositionRepositoryTests: Live/Demo-Trennung, Upsert setzt Account+Demo-Flag,
  Update ohne Duplikat, DeleteLive, DropDemo.
- MarketRepositoryTests: GetActive filtert Closed, Upsert-Update, FindByTokenId.
- TradeLogRepositoryTests: GetRecent (Sortierung+Limit), Find-Predikat, Guid-Id unique.
- MongoExportParserTests: String-Dezimale, null->"", fehlende Felder->Default,
  AssignedAccountIds-Array, Category-Default, Nicht-Array->leer.

Refactor:
- Mongo-Export-Parsing aus ConfigMigrator in testbare Klasse
  PolyTrader.Modules.CopyTrading.ConfigImport.MongoExportParser ausgelagert
  (ParseAccounts -> Account+Settings, ParseTraders). ConfigMigrator nutzt sie;
  --migrate-json end-to-end verifiziert (3/3/32).
- PolyTrader.App.csproj: tests/** vom Default-Glob ausgeschlossen (App zog sonst
  die Testdateien mit rein -> doppelte AssemblyInfo/Xunit-Fehler).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 11:52:52 +02:00
RichardandClaude Opus 4.8 ca16cd8a91 Phase 7: Testprojekt (xUnit) + Repository-Tests
- Neues Projekt tests/PolyTrader.Tests (xUnit, EF Core InMemory-Provider),
  zur Solution hinzugefügt.
- InMemoryContextFactory<TContext>: Test-IDbContextFactory (isolierte In-Memory-DB
  je Test, geteilt über alle Kontexte einer Factory – wie im echten Betrieb).
- 18 Tests über die EF-Repos:
  - TrackedTrader: Upsert insert/update ohne Duplikat, Delete,
    AssignedAccountIds-JSON-Round-Trip (Value-Converter) + Set-Ersetzung.
  - CopyTradingAccountSettings: Upsert/Get (Dezimalwerte), Get-null, Delete.
  - CopyTradeLog: Insert/Find, Exists-Dedup (Account+Token), Predikat-Filter.
  - MasterTraderHistory: Exists-Zeitfenster, GetByTraderSince-Cutoff.
  - Core Accounts: Upsert insert/update, Delete.
- Alle 18 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 11:24:33 +02:00
RichardandClaude Opus 4.8 e27a659529 Copytrading-Tabs: ToolStrips in ClosedTrades + AccountSettings
Konsistent zum Master-Trader-Tab bekommen die beiden anderen Tabs eine ToolStrip
mit ihren Aktions-Buttons:
- ClosedTradesView: ToolStrip mit "Aktualisieren"; Kurzauswertung wandert in eine
  untere Statusleiste (lblSummary).
- AccountSettingsView: ToolStrip mit Account-Auswahl (ToolStripComboBox) +
  "Speichern"; Hinweistext in untere Statusleiste (lblHint).
- Beide bleiben Designer-basiert (Size statt ClientSize, da UserControl).

Hinweis: Separate Einzelview-Registrierungen existieren nicht mehr (bereits in
c3d7e41 auf die eine View copytrading.main konsolidiert); die drei UserControls
sind ausschliesslich Tab-Inhalte.

Verifiziert: Build gruen, --smoke-ui gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 11:13:48 +02:00
RichardandClaude Opus 4.8 c3d7e41e62 Copytrading-UI: ein Fenster mit TabControl statt drei Launcher-Buttons
Statt je Ansicht ein eigenes Fenster (3 Launcher-Buttons) gibt es jetzt EIN
Modul-Fenster mit Tabs – wie im alten PolyTrader. Skaliert sauber, wenn weitere
Module dazukommen (ein Button je Modul).

- MasterTradersView/ClosedTradesView/AccountSettingsView: von Form -> UserControl
  (Tab-Inhalte); Designer-Root auf Size statt ClientSize/Text/MinimumSize.
- Neu: CopyTradingMainForm (Designer) mit TabControl + 3 TabPages, hostet die
  drei UserControls; Initialize(IServiceProvider) versorgt jeden Tab per DI.
- CopyTradingModule.RegisterUi registriert nur noch EINE View "Copytrading".

Verifiziert: Build grün, --smoke-ui grün (eine View copytrading.main +
Launcher konstruieren fehlerfrei, 3 Accounts / 32 Trader hydriert).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 10:26:40 +02:00
RichardandClaude Opus 4.8 76007db93f Modul-Views: parameterloser Ctor + Initialize() (Designer-öffenbar)
Der VS-WinForms-Designer braucht einen parameterlosen Konstruktor, um eine Form
zu instanziieren. Die drei Views hatten nur einen DI-Ctor -> Designer hätte sie
nicht öffnen können. Umgestellt auf das Core-View-Muster (DashboardView):
- Parameterloser Ctor: InitializeComponent() + Event-Wiring.
- Initialize(deps): Abhängigkeiten setzen + Daten laden.
- Felder nullable + Null-Guards in den Handlern.
- CopyTradingModule.RegisterUi: new View() + view.Initialize(...) statt DI-Ctor.

Verifiziert: Build grün, --smoke-ui grün (3 Accounts / 32 Trader, alle Views OK).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 10:15:04 +02:00
RichardandClaude Opus 4.8 4caba5bfd1 Copytrading-Views auf Designer-Muster umgestellt
Die drei Modul-Views wurden von komplett code-first (alle Controls im Konstruktor)
auf das Standard-WinForms-Designer-Muster umgestellt (je X.cs + X.Designer.cs mit
InitializeComponent), damit sie im Designer geöffnet und bearbeitet werden können:

- ClosedTradesView, AccountSettingsView, MasterTradersView: alle wichtigen
  Steuerelemente (Panels, DataGridView mit expliziten Spalten via
  AutoGenerateColumns=false, PropertyGrid, ToolStrip, GroupBox, CheckedListBox,
  ComboBox, Buttons, Labels, Splitter) sind jetzt Designer-Felder.
- Konsistent mit den Core-Views (DashboardView-Muster): Layout im Designer,
  Zellformate/Event-Wiring/Datenbindung im Code.

Verifiziert: --smoke-ui grün (3 Accounts / 32 Trader; alle Views + Launcher OK).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 10:11:30 +02:00
RichardandClaude Opus 4.8 f1451b547c Fix: Startet nicht / MySQL-Timeout ohne UI (Config- & Startup-Härtung)
Ursachen (App startete aus bin/ bzw. per Doppelklick ohne UI):
1. appsettings.Local.json (MySQL-Connection) wurde NICHT ins Output kopiert und
   nur relativ zum Arbeitsverzeichnis geladen -> leere Connection -> Pomelo fiel
   auf localhost:3306 zurueck -> "Connect Timeout expired".
2. ServerVersion.AutoDetect(conn) oeffnet beim Options-Bau eine blockierende
   DB-Verbindung -> haengt/crasht den Start, wenn die DB nicht erreichbar ist.
3. CopyTradingEngine.StartAsync lud den MarketCache ungeschuetzt -> DB-Fehler
   riss AppHost.Start() ab, bevor die UI erschien.

Fixes:
- csproj: appsettings.Local.json mit ins Output kopieren (CopyToOutputDirectory).
- Program: UseContentRoot(AppContext.BaseDirectory) -> Config wird immer neben
  der EXE gesucht (Main + Smoke-Test).
- ServerVersion fest gepinnt: DatabaseServerVersion.Value = MariaDB 11.8.6 (wie
  am Server erkannt); AddCorePersistence + CopyTradingModule nutzen sie statt
  AutoDetect. Kein blockierender Connect mehr beim Start.
- CopyTradingEngine-Preload in try/catch: DB-Fehler bricht den Start nicht mehr ab.
- Neuer Diagnose-CLI --db-version (gibt @@version aus).

Verifiziert: --smoke-ui aus fremdem Arbeitsverzeichnis laeuft gruen
(3 Accounts / 32 Trader hydriert, alle Views + Launcher OK).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 10:03:44 +02:00
RichardandClaude Opus 4.8 6f478e8764 Fix: appsettings.Local.json im Host laden + headless UI-Smoke-Test
- KRITISCH: Host.CreateDefaultBuilder lädt appsettings.Local.json nicht (nur
  appsettings.json + appsettings.{Environment}.json). Dadurch war
  Database:MySqlConnectionString zur Laufzeit leer -> Pomelo fiel auf
  localhost:3306 zurück ("Connect Timeout expired"), die GUI-App hätte am
  Server nie mit MySQL verbunden. Fix: appsettings.Local.json explizit per
  ConfigureAppConfiguration ergänzen (in Main und im Smoke-Test).
- Neuer CLI-Modus --smoke-ui: baut einen minimalen Host, hydriert den State
  aus MySQL und konstruiert jede registrierte View + den Launcher (ohne
  Message-Loop / Trading-Services). Deckte den obigen Bug auf.
- Verifiziert: 3 Accounts / 32 Trader hydriert; alle 3 Modul-Views + Launcher
  konstruieren fehlerfrei mit echten Daten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 09:42:56 +02:00
RichardandClaude Opus 4.8 05e0576965 Phase 5-UI: Copytrading-Modul-Views (Master-Trader, Closed Trades, Account-Settings)
- MasterTradersView: Liste + PropertyGrid-Editor + Account-Zuweisung
  (CheckedListBox -> AssignedAccountIds), Neu/Speichern/Loeschen; persistiert
  via ITrackedTraderRepository + synct CopyTradingState.Traders.
- ClosedTradesView: read-only Grid der geschlossenen Copytrades mit
  aufgeloesten Account-/Trader-Namen + Kurzauswertung (ICopyTradeLogRepository).
- AccountSettingsView: Account-Auswahl + PropertyGrid fuer
  CopyTradingAccountSettings, Speichern via Repo + State-Sync.
- IPolyTraderModule.RegisterUi erhaelt jetzt IServiceProvider (Module loesen
  ihre View-Abhaengigkeiten auf); Program uebergibt viewServices.
- CopyTradingModule.RegisterUi registriert die 3 Views (Group "CopyTrading").
- LauncherForm haengt Modul-Views dynamisch als Buttons an toolstrip_windows
  (Core kennt keine Modulnamen; Bindung nur ueber View-IDs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:09:56 +02:00
RichardandClaude Opus 4.8 b951b912f4 Phase 6 (Stufe 6): MongoDB vollstaendig entfernt
- Legacy-Form stillgelegt: frm_main(.Designer/.resx) + frm_analytics(.Designer/.resx)
  geloescht, 'Open Legacy'-Menue aus LauncherForm entfernt.
- Program.cs: IMongoDatabase-Registrierung + closed_trades-Cleanup weg;
  Trade-Nummerierung liest jetzt hoechste TradeId aus ICopyTradeLogRepository.
- StartupHydrationService: Mongo-/Bson-Fallback entfernt (Settings kommen aus
  dem Repo; fehlende Accounts erhalten Default-Settings).
- Alle Mongo*Repository (Core 4 + Modul 4) geloescht; DI-Zweige auf EF/MySQL
  reduziert (AddCorePersistence, CopyTradingModule).
- ConfigMigrator: Mongo-Pfad (Run/MigrateSettings) entfernt; nur noch
  RunFromJson + VerifyMySql (kein Mongo-Treiber mehr).
- Modelle: [BsonId] entfernt (EF-Keys via HasKey); ObjectId-Defaults -> Guid.
- LiteDB-Shim (MongoDbLiteDBShim) geloescht; MongoDB.Driver- + LiteDB-Pakete
  aus App/Core entfernt; stale usings + user-sichtbare Strings bereinigt.
- DatabaseOptions/appsettings.json: Mongo-Provider/Connection-Felder entfernt.
- Build gruen; --verify-mysql bestaetigt 3 Accounts/3 Settings/32 Trader/2344 Markets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 18:34:17 +02:00
RichardandClaude Opus 4.8 d227d24ca8 Phase 6 (Stufe 5): Default-Provider auf MySQL + Readback-Verifikation
- appsettings.json: Database:Provider = "MySql" (voller Umstieg).
- ConfigMigrator.VerifyMySql + CLI --verify-mysql: liest Accounts,
  Settings, Trader, Markets aus MySQL zurueck.
- Verifiziert: 3 Accounts, 3 Settings, 32 Trader (23 aktiv),
  2344 Markets; Werte/AssignedAccountIds stimmen mit Exporten ueberein.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:59:39 +02:00
RichardandClaude Opus 4.8 9dbecc9514 Phase 6 (Stufe 4b): Config-Migration aus mongoexport-JSON
- ConfigMigrator.RunFromJson: importiert Accounts, Copytrading-Settings
  (Limit-Felder aus dem Alt-Account-Dokument) und Master-Trader aus
  PolyTraderDB.accounts.json / .trackers.json nach MySQL. Idempotent.
- Robuste JSON-Helfer (mongoexport: Dezimale als Strings, null moeglich).
- CLI: PolyTrader.App --migrate-json [ordner=MongoDB].
- .gitignore: MongoDB/ (Exporte enthalten Secrets) ausgeschlossen.
- Ergebnis: 3 Accounts, 3 Settings, 32 Master-Trader in MySQL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:54:07 +02:00
RichardandClaude Opus 4.8 e21a3515d1 Phase 6 (Stufe 4): einmalige Config-Migration Mongo -> MySQL
- ConfigMigrator: kopiert Accounts, aktive Markets, Master-Trader,
  Copytrading-Settings (mit Fallback auf Alt-Felder im accounts-Dokument)
  und Demo-Positionen; Historie startet leer. Idempotent via Upserts.
- Getrennte Mini-Container fuer Quelle (Mongo) und Ziel (EF/MySQL),
  unabhaengig vom Provider-Toggle.
- Aufruf: PolyTrader.App --migrate-config (kein UI-Start).
- Erstlauf: 2344 Markets migriert; Accounts/Trader/Settings in lokaler
  Mongo leer (nichts zu migrieren).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:36:36 +02:00
RichardandClaude Opus 4.8 8101b79cfb Phase 6 (Stufe 3): CopyTrading-Modul auf EF/MySQL umschaltbar
- CopyTradingDbContext (mod_copytrading_* Tabellen) + Design-Time-Factory
- EF-Repos: CopyTradeLog, AccountSettings, TrackedTrader, MasterTraderHistory
- Neue Repo-Contracts ITrackedTraderRepository + IMasterTraderHistoryRepository
  (loest die Collection-Inkonsistenz trackers/tracked_traders auf eine Quelle auf)
- Mongo-Impls der neuen Contracts (Uebergang)
- CopyTradingModule.RegisterServices: Provider-Toggle (MySql via EF / Mongo)
- StartupHydrationService + MasterTraderAnalyticsJob nutzen die Repos statt _db
- InitialCopyTrading-Migration erstellt und auf MySQL angewendet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:11:03 +02:00
RichardandClaude Opus 4.8 d8cfdbf6be Phase 6 (Stufe 2): Core-EF-Repos + umschaltbare Registrierung
- EF-Implementierungen hinter den Core-Interfaces: EfAccountRepository,
  EfMarketRepository, EfPositionRepository, EfTradeLogRepository. Thread-safe via
  IDbContextFactory<CoreDbContext> (kurzlebiger Context je Operation).
- AddCorePersistence(DatabaseOptions): Provider "MySql" -> EF + DbContextFactory,
  "Mongo" -> Mongo-Repos. Program.cs uebergibt die aufgeloesten Optionen.
- appsettings.json Provider-Default = "Mongo" (App bleibt vorerst auf MongoDB,
  kein Verhaltenswechsel). MySQL-Connection liegt in gitignorierter appsettings.Local.json.
- Build 0 Fehler.

Naechste Stufen: Modul-Context + EF-Repos (inkl. trackers/mt_history), Config-Migration
Mongo->MySQL, dann Provider umschalten + Mongo entfernen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 13:43:34 +02:00
RichardandClaude Opus 4.8 ad9bb684d4 Phase 6: Tabellen-Namenskonvention (core_ / mod_<modul>_)
- Core-Tabellen mit core_-Praefix: core_accounts, core_positions, core_markets,
  core_trade_log. CoreDbContext.ToTable angepasst, Migration neu erzeugt + angewandt.
- Modul-Tabellen erhalten spaeter mod_copytrading_-Praefix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 13:37:52 +02:00
RichardandClaude Opus 4.8 97bff61fc5 Phase 6 (Stufe 1): EF Core + MySQL Fundament (Core-Seite)
- Pomelo.EntityFrameworkCore.MySql 8.0.3 + EF Core Design im Core; DI.Abstractions
  auf 8.0.2 angehoben (Downgrade-Konflikt aufgeloest).
- DatabaseOptions: Provider (MySql|Mongo) + MySqlConnectionString (Connection liegt
  in gitignorierter appsettings.Local.json, NICHT im Repo).
- Position: AccountId + IsDemo ergaenzt (MySQL: eine positions-Tabelle statt
  Collection-per-Account).
- CoreDbContext (accounts/positions/markets/trade_log) mit Keys, Decimal-Praezision,
  NotMapped fuer Runtime-Felder, Text-Spalten fuer JSON. Design-Time-Factory (Env-Var).
- EF-Migration InitialCore erstellt UND auf die MySQL-DB angewandt (Tabellen live).

Naechste Stufen: Core-EF-Repos + DI-Umschaltung, Modul-Context (CopyTradingDbContext)
+ Repos, Config-Migration Mongo->MySQL, dann Mongo entfernen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 13:32:06 +02:00
RichardandClaude Opus 4.8 87dd9a750d Phase 5-UI: Polymarket-Accounts-Tab (allgemeine Account-Verwaltung)
- tabPage2: DataGridView (Name/Wallet/Demo/Aktiv) + Toolstrip (Neuer Account/
  Loeschen) + PropertyGrid. Da AccountState jetzt general-only ist, zeigt das
  PropertyGrid automatisch nur die allgemeinen Felder (Wallet, API-Keys, Payouts).
- SettingsView.cs: Accounts laden, Auswahl -> PropertyGrid, Bearbeiten -> speichern
  (IAccountRepository + TradingState), Neu/Loeschen.
- Program.cs: Settings-View bekommt IAccountRepository + TradingState injiziert.
- Copytrading-Detail-Limits folgen im Modul-Account-View.
- Build 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 10:35:20 +02:00
RichardandClaude Opus 4.8 095c4b64aa Phase 5: AccountState-Split (Copytrading-Limits -> Modul)
- Copytrading-Detail-Einstellungen (PerMarketLimit, MaxBuyPrice, PerMasterLimit,
  Zeit-Limits, PreRedeemLimit, ProfitTarget, MaxPriceDifference) aus dem Core-
  AccountState in das Modul-Modell CopyTradingAccountSettings verschoben.
- CopyTradingState.AccountSettings + GetAccountSettings(accountId) (Default-safe).
- Consumer umgestellt: CopyTradingEngine, TraderMonitorService, PolymarketWssClient,
  frm_main lesen die Limits jetzt aus den Account-Settings.
- Neues Modul-Repo ICopyTradingAccountSettingsRepository (Collection ct_account_settings),
  in CopyTradingModule registriert.
- StartupHydration: Settings laden + EINMALIGE Migration der Alt-Limits aus dem
  Roh-accounts-Dokument (keine konfigurierten Limits gehen verloren).
- Build 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 10:32:52 +02:00
RichardandClaude Opus 4.8 37f9d0fae2 Phase 5-UI: SettingsView an Nutzer-Redesign angepasst (TabControl + Toolstrip)
- Altes pnlTop-Panel samt btnSave/btnReload entfernt.
- Neue Toolstrip-Buttons verdrahtet: btn_save -> Speichern, btn_loadsettings -> Neu laden.
- Nutzer-Layout (TabControl: General Settings / Polymarket Accounts, toolStrip1/2,
  PropertyGrid in tabPage1) beibehalten.
- Build 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 10:23:53 +02:00