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>
This commit is contained in:
Richard
2026-07-09 14:03:00 +02:00
co-authored by Claude Opus 4.8
parent 8252219163
commit bdcd3641e4
14 changed files with 148 additions and 22 deletions
@@ -542,7 +542,11 @@ namespace PolyTraderSharp.Services
// Maker-Einstieg (Phase 4.1) ruht als GTC-Limit; sonst GTD (Taker-nah).
string buyOrderType = (trader != null && trader.MakerEntry) ? "GTC" : "GTD";
var result = await _clob.PlaceOrderAsync(account, signal.TokenId, signal.Side, exactUsdc, orderPrice, buyOrderType, _state.DebugOrderPayloadLog, isNegRisk);
// M6: realen Taker-Satz (bzw. Kategorie-Fallback) in die signierte Order schreiben.
int buyFeeBps = _state.MarketCache.TryGetValue(signal.TokenId, out var buyMd)
? FeeModel.ResolveBps(buyMd.TakerFeeBps, buyMd.Category)
: FeeModel.FallbackBps(null);
var result = await _clob.PlaceOrderAsync(account, signal.TokenId, signal.Side, exactUsdc, orderPrice, buyOrderType, _state.DebugOrderPayloadLog, isNegRisk, buyFeeBps);
if (result == "OK")
{