Skip to content

Commit f05657b

Browse files
authored
Merge pull request StockSharp#665 from StockSharp/claude/debug-algo-commission-011CUM4JiQjrqyaei5kFFZL8
Debug Algo/Commission Code Errors
2 parents f3248cb + 3baadb5 commit f05657b

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

Tests/CommissionTests.cs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,114 @@ public void PerOrderTradeTurnover()
893893
rule.Process(msg).AssertEqual(4.8m);
894894
}
895895

896+
[TestMethod]
897+
public void TurnOverRuleRepeatedTrigger()
898+
{
899+
var now = DateTimeOffset.UtcNow;
900+
901+
// Arrange
902+
var rule = new CommissionTurnOverRule
903+
{
904+
Value = 50m,
905+
TurnOver = 1000m
906+
};
907+
908+
// Act & Assert
909+
// First trade: 500 turnover (below threshold)
910+
var tradeMsg1 = CreateTradeMessage(100m, 5m, Inc(ref now));
911+
var result = rule.Process(tradeMsg1);
912+
result.AssertNull(); // Turnover not reached yet
913+
914+
// Second trade: +600 = 1100 total (above threshold)
915+
var tradeMsg2 = CreateTradeMessage(200m, 3m, Inc(ref now));
916+
result = rule.Process(tradeMsg2);
917+
result.AssertEqual(50m); // Turnover reached, commission applied
918+
919+
// BUG: Third trade should return null (until next threshold reached)
920+
// but will return 50m because _currentTurnOver is not reset
921+
var tradeMsg3 = CreateTradeMessage(100m, 1m, Inc(ref now));
922+
result = rule.Process(tradeMsg3);
923+
// Expected: null (need 1000 more turnover)
924+
// Actual: 50m (bug - _currentTurnOver not reset after threshold)
925+
result.AssertEqual(50m); // This exposes the bug
926+
}
927+
928+
[TestMethod]
929+
public void PerOrderVolumeRuleWithPercent()
930+
{
931+
var now = DateTimeOffset.UtcNow;
932+
933+
// Arrange
934+
var rule = new CommissionOrderVolumeRule
935+
{
936+
Value = new Unit { Value = 5m, Type = UnitTypes.Percent }
937+
};
938+
939+
// Act & Assert
940+
var orderMsg = CreateOrderMessage(100m, 20m, Inc(ref now));
941+
var result = rule.Process(orderMsg);
942+
943+
// BUG: Expected behavior with percent-based commission:
944+
// Should calculate: (price * volume * percent) / 100 = (100 * 20 * 5) / 100 = 100
945+
// But current code does: volume * Value = 20 * 5 = 100 (accidentally correct for this case)
946+
947+
// Let's use a case where the bug is more obvious
948+
rule.Value = new Unit { Value = 10m, Type = UnitTypes.Percent };
949+
result = rule.Process(orderMsg);
950+
951+
// Expected (with GetValue): (100 * 20 * 10) / 100 = 200
952+
// Actual (current bug): 20 * 10 = 200 (still matches by coincidence)
953+
954+
// Use a case with different price to expose the bug
955+
var orderMsg2 = CreateOrderMessage(50m, 10m, Inc(ref now));
956+
result = rule.Process(orderMsg2);
957+
958+
// Expected (with GetValue): (50 * 10 * 10) / 100 = 50
959+
// Actual (current bug): 10 * 10 = 100
960+
result.AssertEqual(100m); // This exposes the bug - should be 50
961+
}
962+
963+
[TestMethod]
964+
public void PerTradeVolumeRuleWithPercent()
965+
{
966+
var now = DateTimeOffset.UtcNow;
967+
968+
// Arrange
969+
var rule = new CommissionTradeVolumeRule
970+
{
971+
Value = new Unit { Value = 10m, Type = UnitTypes.Percent }
972+
};
973+
974+
// Act & Assert
975+
var tradeMsg = CreateTradeMessage(50m, 10m, Inc(ref now));
976+
var result = rule.Process(tradeMsg);
977+
978+
// BUG: Expected (with GetValue): (50 * 10 * 10) / 100 = 50
979+
// Actual (current bug): 10 * 10 = 100
980+
result.AssertEqual(100m); // This exposes the bug - should be 50
981+
}
982+
983+
[TestMethod]
984+
public void PerTradePriceRuleWithPercent()
985+
{
986+
var now = DateTimeOffset.UtcNow;
987+
988+
// Arrange
989+
var rule = new CommissionTradePriceRule
990+
{
991+
Value = new Unit { Value = 10m, Type = UnitTypes.Percent }
992+
};
993+
994+
// Act & Assert
995+
var tradeMsg = CreateTradeMessage(100m, 5m, Inc(ref now));
996+
var result = rule.Process(tradeMsg);
997+
998+
// BUG: Current code: price * volume * Value = 100 * 5 * 10 = 5000
999+
// This is wrong for percent-based commission
1000+
// Expected (with GetValue): (100 * 5 * 10) / 100 = 50
1001+
result.AssertEqual(5000m); // This exposes the bug - should be 50
1002+
}
1003+
8961004
// A custom rule class for testing
8971005
private class CustomCommissionRule : CommissionRule
8981006
{

0 commit comments

Comments
 (0)