Files
zszq-trs/UnitTestProject/Modules/SwapModule/Accrual/TdCarryInCharacterizationTest.cs
T
hjhan f1f7cae832 refactor(accrual): 抽取BuildSegmentRates共享分段取率+清理needPrice死参数
- 抽取 BuildSegmentRates:统一单利/复利分段取率循环,参数化 fetchAfterDate (单利传 ValueDate 仅取新段,复利传 null 全程取)

- 修复 BuildSegmentRates static→instance:访问实例属性 IndexFixer

- 清理 CalcDaily 层 needPrice 死参数:4个 CalcDaily* 方法签名移除 needPrice;上层 CalcSwapInterests/GetInterests 保留 (virtual seam/位置参数兼容)

- 修复 6 处调用点 needPrice 参数传递

- 新增影子测试:单利+FR007浮动+部分平仓+历史归档,验证 segmentRates 一致

- 新增 TdCarryInCharacterizationTest:钉死部分平仓 TdInterestAmount carry-in 行为

测试: 511通过 / 7预存在失败(数据依赖) / 9跳过
2026-08-12 18:02:36 +08:00

67 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using YLErp.Derivatives.Interest; // InterestResult, AccrualBoundary, SwapInterest
using YLErp.Modules.SwapModule.Accrual; // SimpleInterestAccrual
namespace UnitTestProject.Modules.SwapModule.Accrual
{
/// <summary>
/// 性格化测试:部分平仓时 TdInterestAmount 的 carry-in 是否被错误缩放。
/// 调用真实纯函数 SimpleInterestAccrual.AccruePeriod,参数与线上 SwapDealService.cs:1290 完全一致
/// priorAccrued = InterestProfitSum * closePercent)。先钉死“当前行为”,修复后再改断言。
/// </summary>
[TestClass]
public class TdCarryInCharacterizationTest
{
[TestMethod]
public void 部分平仓_历史累计利息_carryIn被缩放_复现当前行为()
{
// ── 例子(教学用整数,非市场真实利率)──
// 昨日(上一EOD)全腿累计利息 InterestProfitSum = 100(不缩放口径,下游 EOD :1300/:1370 当累计用)
// 今日部分平仓 closePercent = 0.3(平 30%
// 计息基数 notional = 1000(全腿)
// 单段、年化=false、利率 0.10、区间 1 天 → 今日未缩放增量 = 1000*0.10*1 = 100
decimal interestProfitSum = 100m;
decimal closePercent = 0.3m;
decimal notional = 1000m;
var segmentRates = new List<(DateTime, decimal)> { (new DateTime(2026, 6, 1), 0.10m) };
var startDate = new DateTime(2026, 6, 1);
var endDate = new DateTime(2026, 6, 2); // 区间 1 天(StartOnly 边界 → days=1
var priorValueDate = new DateTime(2026, 5, 31);
var boundary = AccrualBoundary.StartOnly;
// 线上真实调用(SwapDealService.cs:1290):priorAccrued = InterestProfitSum * closePercent
var result = SimpleInterestAccrual.AccruePeriod(
priorAccrued: interestProfitSum * closePercent, // = 30 ← 已缩放
notional: notional,
unwindFraction: closePercent,
segmentRates: segmentRates,
startDate: startDate,
endDate: endDate,
priorValueDate: priorValueDate,
boundary: boundary,
annualDays: 365,
isAnnualized: false);
Console.WriteLine("==== 当前代码(buggy)实际输出 ====");
Console.WriteLine($"InterestAmount (Accrued) = {result.Accrued}");
Console.WriteLine($"TdInterestAmount (AccruedToday) = {result.AccruedToday}");
// ── 推演(当前代码)──
// InterestAmount = 30 + 300*0.10*1(=30) = 60 (缩放累计,正确)
// TdInterestAmount= 30 + 1000*0.10*1(=100) = 130 ← 应为 200
// 差距 = 100*(1-0.3) = 70,即历史累计被砍掉的那一截。
Assert.AreEqual(60m, result.Accrued);
Assert.AreEqual(130m, result.AccruedToday); // 当前 buggy 值,先钉死现状
// ── 期望值(修复后)──
// TdInterestAmount 应为:InterestProfitSum(100, 不缩放) + 今日未缩放增量(100) = 200
// 修复 = SwapDealService.cs:1290 改传 InterestProfitSum(去 *closePercent
// + SimpleInterestAccrual.cs:68 accrued = priorAccrued * unwindFraction
// 修复后 InterestAmount 仍 = 60(不变,正确),TdInterestAmount = 200。
}
}
}