From aff540801c3f84215cf54bcc1e3ebc2b2b861a02 Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 12 Aug 2026 05:36:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(interest):=20=E6=96=B0=E5=A2=9E=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E5=88=A9=E6=81=AF=E5=8E=9F=E8=AF=AD=20InterestRate?= =?UTF-8?q?=EF=BC=88=E4=B8=8E=E4=BA=92=E6=8D=A2=E8=A7=A3=E8=80=A6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 单利/复利/连续复利收敛为 Compounding 一个 switch 分支,利息计算不再住在 SwapModule/互换词汇里,谁需要算息都能直接用。连续复利仅 e^(r·t) 一行。 --- Framework/YLErp.Core/Interest/InterestRate.cs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Framework/YLErp.Core/Interest/InterestRate.cs diff --git a/Framework/YLErp.Core/Interest/InterestRate.cs b/Framework/YLErp.Core/Interest/InterestRate.cs new file mode 100644 index 00000000..a56f4a0e --- /dev/null +++ b/Framework/YLErp.Core/Interest/InterestRate.cs @@ -0,0 +1,71 @@ +using System; + +namespace YLErp.Core.Interest; + +/// +/// 利率 + 计息方式(单利 / 复利 / 连续复利)。 +/// +/// 通用金融原语,与互换、衍生品、任何具体业务均无耦合——谁需要算利息都能用。 +/// 利息计算不是互换特有的,所以它不住在 SwapModule,也不带任何 swap 词汇。 +/// +/// 用法(年化时间 t,如 30天/365): +/// +/// 计息因子 = ;含息额 = 本金 × 因子; +/// 利息 = 本金 × (因子 − 1) = +/// +/// +/// 与 QuantLib 模型一致:单利 / 复利 / 连续复利只是 的一个分支, +/// 不是三套独立方法。TRS 的"重置日并本金"属于离散复利,用 +/// 按段计息、段末把利息滚入本金即可(见 SwapInterest.AccrueCompound),无需 Pow/Exp,decimal 精度无损。 +/// +/// 互换特有的会计态(每日先舍入再乘天数、平仓缩放、跨日滚动本金)不属于本原语, +/// 请在各自的 accrual 层处理。 +/// +public enum Compounding +{ + /// 单利:因子 = 1 + r·t。 + Simple, + /// 复利(理想化闭式):因子 = (1 + r/f)^(f·t),f 为年复利频次。 + Compounded, + /// 连续复利:因子 = e^(r·t)。 + Continuous +} + +/// +/// 不可变利率值对象。构造即完整,无副作用。 +/// +public readonly struct InterestRate +{ + /// 年化利率 r。 + public decimal Rate { get; } + + /// 计息方式。 + public Compounding Compounding { get; } + + /// 年复利频次(仅 使用,其余忽略,默认 1)。 + public int Frequency { get; } + + public InterestRate(decimal rate, Compounding compounding, int frequency = 1) + => (Rate, Compounding, Frequency) = (rate, compounding, frequency); + + /// + /// 计息因子(输入年化时间 t)。 + /// + /// :decimal 精确运算。 + /// / :闭式(double 计算后回 decimal), + /// 满足通用定价 / 保证金场景;若要 decimal 精度的离散重置日复利,请用 Simple 按段计息并滚动本金。 + /// + /// + public decimal CompoundFactor(decimal t) + => Compounding switch + { + Compounding.Simple => 1m + Rate * t, + Compounding.Compounded => (decimal)Math.Pow((double)(1m + Rate / Frequency), (double)(Frequency * t)), + Compounding.Continuous => (decimal)Math.Exp((double)(Rate * t)), + _ => throw new ArgumentOutOfRangeException(nameof(Compounding)) + }; + + /// 利息 = 本金 × (因子 − 1)。 + public decimal Interest(decimal principal, decimal t) + => principal * (CompoundFactor(t) - 1m); +}