test(swap): EQD-6968 补前一营业日基准组合+算尾非重置日放行(方案一场景2/3落格)

- PrevBizDay_TailCalced×2:算尾(11)+rule=-1+当日(7/20)未发布 → 放行(取价日回拨至7/17已发布)
- PrevBizDay_NoTail:不算尾(10)+rule=-1+当日未发布 → 放行
- PrevBizDay_FixingDayMissing:rule=-1 但取价日(7/17)本身缺价 → 仍拦(真实依赖守卫)
- TailCalced_NonResetDay×2:算尾(11)+当日非重置日(7/22)+当日缺价 → 放行(非重置日不取当日价)
新增 Fr007MarketPrevBizDay 市场:重置日7/6、7/13、7/20 回拨取价日7/3、7/10、7/17

验证:GLMS20260817Fr007UnwindMorningTest 23/23 内存全绿
This commit is contained in:
hjhan
2026-08-19 09:28:27 +08:00
parent f069c38d48
commit 7cfa85a7cc
@@ -29,6 +29,14 @@ namespace YLErp.Modules.SwapModule
[new DateTime(2026, 7, 13)] = 0.01425,
[new DateTime(2026, 7, 20)] = 0.0143,
};
/// <summary>interest_rule=-1(前一营业日基准)取价日市场:重置日 7/6、7/13、7/20(周一)
/// 经 GetFixingDate 回拨至前一营业日 7/3、7/10、7/17(周五)。</summary>
private static readonly Dictionary<DateTime, double> Fr007MarketPrevBizDay = new()
{
[new DateTime(2026, 7, 3)] = 0.0142,
[new DateTime(2026, 7, 10)] = 0.01425,
[new DateTime(2026, 7, 17)] = 0.0143,
};
private const double PreviousResetRate = 0.01425;
private const decimal Notional = 279486108.21m;
@@ -344,5 +352,62 @@ namespace YLErp.Modules.SwapModule
preEod: BuildPreEod(new DateTime(2026, 7, 13))),
"不算尾(10)+本次平仓指定算尾+当日有价 → 应成功");
}
// ── 前一营业日基准(interest_rule=-1EQD-6968 方案一场景2)──
// 取价日=重置日前一营业日,当日(7/20)定盘未发布也用不到 → 放行;
// 但取价日(前一营业日)本身缺价 → 仍是真实依赖,必须拦截。
[TestMethod]
public void PrevBizDay_TailCalced_ResetDayTodayMissing_Succeeds()
{
AssertNoThrow(Run(InterestTypeEnum., includeCloseDate: true, calcMode: "11", interestRule: -1,
omitDate: CloseDate, market: Fr007MarketPrevBizDay, preEod: BuildPreEod(new DateTime(2026, 7, 13))),
"算尾(11)+前一营业日基准+当日(7/20)未发布 → 应放行(取价日7/17已发布)");
}
[TestMethod]
public void PrevBizDay_TailCalced_Simple_ResetDayTodayMissing_Succeeds()
{
AssertNoThrow(Run(InterestTypeEnum., includeCloseDate: true, calcMode: "11", interestRule: -1,
omitDate: CloseDate, market: Fr007MarketPrevBizDay, preEod: BuildPreEod(new DateTime(2026, 7, 13))),
"单利 算尾(11)+前一营业日基准+当日未发布 → 应放行");
}
[TestMethod]
public void PrevBizDay_NoTail_ResetDayTodayMissing_Succeeds()
{
AssertNoThrow(Run(InterestTypeEnum., includeCloseDate: true, interestRule: -1,
omitDate: CloseDate, market: Fr007MarketPrevBizDay, preEod: BuildPreEod(new DateTime(2026, 7, 13))),
"不算尾(10)+前一营业日基准+当日未发布 → 应放行");
}
[TestMethod]
public void PrevBizDay_TailCalced_FixingDayMissing_StillThrows()
{
var o = Run(InterestTypeEnum., includeCloseDate: true, calcMode: "11", interestRule: -1,
omitDate: new DateTime(2026, 7, 17), market: Fr007MarketPrevBizDay,
preEod: BuildPreEod(new DateTime(2026, 7, 13)));
Assert.IsTrue(o.Threw, "算尾(11)+前一营业日基准+取价日(7/17)本身缺价 → 仍应拦截(真实依赖)");
StringAssert.Contains(o.Ex.Message, "FR007");
}
// ── 算尾+当前营业日+当日非重置日(EQD-6968 方案一场景3)──
// 当日价未被任何计息段消费(末段重置日7/20是历史日),当日(7/22)缺价 → 放行。
[TestMethod]
public void TailCalced_NonResetDay_TodayMissing_Succeeds()
{
AssertNoThrow(Run(InterestTypeEnum., includeCloseDate: true, calcMode: "11", closeDate: NonIntCloseDate,
preEod: BuildPreEod(new DateTime(2026, 7, 13))),
"算尾(11)+当日非重置日+当日(7/22)缺价 → 应放行(非重置日不取当日价)");
}
[TestMethod]
public void TailCalced_NonResetDay_Simple_TodayMissing_Succeeds()
{
AssertNoThrow(Run(InterestTypeEnum., includeCloseDate: true, calcMode: "11", closeDate: NonIntCloseDate,
preEod: BuildPreEod(new DateTime(2026, 7, 13))),
"单利 算尾(11)+当日非重置日+当日缺价 → 应放行");
}
}
}