diff --git a/YLErpDAL/Modules/SwapModule/Accrual/AccrualPolicy.cs b/YLErpDAL/Modules/SwapModule/Accrual/AccrualPolicy.cs
index 34b2a1f7..9f7e4ec4 100644
--- a/YLErpDAL/Modules/SwapModule/Accrual/AccrualPolicy.cs
+++ b/YLErpDAL/Modules/SwapModule/Accrual/AccrualPolicy.cs
@@ -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);
+
+ /// 从 swap_position 构造 EOD 计息政策(算头算尾,重置周期取 interest_rest_days)。
+ public static AccrualPolicy BuildEod(DBModels.swap_position position, int annualDays, bool isCompound)
+ => new(AccrualBoundary.Both, isCompound, position.interest_rest_days ?? 1, annualDays, position.IsAnnualized);
}
diff --git a/YLErpDAL/Modules/SwapModule/Accrual/FundingLegRate.cs b/YLErpDAL/Modules/SwapModule/Accrual/FundingLegRate.cs
index 6240eae6..731860e4 100644
--- a/YLErpDAL/Modules/SwapModule/Accrual/FundingLegRate.cs
+++ b/YLErpDAL/Modules/SwapModule/Accrual/FundingLegRate.cs
@@ -1,3 +1,5 @@
+using YLErp.DBModels;
+
namespace YLErp.Modules.SwapModule.Accrual;
///
@@ -26,4 +28,10 @@ public readonly struct FundingLegRate
/// 构造浮动腿利率(all-in = 加点利差 + 指数定盘)。
public static FundingLegRate Floating(decimal spread, decimal indexFixing)
=> new(spread + indexFixing);
+
+ /// 从 swap_position 构造:固定腿→Fixed(spread),浮动腿→Floating(spread+fixing)。
+ public static FundingLegRate Build(swap_position position, decimal spread, decimal effectiveFloat)
+ => string.IsNullOrEmpty(position.FloatRateUnderlyingCode)
+ ? Fixed(spread)
+ : Floating(spread, effectiveFloat);
}
diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
index 7364c691..eab142cc 100644
--- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
@@ -1227,16 +1227,6 @@ 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 全程取)。
@@ -1376,8 +1366,8 @@ namespace YLErp.Modules.SwapModule
: 1m;
// 纯数学下沉至 CompoundInterestAccrual.AccrueEod(DDD 命名 + 末位生产精度 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(