Files
PolyTraderSharp/tests/PolyTrader.Tests/DemoModelTests.cs
T
RichardandClaude Opus 4.8 54ed1a414e 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>
2026-07-07 18:49:38 +02:00

49 lines
1.8 KiB
C#

using PolyTrader.Modules.CopyTrading.Logic;
using Xunit;
using static PolyTrader.Modules.CopyTrading.Logic.DemoModel;
namespace PolyTrader.Tests
{
/// <summary>
/// Sicherheitsnetz für den realistischeren Demo-Modus (Phase 4.2): Exit-Slippage + Fees.
/// </summary>
public class DemoModelTests
{
[Fact]
public void ExitFillPrice_is_below_signal_by_half_spread()
{
Assert.Equal(0.495m, ExitFillPrice(0.50m, 0.005m));
}
[Theory]
[InlineData(0.011, 0.005, 0.01)] // Clamp Untergrenze
[InlineData(0.20, 0.30, 0.01)] // stark negativ -> Untergrenze
[InlineData(0.90, 0.005, 0.895)] // normal im Band
[InlineData(0.999, 0.005, 0.99)] // Clamp Obergrenze (0.994 -> 0.99)
public void ExitFillPrice_clamps_to_valid_range(double signal, double half, double expected)
{
Assert.Equal((decimal)expected, ExitFillPrice((decimal)signal, (decimal)half));
}
[Fact]
public void CloseWithFees_subtracts_slippage_and_roundtrip_fee()
{
// size 100, signal 0.60 -> exit 0.595, exitUsd 59.5
// fees = 1% von 50 (Entry) + 1% von 59.5 (Exit) = 0.5 + 0.595 = 1.095
// pnl = 59.5 - 50 - 1.095 = 8.405
var (exitUsd, pnl, fees) = CloseWithFees(size: 100m, signalPrice: 0.60m, entryAmountUsd: 50m, feeBps: 100, halfSpread: 0.005m);
Assert.Equal(59.5m, exitUsd);
Assert.Equal(1.095m, fees);
Assert.Equal(8.405m, pnl);
}
[Fact]
public void CloseWithFees_zero_fee_only_slippage()
{
var (exitUsd, pnl, fees) = CloseWithFees(100m, 0.60m, 50m, feeBps: 0, halfSpread: 0.005m);
Assert.Equal(0m, fees);
Assert.Equal(exitUsd - 50m, pnl);
}
}
}