Phase 5.2: TradingState-Split (Core-State vs. CopyTradingState)

- Core TradingState (in Core): globale Schalter, Accounts, MarketCache, GlobalPnl.
- Neuer CopyTradingState (im Modul): Traders, MasterTraderPositions,
  TraderAnalyticsCache, TotalCopyTrades/GetNextTradeId, PendingOrderTimestamps,
  SixSharesMinimum.
- 10 Konsumenten umgestellt (Program, frm_main, CopyTradingEngine,
  TraderMonitor, Alchemy, WSS, Snapshot, StartupHydration, beide Analytics-Jobs):
  Modul-Felder von _state.* auf _copyState.* umgeleitet, CopyTradingState via DI.
- Rein mechanische Feld-Umleitung, keine Logikänderung. Build 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-01 20:09:50 +02:00
co-authored by Claude Opus 4.8
parent 55050a19e5
commit f8d395b2a3
13 changed files with 174 additions and 127 deletions
+17 -15
View File
@@ -15,6 +15,7 @@ namespace PolyTraderSharp
public partial class frm_main : Form
{
private readonly TradingState _tradingState;
private readonly CopyTradingState _copyState;
private readonly TerminalLogger _logger;
private readonly ThreemaService _threemaService;
private readonly MullvadVpnService _vpnService;
@@ -58,10 +59,11 @@ namespace PolyTraderSharp
private DateTimePicker _dtpClosedTrades;
private bool _terminalAutoScroll = true;
public frm_main(TradingState tradingState, TerminalLogger logger, ThreemaService threemaService, MullvadVpnService vpnService, IMongoDatabase db, PolymarketApiService api, PolymarketClobClient clob, JobManager jobManager)
public frm_main(TradingState tradingState, CopyTradingState copyState, TerminalLogger logger, ThreemaService threemaService, MullvadVpnService vpnService, IMongoDatabase db, PolymarketApiService api, PolymarketClobClient clob, JobManager jobManager)
{
InitializeComponent();
_tradingState = tradingState;
_copyState = copyState;
_logger = logger;
_threemaService = threemaService;
_vpnService = vpnService;
@@ -185,7 +187,7 @@ namespace PolyTraderSharp
int clearedCount = 0;
var validAccountIds = _tradingState.Accounts.Keys.ToList();
foreach (var trader in _tradingState.Traders.Values)
foreach (var trader in _copyState.Traders.Values)
{
var orphanedIds = trader.AssignedAccountIds.Where(id => !validAccountIds.Contains(id)).ToList();
if (orphanedIds.Count > 0)
@@ -436,13 +438,13 @@ namespace PolyTraderSharp
btn_debugorderpayload.Checked = _tradingState.DebugOrderPayloadLog;
};
btn_sixshares.Checked = _tradingState.SixSharesMinimum;
btn_sixshares.BackColor = _tradingState.SixSharesMinimum ? System.Drawing.Color.LightGreen : System.Drawing.Color.IndianRed;
btn_sixshares.Checked = _copyState.SixSharesMinimum;
btn_sixshares.BackColor = _copyState.SixSharesMinimum ? System.Drawing.Color.LightGreen : System.Drawing.Color.IndianRed;
btn_sixshares.Click += (s, ev) =>
{
_tradingState.SixSharesMinimum = !_tradingState.SixSharesMinimum;
btn_sixshares.Checked = _tradingState.SixSharesMinimum;
btn_sixshares.BackColor = _tradingState.SixSharesMinimum ? System.Drawing.Color.LightGreen : System.Drawing.Color.IndianRed;
_copyState.SixSharesMinimum = !_copyState.SixSharesMinimum;
btn_sixshares.Checked = _copyState.SixSharesMinimum;
btn_sixshares.BackColor = _copyState.SixSharesMinimum ? System.Drawing.Color.LightGreen : System.Drawing.Color.IndianRed;
};
btn_debugMTHistory.Click += async (s, ev) =>
@@ -798,7 +800,7 @@ namespace PolyTraderSharp
private void UpdateTraderAnalyticsUI(int accountId)
{
if (_tradingState.TraderAnalyticsCache.TryGetValue(accountId, out var results) && results != null)
if (_copyState.TraderAnalyticsCache.TryGetValue(accountId, out var results) && results != null)
{
// Top Traders (Positive or 0 PnL, descending)
var top = results.Where(x => x.Pnl30T >= 0).OrderByDescending(x => x.Pnl30T).ToList();
@@ -944,7 +946,7 @@ namespace PolyTraderSharp
ExitReason = t.ExitReason
};
r.AccountName = _tradingState.Accounts.TryGetValue(t.AccountId, out var a) ? a.Name : "Unknown";
if (_tradingState.Traders.TryGetValue(t.SourceTraderId, out var mt))
if (_copyState.Traders.TryGetValue(t.SourceTraderId, out var mt))
{
r.SourceTraderName = mt.DisplayName;
r.SourceTraderAddress = mt.WalletAddress;
@@ -1027,9 +1029,9 @@ namespace PolyTraderSharp
private void btn_Mastertraders_add_Click(object? sender, EventArgs e)
{
int newId = _tradingState.Traders.Count > 0 ? _tradingState.Traders.Keys.Max() + 1 : 1;
int newId = _copyState.Traders.Count > 0 ? _copyState.Traders.Keys.Max() + 1 : 1;
var newTrd = new TrackedTrader { Id = newId, DisplayName = "Neuer Master", WalletAddress = "0x..." };
_tradingState.Traders[newTrd.Id] = newTrd;
_copyState.Traders[newTrd.Id] = newTrd;
SaveTrader(newTrd);
RefreshMasterGrid();
_bsMasters.Position = _bsMasters.Count - 1;
@@ -1042,7 +1044,7 @@ namespace PolyTraderSharp
var confirm = MessageBox.Show($"Möchten Sie den Master-Trader '{trd.DisplayName}' wirklich löschen?", "Löschen bestätigen", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (confirm == DialogResult.Yes)
{
_tradingState.Traders.TryRemove(trd.Id, out _);
_copyState.Traders.TryRemove(trd.Id, out _);
_db.GetCollection<TrackedTrader>("trackers").DeleteMany(x => x.Id == trd.Id);
RefreshMasterGrid();
}
@@ -1206,7 +1208,7 @@ namespace PolyTraderSharp
private void RefreshMasterGrid()
{
var currentPos = _bsMasters.Position;
_bsMasters.DataSource = _tradingState.Traders.Values.ToList();
_bsMasters.DataSource = _copyState.Traders.Values.ToList();
_bsMasters.ResetBindings(false);
if (currentPos >= 0 && currentPos < _bsMasters.Count) _bsMasters.Position = currentPos;
}
@@ -1413,7 +1415,7 @@ namespace PolyTraderSharp
var ct = new ClosedTrade
{
TradeId = _tradingState.GetNextTradeId(),
TradeId = _copyState.GetNextTradeId(),
AccountId = account.AccountId,
IsDemo = true,
MarketSlug = openPos.MarketSlug,
@@ -1506,7 +1508,7 @@ namespace PolyTraderSharp
var ct = new ClosedTrade
{
TradeId = _tradingState.GetNextTradeId(),
TradeId = _copyState.GetNextTradeId(),
AccountId = account.AccountId,
IsDemo = false,
MarketSlug = liveOpenPos.MarketSlug,