Phase 4.2 / 0.2: realistischer Demo-Modus (Exit-Slippage + Fees)
- DemoModel (pure, getestet): ExitFillPrice (Signalpreis minus halber Spread, geclamped) + CloseWithFees (Erlös zum Fill-Preis minus Round-Trip-Fee). - CopyTradingEngine Demo-Close nutzt es: ExitPrice = realistischer Fill statt Signalpreis, RealizedPnl netto nach Fees, ClosedTrade.TotalFees befuellt. -> Demo-PnL ist nicht mehr systematisch geschoent (Master-Validierung brauchbar). - DemoModelTests (Fill-Clamping, Round-Trip-Fee, 0-Fee). 207 Tests gruen. Build/Smoke gruen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b259f310d3
commit
54ed1a414e
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user