diff --git a/UnitTestProject/Modules/SwapModule/SwapFixedInterestLegClosePercentBugTest.cs b/UnitTestProject/Modules/SwapModule/SwapFixedInterestLegClosePercentBugTest.cs index 774059a2..3bdd657c 100644 --- a/UnitTestProject/Modules/SwapModule/SwapFixedInterestLegClosePercentBugTest.cs +++ b/UnitTestProject/Modules/SwapModule/SwapFixedInterestLegClosePercentBugTest.cs @@ -154,6 +154,78 @@ namespace UnitTestProject.Modules.SwapModule #endregion + /// 与 CallProductionPath 相同,但允许指定平仓日期(用于两段式生命周期) + private static swap_flow_event CallWithDate(trade td, swap_position leg, decimal closePercent, DateTime closeDate) + { + var svc = new StubSvc(); + var stockEqvNotional = Notional; + var posiLongNotionalValue = Notional; + var posiShortNotionalValue = 0m; + var closePosiNotionalValue = stockEqvNotional * closePercent; + var orginPv = stockEqvNotional; + + var interests = svc.GetInterests( + td, td.trade_extend, closeDate, closeDate, + new List(), + new List { leg }, + stockEqvNotional, + posiLongNotionalValue, + posiShortNotionalValue, + closePosiNotionalValue, + closePercent, + (int)SwapEventTypeEnum.平仓, + tdClose: false, + needPrice: false, + grossPrice: 0m, + orginPv: orginPv, + add: true, + settment: false); + + Assert.AreEqual(1, interests.Count, "应返回 1 条利息腿"); + return interests[0]; + } + + #region 业务场景4-2:固定值腿 部分平仓后再全平(两段式,GLMS-债券TRS期间结算 260702「未测」缺口) + + /// + /// 覆盖「国联民生-债券TRS期间结算功能测试260702.xlsx」Sheet1 矩阵中唯一标记为「未测」的格子: + /// 业务场景4-2(固定值腿,部分平仓一次后经过数日再全平)。 + /// 同时守护 d1badfe4 的固定值腿平仓比例缩放修复—— + /// 修复前 newClosePercent=1,部分平仓利息与全平完全相同(界面改比例利息腿不变)。 + /// 本测试断言两段利息各自随平仓比例线性缩放(30% / 70%),正是该场景的回归守卫。 + /// + [DataTestMethod] + [DataRow("11")] // 算头算尾 + [DataRow("10")] // 算头不算尾 + public void 业务场景4_2_固定值腿_部分平仓后再全平_两段利息均随比例线性缩放(string calcMode) + { + var td = CreateTrade(calcMode); + var leg = CreateLeg((int)InterestModeEnum.固定值, InterestTypeEnum.单利); + + // 单步全平(100%)作为基准 + var full = CallProductionPath(td, leg, 1m); + Assert.AreNotEqual(0m, full.InterestAmount, "全平利息不应为 0,否则用例无区分度"); + + var partialDate = new DateTime(2026, 5, 11); + // 第一段:部分平仓 30%(较早日期 2026-05-11) + var i30 = CallWithDate(td, leg, 0.3m, partialDate); + // 第二段:剩余 70% 全平(到期日,算尾) + var i70 = CallWithDate(td, leg, 0.7m, Maturity); + // 各段对照「同日期全平」基准:缩放必须在相同日期范围内比较 + var fullAtPartial = CallWithDate(td, leg, 1m, partialDate); + var fullAtMaturity = CallWithDate(td, leg, 1m, Maturity); + + Console.WriteLine($"[场景4-2 mode=1 calcMode={calcMode}] 5/11全平={fullAtPartial.InterestAmount} 30%={i30.InterestAmount} 到期全平={fullAtMaturity.InterestAmount} 70%={i70.InterestAmount}"); + + // 核心断言:两段利息必须各自随平仓比例线性缩放(守护 mode-1 修复,修复前会等于全平) + Assert.AreEqual((double)(fullAtPartial.InterestAmount * 0.3m), (double)i30.InterestAmount, 0.01, + "固定值腿第一段(30%)利息应≈同日期全平×30%(修复前会等于全平,即 Bug)"); + Assert.AreEqual((double)(fullAtMaturity.InterestAmount * 0.7m), (double)i70.InterestAmount, 0.01, + "固定值腿第二段(70%)利息应≈同日期全平×70%"); + } + + #endregion + #region 对照组:标的期初全价(9) —— 正确行为,比例线性缩放 [DataTestMethod]