From bfa230381b140cf4e521dea63a575a8aec1028e5 Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 12 Aug 2026 14:01:24 +0800 Subject: [PATCH] =?UTF-8?q?refactor(accrual):=20=E6=8F=90=E5=8F=96BuildLeg?= =?UTF-8?q?Rate/BuildEodPolicy=E6=B6=88=E9=99=A4EOD=20wrapper=E6=9E=84?= =?UTF-8?q?=E9=80=A0=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EOD CompoundEod + SimpleEod 各有一份相同的FundingLegRate构造(3行) 和AccrualPolicy构造(5行), 共16行重复。 提取为: - BuildLegRate(position, spread, effectiveFloat): 固定腿→Fixed, 浮动腿→Floating - BuildEodPolicy(position, annualDays, isCompound): 算头算尾+重置周期 每个EOD wrapper从10行构造代码→2行调用, 净减12行 SwapModule零回归(7基线/510通过) --- .../Modules/SwapModule/SwapDealService.cs | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index f8a778c3..87b1dc08 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -1339,6 +1339,16 @@ namespace YLErp.Modules.SwapModule throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格"); } + /// 构造利率值对象:固定腿→Fixed(spread),浮动腿→Floating(spread+fixing)。 + private static FundingLegRate BuildLegRate(swap_position position, decimal spread, decimal effectiveFloat) + => string.IsNullOrEmpty(position.FloatRateUnderlyingCode) + ? FundingLegRate.Fixed(spread) + : FundingLegRate.Floating(spread, effectiveFloat); + + /// 构造 EOD 计息政策(算头算尾,重置周期取 position.interest_rest_days)。 + private static AccrualPolicy BuildEodPolicy(swap_position position, int annualDays, bool isCompound) + => new AccrualPolicy(AccrualBoundary.Both, isCompound, position.interest_rest_days ?? 1, annualDays, position.IsAnnualized); + /// /// 按重置周期切分利率段,每段记录 all-in 利率(spread+fixing)。返回 (分段列表, 末段浮动利率)。 /// fetchAfterDate: 仅该日期之后的重置日才取 FR007(单利传 ValueDate,复利传 null 全程取)。 @@ -1478,16 +1488,8 @@ namespace YLErp.Modules.SwapModule : 1m; // 纯数学下沉至 CompoundInterestAccrual.AccrueEod(DDD 命名 + 末位生产精度 12 舍入)。 - var isFixedLeg = string.IsNullOrEmpty(position.FloatRateUnderlyingCode); - var legRate = isFixedLeg - ? FundingLegRate.Fixed(flowEvent.InterestRate) - : FundingLegRate.Floating(flowEvent.InterestRate, effectiveFloat); - var accrualPolicy = new AccrualPolicy( - convention: AccrualBoundary.Both, - isCompound: true, - resetPeriodDays: interestPeriod, - annualDays: annualDays, - isAnnualized: position.IsAnnualized); + var legRate = BuildLegRate(position, flowEvent.InterestRate, effectiveFloat); + var accrualPolicy = BuildEodPolicy(position, annualDays, isCompound: true); // 完整计息 trace:前后日期/基数/利率/重置标志全过程,经 SwapCalcTrace 常驻落盘(关键路径日志)。 var interestTrace = new AccrualTrace(); @@ -1533,18 +1535,9 @@ namespace YLErp.Modules.SwapModule flowEvent.FloatRate = effectiveFloat; - // 纯数学下沉至 SimpleInterestAccrual(DDD 命名 + 末位生产精度 12 舍入),行为与上版逐字对齐。 - // 利率构成按腿型封装:固定腿 → FixedRate;浮动腿 → Spread + IndexFixing(沿用旧实现 InterestRate+浮动利率 的口径)。 - var isFixedLeg = string.IsNullOrEmpty(position.FloatRateUnderlyingCode); - var legRate = isFixedLeg - ? FundingLegRate.Fixed(flowEvent.InterestRate) - : FundingLegRate.Floating(flowEvent.InterestRate, effectiveFloat); - var accrualPolicy = new AccrualPolicy( - convention: AccrualBoundary.Both, - isCompound: false, - resetPeriodDays: position.interest_rest_days ?? 1, - annualDays: annualDays, - isAnnualized: position.IsAnnualized); + // 纯数学下沉至 SimpleInterestAccrual(末位生产精度 12 舍入)。 + var legRate = BuildLegRate(position, flowEvent.InterestRate, effectiveFloat); + var accrualPolicy = BuildEodPolicy(position, annualDays, isCompound: false); // 完整计息 trace:收集器由适配器创建,随后经 SwapCalcTrace 常驻落盘(关键路径日志,无条件)。 var interestTrace = new AccrualTrace(); var result = SimpleInterestAccrual.AccrueEod(