Commit Graph
4 Commits
Author SHA1 Message Date
RichardandClaude Opus 5 6498a3d0ec Pause stoppt jetzt auch Verkaufsleitern und Auto-Redeem
Behebt #570.

"Trading pausieren" hielt drei Wege nicht an, die Orders am CLOB platzieren:

1. SellLadderService: Eine laufende Verkaufsleiter preiste alle 5 s weiter
   nach, storniert und neu platziert. Sie pruefte weder Pause noch Modus. Die
   Engine ignoriert bei Pause zwar alle Signale, die bereits laufende Leiter
   lief aber ungebremst.
2. TraderMonitorService: Der REST-Pre-Redeem feuert aus der
   Positions-Synchronisierung, die bewusst auch bei Pause weiterlaeuft. Er
   pruefte nur LiveTradingMode.
3. PolymarketWssClient: Die Pause wurde nur beim Verbindungsaufbau geprueft.
   Auf einer bereits offenen Verbindung loesten Kursmeldungen den Auto-Redeem
   weiter aus.

Die Ursache ist allen gemeinsam: Jeder Dienst hat seine Sperre selbst
nachgebaut, und jeder hat etwas anderes vergessen. Die Regeln liegen jetzt an
einer Stelle, in TradingGate, und alle drei benutzen sie:
- Verkaufsleiter: Pause oder Modus des Kontotyps "Inaktiv" friert sie ein,
  bei "Nur Verkauf" laeuft sie weiter. Das entspricht der Engine.
- Pre-Redeem (REST und WSS): wie bisher nur bei Modus Aktiv, jetzt zusaetzlich
  nicht bei Pause.

Eine eingefrorene Leiter storniert nichts und platziert nichts. Das gilt auch
am Floor, wenn dort die ruhende Order fehlt. Die ruhende GTC-Order bleibt am
Buch, genau wie beim Beenden der Anwendung. LastActionAt bleibt unveraendert,
nach der Freigabe geht es an der aktuellen Stufe weiter. Protokolliert wird
einmal beim Einfrieren und einmal beim Fortsetzen, nicht alle 5 s.

CLOB-kritisch, deshalb:
- Vor der Aenderung gesichert unter agentspace/scripts/backups/*.vor-570-*.bak.
- Orderaufbau und Preislogik sind nicht angefasst. Der Diff umfasst eine Sperre
  und drei Bedingungen.
- Die Sperre steht vor dem ersten CLOB-Zugriff.

Die Harness von SellLadderServiceTests setzt jetzt Live = Aktiv. Mit dem
Standard Inaktiv waere Floor_replaces_order rot geworden, und Floor_holds_...
waere gruen geblieben, aber aus dem falschen Grund: keine Order, weil
eingefroren, nicht weil die Order noch ruht.

Neu in SellLadderFreezeTests: Pause, Inaktiv, "Nur Verkauf", Floor im
eingefrorenen Zustand, Fortsetzen an der aktuellen Stufe, dazu die
Entscheidungstabellen von TradingGate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 13:55:39 +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 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 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