Files
zszq-trs/YLErpDAL/Modules/SwapModule/Fr007IndexFixer.cs
T
hjhan 250c41b925 refactor(interest): 抽取 IIndexFixer 取价接缝 + 清理固定值腿错误测试
为后续拆三类腿做准备,新增 FR007 取价的独立接口层(参考 QuantLib IborIndex
分层),本次零生产代码改动,全部为新增小文件。

新增文件(取价接缝,供后续 SwapDealService 6 处 inline 取价迁移用):
- Framework/YLErp.Core/Interest/IIndexFixer.cs
  接口定义:给定取价日和标的代码返回当日利率,取价与计息解耦
- Framework/YLErp.Core/Interest/IndexFixerBase.cs
  取价日计算工具:收敛原散落 6 处的 GetNonHolidayDefore(date.AddDays(rule))
- YLErpDAL/Modules/SwapModule/Fr007IndexFixer.cs
  生产实现 + GetFixingOrThrow 辅助方法,独立文件便于单测

测试清理(删除基于错误假设的测试):
- 删除 SwapFixedInterestLegClosePercentBugTest.cs 整个文件
  该文件假设'固定值腿利息应随平仓比例线性缩放',但固定值是合同写死的、
  永远不随平仓比例变化。d1badfe4 的'修复'本身才是错的,当前分支已正确回退
- 修正 SwapUnwindPrepayPrincipalBugTdd.cs 固定值测试方法
  断言从'应=Fix×0.5'改为'恒=Fix不随比例变化',对齐正确的业务定义

已知失败(非本次引入,留待后续与拆腿一起修):
- BondTrsAutoSwapScenarioTest 的 AS_001/004/008/009/010/011 共 6 个
  原因:SaveAutoSwapDeal 直接调 AddClientCashInCashOut(非virtual)绕过
  AddClientCash(virtual)封装,无库环境抛'客户信息未找到'。
  从 096d2609 引入时即失败,需 AddClientCashInCashOut 加 virtual + 客户数据
  mock,与拆腿那次可测性改造一起做
2026-08-10 18:01:37 +08:00

37 lines
1.6 KiB
C#

using System;
using YLErp.Derivatives.Interest;
using YLErp.Modules.DataProviderModule;
namespace YLErp.Modules.SwapModule;
/// <summary>
/// IIndexFixer 的生产实现:FR007 等浮动利率取价。
/// 直接调用 EodPriceQueryService.TryGetPrice,不依赖 SwapDealService 实例,便于独立测试。
/// 未来 SwapDealService 的 6 处 inline 取价代码迁移到本类后,取价规则只在此一处维护。
/// </summary>
public sealed class Fr007IndexFixer : IndexFixerBase, IIndexFixer
{
public static readonly Fr007IndexFixer Instance = new();
public bool TryGetFixing(DateTime fixingDate, string underlyingCode, out decimal rate)
{
bool ok = EodPriceQueryService.TryGetPrice(fixingDate, underlyingCode, out double r);
rate = Convert.ToDecimal(r);
return ok;
}
/// <summary>
/// 取价日 → 取价 → 取不到抛异常。等价于原 SwapDealService 里散落 6 处的 inline 代码:
/// GetNonHolidayDefore(date.AddDays(rule)) + TryGetFloatRate + throw
/// 取到 0 视为"取到一个 0 值"(返回 0),由调用方决定是否沿用旧值;
/// 只有 TryGetFixing 返回 false 才抛异常——对齐既有语义。
/// </summary>
public decimal GetFixingOrThrow(DateTime resetDate, int? interestRule, string underlyingCode)
{
var fixingDate = GetFixingDate(resetDate, interestRule ?? 0);
if (TryGetFixing(fixingDate, underlyingCode, out decimal rate))
return rate;
throw new Exception($"获取不到{underlyingCode}在{fixingDate:yyyy年MM月dd日}的价格");
}
}