From bf2adf0fae0909b7e3bedf0a6c55960bb593db2c Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 19 Aug 2026 10:31:54 +0800 Subject: [PATCH] =?UTF-8?q?test(swap):=20EQD-6968=20=E8=A1=A5=20EOD=20?= =?UTF-8?q?=E6=94=B6=E7=9B=98=E5=BD=92=E6=A1=A3=E5=8F=96=E4=BB=B7=E9=93=BE?= =?UTF-8?q?=E2=80=94=E2=80=94=E6=AD=A4=E5=89=8D=20settment=3Dtrue=20?= =?UTF-8?q?=E9=9B=B6=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EOD 不取尾日价靠两道闸:InitInterestDate 到期日回拨(endDate=D-1) + CalcEodInterest calcToday=false(到期日且不算尾)跳过 ByEod 重算——ByEod 的 isResetDay→ResolveFloatRate 不看 calcLast,任一环回归即到期日收盘重新索要尾日价。 - Eod_NoTail_MaturityDayFr007Missing_Succeeds:不算尾+到期日(重置日)缺价 → 放行 - Eod_Tail_MaturityDayFr007Missing_StillThrows:算尾+到期日缺价 → 仍拦 - Eod_MidTradeResetDayFr007Missing_StillThrows:非到期重置日缺价 → 仍拦 (盘中重置日新利率被持续持仓消费,ByEod 取价链是真实依赖,不算尾也不豁免) 验证:GLMS20260817Fr007UnwindMorningTest 28/28 内存全绿 --- .../GLMS20260817Fr007UnwindMorningTest.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/UnitTestProject/Modules/SwapModule/GLMS20260817Fr007UnwindMorningTest.cs b/UnitTestProject/Modules/SwapModule/GLMS20260817Fr007UnwindMorningTest.cs index a4c65c4b..57360ea2 100644 --- a/UnitTestProject/Modules/SwapModule/GLMS20260817Fr007UnwindMorningTest.cs +++ b/UnitTestProject/Modules/SwapModule/GLMS20260817Fr007UnwindMorningTest.cs @@ -452,6 +452,40 @@ namespace YLErp.Modules.SwapModule Assert.AreEqual(expectedStartDayInterest, w10.Fe.InterestAmount - w00.Fe.InterestAmount, 0.0000001m, "不算头(00)应恰好少计开始日一天利息(CalcFirst 回归锚)"); } + + // ── EOD 收盘归档路径(settment=true,此前全套件仅覆盖盘中 settment:false)── + // EOD 不取尾日价的依赖链:InitInterestDate 到期日回拨(endDate=D-1) + CalcEodInterest 的 + // calcToday=false(valueDate==到期日且不算尾) 整体跳过 ByEod 重算——ByEod 的取价 + // (CalcDailyCompoundInterestByEod/CalcDailySimpleInterestByEod 的 isResetDay→ResolveFloatRate) + // 不看 calcLast,任何一环回归都会让到期日收盘重新索要尾日 FR007。以下三例钉死该链。 + + [TestMethod] + public void Eod_NoTail_MaturityDayFr007Missing_Succeeds() + { + // 到期日=7/20(重置日)当天收盘,尾日价未发布 → 不算尾应放行(回拨+跳过重算两道闸) + AssertNoThrow(Run(InterestTypeEnum.复利, includeCloseDate: false, calcMode: "10", + exerciseDate: CloseDate, preEod: BuildPreEod(new DateTime(2026, 7, 13)), settment: true), + "EOD 不算尾(10)+到期日缺价 → 应放行(尾日不参与计息,不得取价)"); + } + + [TestMethod] + public void Eod_Tail_MaturityDayFr007Missing_StillThrows() + { + var o = Run(InterestTypeEnum.复利, includeCloseDate: false, calcMode: "11", + exerciseDate: CloseDate, preEod: BuildPreEod(new DateTime(2026, 7, 13)), settment: true); + Assert.IsTrue(o.Threw, "EOD 算尾(11)+到期日(重置日)缺价 → 应拦截(该日利率被消费)"); + StringAssert.Contains(o.Ex.Message, "FR007"); + } + + [TestMethod] + public void Eod_MidTradeResetDayFr007Missing_StillThrows() + { + // 非到期日的盘中重置日:不算尾也不豁免——新利率自当日起被持续持仓消费,ByEod 必须取到 + var o = Run(InterestTypeEnum.复利, includeCloseDate: false, calcMode: "10", + preEod: BuildPreEod(new DateTime(2026, 7, 13)), settment: true); + Assert.IsTrue(o.Threw, "EOD 不算尾(10)+非到期重置日(7/20)缺价 → 仍应拦截(ByEod 取价链,真实依赖)"); + StringAssert.Contains(o.Ex.Message, "FR007"); + } } }