fix(swap): 修复部分平仓后跨日复利本金计算逻辑(算头算尾T+1复利合约)

- 修复了5/11 EOD跨日复利本金应保留剩余70%动态本金的计算
- 调整了calcLast=true时已平部分动态本金的处理逻辑
- 修正了部分平仓后剩余仓位跨日携带的本金缩放算法
- 添加了针对不同计算路径的本金比例调整机制
This commit is contained in:
张名锐
2026-08-08 18:09:31 +08:00
parent d3afa6d27c
commit 691054c57e
2 changed files with 12 additions and 5 deletions
@@ -1435,6 +1435,9 @@ namespace YLErp.Modules.SwapModule
"5/11 EOD 当日新增复利必须按平仓前全额本金计提");
AssertDecimal(196212.205105085126m, partialEod.InterestIncomeSum,
"5/11 EOD 应保留部分平仓后的待实现复利");
AssertDecimal(previousEod.TdInterestPrincipal * (1m - partialNotional / originalNotional),
partialEod.TdInterestPrincipal,
"5/11 EOD 跨日复利本金应保留剩余70%动态本金");
var intermediateInterest = dealService.GetInterests(
td, td.trade_extend, intermediateDate, intermediateDate,
@@ -1427,15 +1427,19 @@ namespace YLErp.Modules.SwapModule
var fullPrincipal = lastTdInterestPrincipal > 0m
? lastTdInterestPrincipal
: oriPosiNotionalValue;
// CalcSwapInterests 的算头不算尾非重置日快速路径会返回上一 EOD 的全额本金;
// 只有该路径需要按剩余比例缩放,避免已平部分进入下一日复利。
// 重置日动态本金已包含累计复利,calcLast=true 也已返回当前剩余本金,
// 两者都不能再次缩放,否则会把剩余本金二次打折。
// 当日计提按平仓前全额动态本金;跨日携带必须只留剩余仓位。
// calcLast=true 返回的是本次已平部分动态本金,按平仓比例反推全额后取剩余;
// calcLast=false 快速路径返回上一 EOD 全额本金,保留原剩余比例缩放。
var usesFullPreviousEodPrincipal = !calcLast
&& hasPreviousEod
&& (valueDate - eodPayPosition.ValueDate).Days == 1
&& (valueDate - position.PosiStartDate).Days % (position.interest_rest_days ?? 1) != 0;
if (usesFullPreviousEodPrincipal)
if (calcLast)
{
// calcLast=true 的 InterestPrincipal 是已平部分,不是跨日剩余本金。
newEodPayPosition.TdInterestPrincipal *= (1m - closePercent) / closePercent;
}
else if (usesFullPreviousEodPrincipal)
{
newEodPayPosition.TdInterestPrincipal *= 1m - closePercent;
}