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>
This commit is contained in:
Richard
2026-07-03 10:32:52 +02:00
co-authored by Claude Opus 4.8
parent 37f9d0fae2
commit 095c4b64aa
11 changed files with 208 additions and 60 deletions
+5 -5
View File
@@ -183,7 +183,7 @@ namespace PolyTraderSharp.Services
pos.CurrentValueUsd = pos.Size * price;
// Execute Auto-Redeem if config conditions are met
if (acc.PreRedeemLimit > 0 && price >= acc.PreRedeemLimit && acc.IsActive)
if (_copyState.GetAccountSettings(acc.AccountId).PreRedeemLimit > 0 && price >= _copyState.GetAccountSettings(acc.AccountId).PreRedeemLimit && acc.IsActive)
{
string redeemKey = $"{acc.AccountId}_{assetId}";
// Spam protection: max 2 attempts per position, 5 minutes apart
@@ -195,13 +195,13 @@ namespace PolyTraderSharp.Services
if (!acc.IsDemo && _state.LiveTradingMode == TradingMode.Active)
{
_logger.Trade($"🚨 [AUTO REDEEM] {acc.Name} | {pos.MarketQuestion} | Preis >= {acc.PreRedeemLimit}");
_logger.Trade($"🚨 [AUTO REDEEM] {acc.Name} | {pos.MarketQuestion} | Preis >= {_copyState.GetAccountSettings(acc.AccountId).PreRedeemLimit}");
// Best effort non-blocking
_ = Task.Run(async () => await ExecuteAutoRedeemLive(acc, pos, price));
}
else if (acc.IsDemo && _state.DemoTradingMode == TradingMode.Active)
{
_logger.Trade($"🚨 [AUTO REDEEM DEMO] {acc.Name} | {pos.MarketQuestion} | Preis >= {acc.PreRedeemLimit}");
_logger.Trade($"🚨 [AUTO REDEEM DEMO] {acc.Name} | {pos.MarketQuestion} | Preis >= {_copyState.GetAccountSettings(acc.AccountId).PreRedeemLimit}");
_ = Task.Run(() => ExecuteAutoRedeemDemo(acc, pos, price));
}
}
@@ -227,7 +227,7 @@ namespace PolyTraderSharp.Services
try
{
// The user explicitly requested an exact GTC order using the configured PreRedeemLimit, without slippage
decimal expectedFillPrice = acc.PreRedeemLimit;
decimal expectedFillPrice = _copyState.GetAccountSettings(acc.AccountId).PreRedeemLimit;
decimal amountUsdc = Math.Max(pos.Size * expectedFillPrice, 0.01m);
// Fire and forget SELL via ClobClient
@@ -259,7 +259,7 @@ namespace PolyTraderSharp.Services
{
_positionRepo.DeleteDemo(acc.AccountId, pos.TokenId);
decimal exactLimitPrice = acc.PreRedeemLimit;
decimal exactLimitPrice = _copyState.GetAccountSettings(acc.AccountId).PreRedeemLimit;
decimal exitUsd = pos.Size * exactLimitPrice;
decimal realizedPnl = exitUsd - pos.AmountUsd;