Files
PolyTraderSharp/src/PolyTrader.Modules.CopyTrading/Logic/DemoModel.cs
T
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

42 lines
1.9 KiB
C#

using System;
using PolyTrader.Core.Trading;
namespace PolyTrader.Modules.CopyTrading.Logic
{
/// <summary>
/// Reine Logik für einen realistischeren Demo-Modus (Phase 4.2). Demo füllte bisher zum
/// Signalpreis ohne Slippage/Fees → Ergebnisse systematisch geschönt und als Validierung
/// neuer Master unbrauchbar. Hier: Exit-Fill mit halbem Spread + Fees (aus <see cref="FeeModel"/>),
/// damit Demo- und Live-PnL grob vergleichbar werden.
/// </summary>
public static class DemoModel
{
/// <summary>Fallback-Halbspread (¢), wenn kein Orderbuch verfügbar ist (Phase 1.2).</summary>
public const decimal FallbackHalfSpread = 0.005m;
/// <summary>
/// Simulierter SELL-Fill-Preis im Demo: der Verkäufer trifft den Bid, also unter dem
/// Signalpreis um den halben Spread. Auf [0.01, 0.99] geclamped.
/// </summary>
public static decimal ExitFillPrice(decimal signalPrice, decimal halfSpread)
{
decimal p = signalPrice - halfSpread;
return Math.Clamp(p, 0.01m, 0.99m);
}
/// <summary>
/// Realistischer Demo-Close: Erlös zum (leicht schlechteren) Fill-Preis, minus Round-Trip-Fee
/// (Entry- und Exit-Leg). Liefert (exitUsd, realizedPnl, totalFees).
/// </summary>
public static (decimal exitUsd, decimal realizedPnl, decimal totalFees) CloseWithFees(
decimal size, decimal signalPrice, decimal entryAmountUsd, int feeBps, decimal halfSpread)
{
decimal exitPrice = ExitFillPrice(signalPrice, halfSpread);
decimal exitUsd = size * exitPrice;
decimal totalFees = FeeModel.FeeUsd(entryAmountUsd, feeBps) + FeeModel.FeeUsd(exitUsd, feeBps);
decimal realizedPnl = exitUsd - entryAmountUsd - totalFees;
return (exitUsd, realizedPnl, totalFees);
}
}
}