diff --git a/Framework/YLErp.Core/Interest/SwapInterest.cs b/Framework/YLErp.Core/Interest/SwapInterest.cs index f9ca0ad3..b43f69f0 100644 --- a/Framework/YLErp.Core/Interest/SwapInterest.cs +++ b/Framework/YLErp.Core/Interest/SwapInterest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using YLErp.Core.Interest; namespace YLErp.Derivatives.Interest; @@ -77,16 +78,25 @@ public readonly struct InterestResult /// /// 收益互换(TRS)利息腿计算——纯函数。 /// -/// 设计约束: +/// 层级关系:计息数学(单利/复利/连续复利)是通用金融原语,已抽到 +/// YLErp.Core.Interest,与互换无关,谁都能用)。 +/// 本类只负责 TRS 特有的会计态:每日先舍入再乘天数的对账口径、平仓缩放、 +/// 跨日滚动本金、预付金/授信模式——这些不是"利率数学",不应塞进通用原语。 +/// +/// 设计约束: /// 1. 无副作用——不读写 flowEvent、不取利率、不连库、不碰任何共享可变状态; /// 2. 同 input → 同 output,结果仅通过返回值流出; /// 3. 正交轴(算头算尾 / 单利复利 / 平仓 / 待实现收益)各自独立,互不耦合; /// 4. 调用方负责「取利率 + 构造日期区间 + 落库」,本类只算账。 -/// 由此,corp action 调整价格 / 数量时只需把新的 principal 与 rate 喂入,计息逻辑一行不动。 +/// 由此,corp action 调整价格 / 数量时只需把新的 principal 与 rate 喂入,计息逻辑一行不动。 /// -/// 领域口径:本系统利息腿是单边融资腿,任一时点只有一个生效利率(见 SwapDealService 的 +/// 领域口径:本系统利息腿是单边融资腿,任一时点只有一个生效利率(见 SwapDealService 的 /// floateRate 单一入参),不存在 IRS 那种 fixedRate − floatingRate 轧差; -/// 权益腿盈亏与平仓费用属三腿汇总层,不在本类职责内。 +/// 权益腿盈亏与平仓费用属三腿汇总层,不在本类职责内。 +/// +/// TRS 的"复利"是离散重置日复利:按重置日切段,每段用 +/// 计息、段末把利息滚入本金——本质就是单利按段叠加,decimal 精度无损,无需 Pow/Exp +/// (见 )。所以本类不另立复利方法,计息只有一种,区别在于"是否滚动本金"。 /// /// 为何不复用 Qdp 的 IDayCount: /// a. 语义——Qdp 的 DaysInPeriod = end − start 是写死的半开区间,只能表达四种算头算尾中的一种; @@ -96,9 +106,13 @@ public readonly struct InterestResult /// public static class SwapInterest { - /// 系统统一价格精度位数。 + /// 系统统一价格精度位数(保证金腿)。 public const int Precision = 11; + /// 资金腿计息精度(生产口径)。资金腿所有落库/对账均以 12 位为准, + /// 与保证金腿的 Precision=11 不同。提升至公共常量,消除 SwapDealService 与 FundingLegAccrual 的重复定义。 + public const int FundingLegPrecision = 12; + /// 年化天数常量(合约字段存的是 int,故不用 enum)。 public const int Act365 = 365; @@ -113,6 +127,11 @@ public static class SwapInterest return days < 0 ? 0 : days; } + /// 把 TRS 年化利率收敛为通用利率原语。 + /// TRS 计息按段均为单利——离散重置日复利靠"段末把利息滚入本金"实现,不引入 Compounded 闭式。 + public static InterestRate ToInterestRate(decimal annualRate) + => new(annualRate, Compounding.Simple); + /// 单利:计息基数固定,每日利息相同,无逐日循环。 public static InterestResult AccrueSimple( decimal principal, @@ -129,8 +148,9 @@ public static class SwapInterest } /// - /// 复利:按重置日切段,段间把累计利息并入计息基数。 - /// 段内复用 AccrueSimple(仍无逐日循环);重置日是唯一并本金的地方。 + /// 离散重置日复利:按重置日切段,段间把累计利息并入计息基数(滚动本金)。 + /// 每段计息即 得到的 (无逐日循环); + /// 重置日是唯一并本金的地方。复利与单利只有"是否滚动本金"这一个区别。 /// public static InterestResult AccrueCompound( decimal principal,