Plattform-Fundament im Core: Vertraege, Registry, Global-Adapter (#623)
CI / Build & Tests (Linux) (push) Canceled after 0s
CI / Plattformneutralität & Hygiene (push) Canceled after 0s

Neue neutrale Handelsvertraege (Maerkte, Orderbuch, Orders, Portfolio,
Gebuehren) hinter IPlatformAdapter, aufgeloest ueber IPlatformRegistry je
Konto. Polymarket Global ist eine duenne Huelle um die bestehenden Dienste;
PolymarketClobClient bleibt unveraendert. Das Gateway lehnt ab, was die heutige
Anbindung nicht sauber kann (Post-only, IOC/GTD, falsche Plattform), bevor
etwas an den CLOB geht.

core_accounts und core_markets bekommen die Spalte Platform (Vorgabe
polymarket-global), core_markets den Schluessel (Platform, Id). core_positions
bleibt: die Plattform folgt aus dem Konto.

Noch nutzt kein Modul die Vertraege - das Handelsverhalten ist unveraendert.
Vor dem ersten Start auf dem Server: dotnet ef database update --project
src/PolyTrader.Core (Migration AddPlatformColumns).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-09-18 10:54:00 +02:00
co-authored by Claude Opus 5
parent 05979406c7
commit c863bf5fce
21 changed files with 1820 additions and 10 deletions
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using PolyTraderSharp.Models;
namespace PolyTrader.Core.Platforms
{
/// <summary>Löst den Adapter einer Plattform auf – der einzige Weg an Handelsverträge (#623).</summary>
public interface IPlatformRegistry
{
/// <summary>Plattformen, für die ein Adapter registriert ist.</summary>
IReadOnlyList<PlatformId> Available { get; }
bool IsAvailable(PlatformId platform);
/// <summary>Wirft, wenn für die Plattform kein Adapter registriert ist.</summary>
IPlatformAdapter Get(PlatformId platform);
bool TryGet(PlatformId platform, out IPlatformAdapter? adapter);
/// <summary>Adapter der Plattform, zu der das Konto gehört.</summary>
IPlatformAdapter ForAccount(AccountState account);
}
public sealed class PlatformRegistry : IPlatformRegistry
{
private readonly Dictionary<PlatformId, IPlatformAdapter> _adapters;
public PlatformRegistry(IEnumerable<IPlatformAdapter> adapters)
{
_adapters = new Dictionary<PlatformId, IPlatformAdapter>();
foreach (var adapter in adapters ?? throw new ArgumentNullException(nameof(adapters)))
{
if (!_adapters.TryAdd(adapter.Id, adapter))
throw new InvalidOperationException($"Für die Plattform '{adapter.Id}' ist mehr als ein Adapter registriert.");
}
Available = _adapters.Keys.ToList();
}
public IReadOnlyList<PlatformId> Available { get; }
public bool IsAvailable(PlatformId platform) => _adapters.ContainsKey(platform);
public IPlatformAdapter Get(PlatformId platform) =>
_adapters.TryGetValue(platform, out var adapter)
? adapter
: throw new InvalidOperationException(
$"Für die Plattform '{platform.DisplayName}' ist in dieser Installation kein Adapter vorhanden.");
public bool TryGet(PlatformId platform, out IPlatformAdapter? adapter) =>
_adapters.TryGetValue(platform, out adapter);
public IPlatformAdapter ForAccount(AccountState account) =>
Get(PlatformId.Parse((account ?? throw new ArgumentNullException(nameof(account))).Platform));
}
}