fix(swap): 修复部分平仓后算尾利息计算问题(算头算尾T+0合约单利)

- 将测试方法改为数据驱动测试以覆盖不同利息模式
- 在测试中添加对不同利息模式的验证逻辑
- 修复平仓后EOD本金只携带剩余持仓的计算逻辑
- 添加对算尾部分平仓后EOD本金的断言验证
- 优化单利算尾当日按平仓前全额计提的处理逻辑
This commit is contained in:
张名锐
2026-08-09 13:42:59 +08:00
parent 691054c57e
commit 7528670e8b
2 changed files with 17 additions and 2 deletions
@@ -864,8 +864,10 @@ namespace YLErp.Modules.SwapModule
"预付金部分平仓待实现收益应为历史待实现+平仓后当日新增-平仓实现");
}
[TestMethod]
public void DI_MANUAL_PARTIAL_CLOSE_CalcLastIncludesClosedPrincipalDailyInterest()
[DataTestMethod]
[DataRow((int)InterestModeEnum.合约名义本金规模)]
[DataRow((int)InterestModeEnum.标的期初全价)]
public void DI_MANUAL_PARTIAL_CLOSE_CalcLastIncludesClosedPrincipalDailyInterest(int interestMode)
{
var service = new StubEodPositionService();
var td = CreateTrade();
@@ -876,6 +878,7 @@ namespace YLErp.Modules.SwapModule
SettlementRules = 0
});
var position = CreateInterestPosition();
position.InterestMode = interestMode;
var previousEod = CreatePreEod(StartDate.AddDays(2), 100m);
previousEod.TdInterestPrincipal = Principal;
var closeFlow = CreateSwapFlowEvent(StartDate.AddDays(3), 50m);
@@ -887,6 +890,8 @@ namespace YLErp.Modules.SwapModule
AssertDecimal(Principal * FixedRate / AnnualDays, result.TdInterestIncome,
"算尾部分平仓的当日新计利息应包含已平仓部分(按全额本金计提)");
AssertDecimal(500m, result.TdInterestPrincipal,
"算尾部分平仓后的 EOD 本金应只携带剩余持仓");
// 补充:算尾部分平仓的待实现利息总额应满足递推
// InterestIncomeSum = 前日待实现 + 当日新计(全额本金,含被平仓部分) - 当日实现
@@ -1453,6 +1453,16 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition.TdInterestIncome /= tradeExtend.AnnualDays;
}
}
if (!autoSwap
&& closePercent > 0m && closePercent < 1m
&& posiNotionalValue > 0m
&& position.InterestType == (int)InterestTypeEnum.
&& (position.InterestMode == (int)InterestModeEnum.
|| position.InterestMode == (int)InterestModeEnum.))
{
// 单利算尾当日仍按平仓前全额计提,跨日 EOD 本金只携带剩余持仓。
newEodPayPosition.TdInterestPrincipal = posiNotionalValue;
}
Log.Info($"InterestIncomeSum is {lastInterestIncomeSum},TdInterestIncome is {newEodPayPosition.TdInterestIncome}" +
$",TdCloseInterest is {newEodPayPosition.TdCloseInterest}");
Log.Info($"InterestFeeSum is {eodPayPosition.InterestFeeSum},TdInterestFee is {newEodPayPosition.TdInterestFee}" +