using YLErp.Modules.EodModule.SettlementModule; namespace YLErp.Modules.EodModule { /// /// 收盘 FR007 定盘检查(EodCheckFr007Price)行为契约(纯内存,不连库): /// ① 检查日回拨:交易日 = 收盘日自身(对既有交易日收盘行为零变更); /// 周末/节假日 = 上一交易日——非交易日无 FR007 定盘,按裸收盘日检查会形成 /// "收盘必报缺价"死锁(2026-08-28:0523 周六收盘即此症); /// ② 回拨规则与计息取价同源(IndexFixerBase.GetFixingDate),检查的日期 /// 就是计息路径实际会读的日期; /// ③ 报错文案:交易日缺价保持旧格式,非交易日注明回拨,附交易编号供定位。 /// [TestClass] public class EodCheckFr007PriceTest { [TestMethod] public void 检查日_交易日收盘_等于收盘日自身() { // 2026-05-22 周五、2026-08-28 周五:正常交易日收盘,行为必须与改造前一致 Assert.AreEqual(new DateTime(2026, 5, 22), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 5, 22))); Assert.AreEqual(new DateTime(2026, 8, 28), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 8, 28))); } [TestMethod] public void 检查日_周六收盘_回拨到上一交易日周五() { // 2026-08-28 缺陷场景:0523 为周六,FR007 非发布日永无定盘行, // 旧逻辑检查裸收盘日必报"未入库"且无法通过补交易要素绕过 Assert.AreEqual(new DateTime(2026, 5, 22), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 5, 23))); } [TestMethod] public void 检查日_周日收盘_回拨跳过周末到周五() { // 与 GetInterestsUnitTest_T0 记录的取价回拨先例一致:GetNonHolidayDefore(4/26周日)→4/24周五 Assert.AreEqual(new DateTime(2026, 4, 24), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 4, 26))); } [TestMethod] public void 检查日_与计息取价日同源() { // 同一收盘日,检查日必须等于计息路径 interest_rule=0 腿实际读的取价日 var settleDate = new DateTime(2026, 5, 23); var interestPathFixingDate = YLErp.Derivatives.Interest.IndexFixerBase.GetFixingDate(settleDate, 0); Assert.AreEqual(interestPathFixingDate, EodCheckFr007Price.GetCheckDate(settleDate)); } [TestMethod] public void 报错文案_交易日缺价_格式与旧版一致() { // 交易日缺价:不带回拨说明、无交易则不带交易段,保持"yyyy年MM月dd日FR007价格未入库"原格式 var msg = EodCheckFr007Price.BuildMissingMessage(new DateTime(2026, 5, 22), new DateTime(2026, 5, 22), Array.Empty()); Assert.AreEqual("2026年05月22日FR007价格未入库", msg); } [TestMethod] public void 报错文案_非交易日回拨缺价_注明回拨() { var msg = EodCheckFr007Price.BuildMissingMessage(new DateTime(2026, 5, 23), new DateTime(2026, 5, 22), null); StringAssert.Contains(msg, "2026年05月22日FR007价格未入库"); StringAssert.Contains(msg, "收盘日2026年05月23日为非交易日,已回拨至上一交易日检查"); } [TestMethod] public void 报错文案_带交易编号供定位() { var msg = EodCheckFr007Price.BuildMissingMessage( new DateTime(2026, 5, 22), new DateTime(2026, 5, 22), new[] { "TRS-001", "TRS-002" }); StringAssert.EndsWith(msg, ";涉及FR007浮动的交易: TRS-001、TRS-002"); } [TestMethod] public void 报错文案_交易超过上限_截断并以等N笔收尾() { var trades = Enumerable.Range(1, 25).Select(i => $"TRS-{i:D3}").ToArray(); var msg = EodCheckFr007Price.BuildMissingMessage( new DateTime(2026, 5, 22), new DateTime(2026, 5, 22), trades); StringAssert.Contains(msg, $"TRS-{EodCheckFr007Price.MaxTradesInMessage:D3}"); StringAssert.Contains(msg, "等25笔"); Assert.IsFalse(msg.Contains("TRS-021"), "超过上限的交易编号不应完整列出"); Assert.IsFalse(msg.Contains("TRS-025、"), "截断后不应再拼接后续编号"); } } }