Files
zszq-trs/UnitTestProject/Modules/SwapModule/Penalty/PenaltyLegRateResolverTest.cs
T

82 lines
3.4 KiB
C#

using YLErp.DBModels.Enums;
using YLErp.Modules.SwapModule;
using YLErp.Modules.SwapModule.Accrual;
using YLErp.Modules.SwapModule.Penalty;
namespace UnitTestProject.Modules.SwapModule.Penalty
{
/// <summary>
/// EQD-6977 罚息冻结利率解析契约测试。
/// 规则(需求 2.2.2):冻结为「最后一个重置区间」定盘;终止日为重置日也取上一区间。
/// </summary>
[TestClass]
public class PenaltyLegRateResolverTest
{
private const decimal Spread = 0.05m; // +500bp
private static readonly DateTime UnwindDate = new(2026, 8, 25);
private static swap_position CreateFloatPosition(int interestRule = 0)
=> new()
{
id = 1001, SwapTradeId = 1, PosiDirection = 0,
InterestDirection = (int)SwapDirectionEnum.支付,
InterestMode = (int)InterestModeEnum.标的期初全价,
InterestRateDefault = Spread,
PosiStartDate = new DateTime(2026, 7, 31),
interest_rest_days = 7, interest_rule = interestRule,
FloatRateUnderlyingCode = "FR007",
FloatRate = 0.0185m
};
[TestMethod]
public void 浮动腿_preEod快照优先_重置日下午仍取上一区间()
{
// 8/25 为重置日且下午已出新价的边缘场景:preEod.FloatRate(昨日区间定盘)仍优先,
// 解析器不做任何取价——「终止日取上一区间」由快照语义天然覆盖。
var p = CreateFloatPosition();
var rate = PenaltyLegRateResolver.ResolveFrozenRate(
p, spread: Spread, preEodFloatRate: 0.0210m,
unwindDate: UnwindDate, tryGetFixing: _ => throw new AssertFailedException("preEod 在场时不应取价"));
Assert.AreEqual(Spread + 0.0210m, rate.AllInRate, "冻结 all-in = 利差 + 上一区间定盘");
}
[TestMethod]
public void 浮动腿_无preEod_按前一营业日取价日取定盘()
{
var p = CreateFloatPosition(interestRule: 0); // 当前营业日规则
DateTime? askedDate = null;
var rate = PenaltyLegRateResolver.ResolveFrozenRate(
p, spread: Spread, preEodFloatRate: null,
unwindDate: UnwindDate,
tryGetFixing: d => { askedDate = d; return 0.0195m; });
Assert.AreEqual(new DateTime(2026, 8, 24), askedDate, "取价日 = GetFixingDate(8/24, rule=0)");
Assert.AreEqual(Spread + 0.0195m, rate.AllInRate);
}
[TestMethod]
public void 浮动腿_无preEod_缺价抛异常()
{
var p = CreateFloatPosition();
Assert.ThrowsException<Exception>(() =>
PenaltyLegRateResolver.ResolveFrozenRate(
p, spread: Spread, preEodFloatRate: null,
unwindDate: UnwindDate, tryGetFixing: _ => null));
}
[TestMethod]
public void 固定腿_不取价_直接固定利率()
{
var p = CreateFloatPosition();
p.FloatRateUnderlyingCode = null;
var rate = PenaltyLegRateResolver.ResolveFrozenRate(
p, spread: Spread, preEodFloatRate: null,
unwindDate: UnwindDate, tryGetFixing: _ => throw new AssertFailedException("固定腿不应取价"));
Assert.AreEqual(Spread, rate.AllInRate);
}
}
}