Files
zszq-trs/YLErpDAL/Modules/SwapModule/Accrual/AccrualPolicy.cs
T
hjhan e2431e9d44 refactor(accrual): 计息类型整体迁入 DAL——新增 Accrual/InterestMath,删 Core 未接线孤儿
搬迁(算法体逐字未动,仅换命名空间与归属):
- SwapInterest.Round/AccrualDays/FundingLegPrecision + AccrualBoundary/InterestResult
  → YLErpDAL/Modules/SwapModule/Accrual/InterestMath.cs
- AccrualTrace → Accrual/AccrualTrace.cs(被迫同迁:其 MarkStart 引用 AccrualBoundary,
  Core 不能反向依赖 DAL)
- 引用切换:Simple/CompoundInterestAccrual、AccrualPolicy、SwapCalcTrace、SwapDealService
  (保留 using YLErp.Derivatives.Interest——IIndexFixer/IndexFixerBase 留 Core)

删除(零生产引用,孤儿清零):
- Core:SwapInterest.cs 算法方法(AccrueSimple/AccrueCompoundInArrears/ApplyUnwind/
  AccrueUnrealized/ToInterestRate,未接线且与 DAL 生产实现舍入/rollover 口径已分叉)、
  AccrualContext.cs、InterestRate.cs
- DAL:AccrualState.cs(零引用死类)
- 测试:SwapInterest_CompoundInArrears_RolloverTimingTests.cs(仅测已删原语)

验证:两解决方案 Rebuild 0 错误;磁盘 SwapInterest. 残留 0;影子/分红/场景 86/86 通过
(含 Accrual 3 影子对账、Margin 影子、divPower 新增 AutoUnwindMultiPartial)。
注:AccrualContext 默认精度 11 与生产 12 的分叉隐患随删除一并消除;
已删原语若将来重建须先补对账测试,勿凭记忆复原(ARCHITECTURE.md 已留警告)。
2026-08-14 15:31:04 +08:00

35 lines
2.0 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.
namespace YLErp.Modules.SwapModule.Accrual;
/// <summary>
/// 计息政策(不可变配置)。把"算头算尾 / 单复利率 / 重置频率 / 年化天数"收敛为一处,
/// 取代旧代码里散落各处的 calcFirst/calcLast 布尔对与魔法数字。
///
/// 单/复利不再另立枚举——直接复用既有 DB 枚举 InterestTypeEnum(单利=0 / 复利=1),
/// 通过 <see cref="IsCompound"/> 暴露为类型安全的 bool。
/// </summary>
public sealed class AccrualPolicy
{
/// <summary>算头算尾约定(AccrualBoundary,物理上杜绝 calcFirst/calcLast 传反)。</summary>
public AccrualBoundary Convention { get; }
/// <summary>是否复利(利滚利)。来自 DB 的 InterestTypeEnum;单利=false,复利=true。</summary>
public bool IsCompound { get; }
/// <summary>利率重置周期(天)。FR007 通常为 7;复利时亦为"利息并入本金"的周期。</summary>
public int ResetPeriodDays { get; }
/// <summary>年化基数(365 / 360)。</summary>
public int AnnualDays { get; }
/// <summary>是否年化(position.IsAnnualized)。决定利息是否再除以 <see cref="AnnualDays"/>
/// 与 <see cref="AnnualDays"/> 一同收敛 daycount 语义,不再作为裸 bool 散落在计息签名里。</summary>
public bool IsAnnualized { get; }
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);
}