From adc22a5b4ca88c9da162030763471f1614ee4575 Mon Sep 17 00:00:00 2001 From: hjhan Date: Tue, 14 Jul 2026 17:21:45 +0800 Subject: [PATCH] =?UTF-8?q?refactor(swap):=20=E5=90=88=E5=B9=B6=20CalcDail?= =?UTF-8?q?ySimpleInterest=20=E9=87=8D=E7=BD=AE=E6=97=A5/=E9=9D=9E?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E6=97=A5=E9=87=8D=E5=A4=8D=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 两分支除"重置日重取浮动利率"外本金口径完全一致(都只缩放一次), 原非重置日分支是复制重置日逻辑时多写一行 tdDynomicPrincipal = flowEvent.InterestPrincipal (已含 closePercent) 导致 closePercent^N 的指数 bug。合并为单分支,仅在 i % interestPeriod == 0 时重取利率,本金处理统一为 InterestPrincipal = 基数×closePercent。 行为保持:SwapModule 全量 196 通过/4 跳过,与重构前一致。 --- .../Modules/SwapModule/SwapDealService.cs | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index 51f0ae9b..86a43b87 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -1014,36 +1014,28 @@ namespace YLErp.Modules.SwapModule if (!calcLast && accrueDate == endDate) continue; // 到期日不算尾 if (accrueDate > preEodPosition.ValueDate) { - if (i % interestPeriod == 0) + // 重置日重新获取该段浮动利率;非重置日沿用上一段利率。 + // 两分支唯一差异即"是否重取利率",本金口径(只缩放一次)完全一致, + // 合并后消除复制粘贴导致的 closePercent^N 类 bug(原非重置日分支多了一行 + // tdDynomicPrincipal = flowEvent.InterestPrincipal 使本金累积乘 closePercent^N)。 + if (i % interestPeriod == 0 && !string.IsNullOrEmpty(position.FloatRateUnderlyingCode)) { - // 获取新的浮动利率 - if (!string.IsNullOrEmpty(position.FloatRateUnderlyingCode)) + var fr007RateDate = QdpCalendarHelper.GetNonHolidayDefore(accrueDate.AddDays(position.interest_rule ?? 0)); + if (TryGetFloatRate(fr007RateDate, position.FloatRateUnderlyingCode, out double floatRate1)) { - var fr007RateDate = QdpCalendarHelper.GetNonHolidayDefore(accrueDate.AddDays(position.interest_rule ?? 0)); - if (TryGetFloatRate(fr007RateDate, position.FloatRateUnderlyingCode, out double floatRate1)) - { - if (floatRate1 != 0) floatRate = floatRate1; - } - else - { - throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fr007RateDate:yyyy年MM月dd日}的价格"); - } + if (floatRate1 != 0) floatRate = floatRate1; + } + else + { + throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fr007RateDate:yyyy年MM月dd日}的价格"); } - flowEvent.InterestPrincipal = tdDynomicPrincipal * closePercent; - TdInterestPrincipal = tdDynomicPrincipal; - } - else - { - // 单利:计息基数(tdDynomicPrincipal)逐日恒定,非重置日与重置日对本金的处理必须一致—— - // 显示本金 InterestPrincipal = 基数 × closePercent(线性,只缩放一次), - // 计息基数 TdInterestPrincipal = 基数(不缩放)。 - // 修复前此处曾写 tdDynomicPrincipal = flowEvent.InterestPrincipal(已含 closePercent), - // 使下一个非重置日再乘一次 closePercent,累积成 InterestPrincipal = Fix × closePercent^N, - // 导致部分平仓"应返还本金"被指数级缩小(50%→Fix×0.5^7、10%→Fix×0.1^7)。 - // 与日终 CalcDailySimpleInterestByEod(baseInterestPrincipal 只乘一次)对齐。 - flowEvent.InterestPrincipal = tdDynomicPrincipal * closePercent; - TdInterestPrincipal = tdDynomicPrincipal; } + + // 显示本金 = 计息基数 × closePercent(只缩放一次,与日终 ByEod 口径一致); + // 计息基数(tdDynomicPrincipal)逐日恒定、不缩放(单利特征)。 + flowEvent.InterestPrincipal = tdDynomicPrincipal * closePercent; + TdInterestPrincipal = tdDynomicPrincipal; + flowEvent.FloatRate = Convert.ToDecimal(floatRate); var interest1 = flowEvent.InterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate)); var tdinterest1 = TdInterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));