refactor(accrual): BuildLegRate/BuildEodPolicy移到各自类型(Phase1补完)

BuildLegRate → FundingLegRate.Build(position, spread, float) — 利率值对象的自然工厂
BuildEodPolicy → AccrualPolicy.BuildEod(position, annualDays, isCompound) — 计息政策的自然工厂

SwapDealService删除2个private static定义, 4处调用点改用类型方法
SwapModule零回归(7基线/510通过)
This commit is contained in:
hjhan
2026-08-12 16:32:04 +08:00
parent b9362ea700
commit 40756a28b3
3 changed files with 16 additions and 14 deletions
@@ -29,4 +29,8 @@ public sealed class AccrualPolicy
public AccrualPolicy(AccrualBoundary convention, bool isCompound, int resetPeriodDays, int annualDays, bool isAnnualized = false)
=> (Convention, IsCompound, ResetPeriodDays, AnnualDays, IsAnnualized) = (convention, isCompound, resetPeriodDays, annualDays, isAnnualized);
/// <summary>从 swap_position 构造 EOD 计息政策(算头算尾,重置周期取 interest_rest_days)。</summary>
public static AccrualPolicy BuildEod(DBModels.swap_position position, int annualDays, bool isCompound)
=> new(AccrualBoundary.Both, isCompound, position.interest_rest_days ?? 1, annualDays, position.IsAnnualized);
}
@@ -1,3 +1,5 @@
using YLErp.DBModels;
namespace YLErp.Modules.SwapModule.Accrual;
/// <summary>
@@ -26,4 +28,10 @@ public readonly struct FundingLegRate
/// <summary>构造浮动腿利率(all-in = 加点利差 + 指数定盘)。</summary>
public static FundingLegRate Floating(decimal spread, decimal indexFixing)
=> new(spread + indexFixing);
/// <summary>从 swap_position 构造:固定腿→Fixed(spread),浮动腿→Floating(spread+fixing)。</summary>
public static FundingLegRate Build(swap_position position, decimal spread, decimal effectiveFloat)
=> string.IsNullOrEmpty(position.FloatRateUnderlyingCode)
? Fixed(spread)
: Floating(spread, effectiveFloat);
}
+4 -14
View File
@@ -1227,16 +1227,6 @@ namespace YLErp.Modules.SwapModule
throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格");
}
/// <summary>构造利率值对象:固定腿→Fixed(spread),浮动腿→Floating(spread+fixing)。</summary>
private static FundingLegRate BuildLegRate(swap_position position, decimal spread, decimal effectiveFloat)
=> string.IsNullOrEmpty(position.FloatRateUnderlyingCode)
? FundingLegRate.Fixed(spread)
: FundingLegRate.Floating(spread, effectiveFloat);
/// <summary>构造 EOD 计息政策(算头算尾,重置周期取 position.interest_rest_days)。</summary>
private static AccrualPolicy BuildEodPolicy(swap_position position, int annualDays, bool isCompound)
=> new AccrualPolicy(AccrualBoundary.Both, isCompound, position.interest_rest_days ?? 1, annualDays, position.IsAnnualized);
/// <summary>
/// 按重置周期切分利率段,每段记录 all-in 利率(spread+fixing)。返回 (分段列表, 末段浮动利率)。
/// fetchAfterDate: 仅该日期之后的重置日才取 FR007(单利传 ValueDate,复利传 null 全程取)。
@@ -1376,8 +1366,8 @@ namespace YLErp.Modules.SwapModule
: 1m;
// 纯数学下沉至 CompoundInterestAccrual.AccrueEodDDD 命名 + 末位生产精度 12 舍入)。
var legRate = BuildLegRate(position, flowEvent.InterestRate, effectiveFloat);
var accrualPolicy = BuildEodPolicy(position, annualDays, isCompound: true);
var legRate = FundingLegRate.Build(position, flowEvent.InterestRate, effectiveFloat);
var accrualPolicy = AccrualPolicy.BuildEod(position, annualDays, isCompound: true);
// 完整计息 trace:前后日期/基数/利率/重置标志全过程,经 SwapCalcTrace 常驻落盘(关键路径日志)。
var interestTrace = new AccrualTrace();
@@ -1424,8 +1414,8 @@ namespace YLErp.Modules.SwapModule
flowEvent.FloatRate = effectiveFloat;
// 纯数学下沉至 SimpleInterestAccrual(末位生产精度 12 舍入)。
var legRate = BuildLegRate(position, flowEvent.InterestRate, effectiveFloat);
var accrualPolicy = BuildEodPolicy(position, annualDays, isCompound: false);
var legRate = FundingLegRate.Build(position, flowEvent.InterestRate, effectiveFloat);
var accrualPolicy = AccrualPolicy.BuildEod(position, annualDays, isCompound: false);
// 完整计息 trace:收集器由适配器创建,随后经 SwapCalcTrace 常驻落盘(关键路径日志,无条件)。
var interestTrace = new AccrualTrace();
var result = SimpleInterestAccrual.AccrueEod(