Improve tests logic

This commit is contained in:
2025-11-14 03:18:11 +07:00
parent b712cf8fc3
commit 0831cf2ca0
3 changed files with 78 additions and 35 deletions

View File

@@ -591,6 +591,7 @@ public class TradingMetricsTests : TradingBoxTests
public void GetTotalFees_WithMixedStatuses_IncludesOnlyValidPositions()
{
// Arrange - Mix of positions with different statuses
// IsValidForMetrics() returns true for: Filled, Finished, Flipped
var finishedPosition1 = CreateFinishedPosition(openPrice: 50000m, quantity: 0.001m, leverage: 1m);
var finishedPosition2 = CreateFinishedPosition(openPrice: 60000m, quantity: 0.002m, leverage: 1m);
var filledPosition = CreateFilledPosition(openPrice: 40000m, quantity: 0.001m, leverage: 1m);
@@ -607,10 +608,33 @@ public class TradingMetricsTests : TradingBoxTests
// Act
var result = TradingBox.GetTotalFees(positions);
// Assert - Should include fees from finished positions only
// New positions don't have fees calculated yet
result.Should().BeGreaterThan(0);
// The exact value depends on fee calculation, but should be positive for finished positions
// Assert - Calculate expected fees for valid positions only (Finished + Filled, exclude New)
// GMX Fee Structure: UI fee (0.05%) on open + close, Gas fee ($0.15) on open
// finishedPosition1 (VALID - Finished):
// - Open: 50000 * 0.001 * 1 = 50 USD -> UI fee: 50 * 0.0005 = 0.025
// - Close (TP1): 52000 * 0.001 * 1 = 52 USD -> UI fee: 52 * 0.0005 = 0.026
// - Gas fee: 0.15
// - Total: 0.025 + 0.026 + 0.15 = 0.201
// finishedPosition2 (VALID - Finished):
// - Open: 60000 * 0.002 * 1 = 120 USD -> UI fee: 120 * 0.0005 = 0.06
// - Close (TP1): 62400 * 0.002 * 1 = 124.8 USD -> UI fee: 124.8 * 0.0005 = 0.0624
// - Gas fee: 0.15
// - Total: 0.06 + 0.0624 + 0.15 = 0.2724
// filledPosition (VALID - Filled - only open position):
// - Open: 40000 * 0.001 * 1 = 40 USD -> UI fee: 40 * 0.0005 = 0.02
// - No close yet
// - Gas fee: 0.15
// - Total: 0.02 + 0.15 = 0.17
// newPosition (EXCLUDED - New status is not valid for metrics):
// - Not counted
// Total expected: 0.201 + 0.2724 + 0.17 = 0.6434
var expectedTotalFees = 0.6434m;
result.Should().Be(expectedTotalFees);
}
[Fact]
@@ -648,7 +672,7 @@ public class TradingMetricsTests : TradingBoxTests
}
[Fact]
public void GetTotalNetPnL_WithMixedStatuses_IncludesOnlyClosedPositions()
public void GetTotalNetPnL_WithMixedStatuses_IncludesOnlyClosedAndOpenPositions()
{
// Arrange - Mix of positions with different statuses
var finishedProfit = CreateFinishedPosition();
@@ -682,13 +706,20 @@ public class TradingMetricsTests : TradingBoxTests
}
[Theory]
[InlineData(PositionStatus.New, 50)] // New positions include open volume
[InlineData(PositionStatus.Filled, 50)] // Filled positions include open volume only
[InlineData(PositionStatus.Finished, 102)] // Finished positions include open + close volume
[InlineData(PositionStatus.New, 0)] // New positions NOT valid for metrics - GetVolumeForPosition returns 0
[InlineData(PositionStatus.Filled,
50)] // Filled positions (VALID) - open trade volume only (50000 * 0.001 * 1 = 50)
[InlineData(PositionStatus.Finished, 102)] // Finished positions (VALID) - open (50) + close TP1 (52) = 102
[InlineData(PositionStatus.Canceled,
0)] // Canceled positions NOT valid for metrics - GetVolumeForPosition returns 0
[InlineData(PositionStatus.Flipped,
50)] // Flipped positions (VALID) - only open volume counted (SL/TP not filled by default)
public void GetVolumeForPosition_WithDifferentStatuses_CalculatesAppropriateVolume(PositionStatus status,
decimal expectedVolume)
{
// Arrange
// Note: GetVolumeForPosition calculates volume for ANY position
// The IsValidForMetrics() filtering happens in GetTotalVolumeTraded(), not in GetVolumeForPosition()
Position position;
switch (status)
{
@@ -701,6 +732,12 @@ public class TradingMetricsTests : TradingBoxTests
case PositionStatus.Finished:
position = CreateFinishedPosition(openPrice: 50000m, quantity: 0.001m, leverage: 1m);
break;
case PositionStatus.Canceled:
position = CreateCanceledPosition(openPrice: 50000m, quantity: 0.001m, leverage: 1m);
break;
case PositionStatus.Flipped:
position = CreateFlippedPosition(openPrice: 50000m, quantity: 0.001m, leverage: 1m);
break;
default:
throw new ArgumentException("Unsupported status for test");
}
@@ -709,6 +746,8 @@ public class TradingMetricsTests : TradingBoxTests
var result = TradingBox.GetVolumeForPosition(position);
// Assert
// GetVolumeForPosition returns volume for the position
// Filtering by IsValidForMetrics happens at a higher level (GetTotalVolumeTraded)
result.Should().Be(expectedVolume);
}

View File

@@ -919,31 +919,30 @@ public static class TradingBox
/// <returns>The total volume for the position</returns>
public static decimal GetVolumeForPosition(Position position)
{
if (!position.IsValidForMetrics())
return 0;
// Always include the opening trade volume
var totalVolume = position.Open.Price * position.Open.Quantity * position.Open.Leverage;
// For closed positions, add volume from filled closing trades
if (position.IsValidForMetrics())
// Add Stop Loss volume if filled
if (position.StopLoss?.Status == TradeStatus.Filled)
{
// Add Stop Loss volume if filled
if (position.StopLoss?.Status == TradeStatus.Filled)
{
totalVolume += position.StopLoss.Price * position.StopLoss.Quantity * position.StopLoss.Leverage;
}
totalVolume += position.StopLoss.Price * position.StopLoss.Quantity * position.StopLoss.Leverage;
}
// Add Take Profit 1 volume if filled
if (position.TakeProfit1?.Status == TradeStatus.Filled)
{
totalVolume += position.TakeProfit1.Price * position.TakeProfit1.Quantity *
position.TakeProfit1.Leverage;
}
// Add Take Profit 1 volume if filled
if (position.TakeProfit1?.Status == TradeStatus.Filled)
{
totalVolume += position.TakeProfit1.Price * position.TakeProfit1.Quantity *
position.TakeProfit1.Leverage;
}
// Add Take Profit 2 volume if filled
if (position.TakeProfit2?.Status == TradeStatus.Filled)
{
totalVolume += position.TakeProfit2.Price * position.TakeProfit2.Quantity *
position.TakeProfit2.Leverage;
}
// Add Take Profit 2 volume if filled
if (position.TakeProfit2?.Status == TradeStatus.Filled)
{
totalVolume += position.TakeProfit2.Price * position.TakeProfit2.Quantity *
position.TakeProfit2.Leverage;
}
return totalVolume;