搬迁(算法体逐字未动,仅换命名空间与归属): - 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 已留警告)。
35 lines
2.0 KiB
C#
35 lines
2.0 KiB
C#
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);
|
||
}
|