diff --git a/UnitTestProject/Modules/SwapModule/DealInterestsScenarioTest.cs b/UnitTestProject/Modules/SwapModule/DealInterestsScenarioTest.cs index b9dbe757..f75375be 100644 --- a/UnitTestProject/Modules/SwapModule/DealInterestsScenarioTest.cs +++ b/UnitTestProject/Modules/SwapModule/DealInterestsScenarioTest.cs @@ -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, diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index f29709fa..9eea085c 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -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; }