Files
zszq-trs/YLErpDAL/Modules/SwapModule/Accrual/FundingLegAccrual.cs
T
hjhan dee491b8d0 refactor(interest): FundingLegAccrual 删除危险骨架,仅保留纯函数 AccrueSimpleEod
移除标注"切勿在未迁移前接入生产"的 AccrueDay/AccruePeriod 骨架(含 IIndexFixer/
Func 取价),保留与旧实现逐字对齐的纯函数,消除两套计息逻辑并存的隐患。
2026-08-12 05:36:02 +08:00

66 lines
3.9 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.
using System;
using YLErp.Derivatives.Interest;
namespace YLErp.Modules.SwapModule.Accrual;
/// <summary>
/// 融资腿计息编排层——纯数学部分(替换 SwapDealService 内 CalcDaily* 家族的纯计算)。
///
/// <para>职责边界(与 SwapInterest 原语、SwapDealService 适配器三者正交):</para>
/// <list type="bullet">
/// <item><description>本类:持有已解析的 <see cref="FundingLegRate"/> 与 <see cref="AccrualPolicy"/>,执行单利日终计息纯函数。</description></item>
/// <item><description>SwapInterest:原子 "本金×利率×天数/年化" 纯函数,无状态。</description></item>
/// <item><description>SwapDealService:负责 DB 读、取率、swap_flow_event 构造与落库(IO)。</description></item>
/// </list>
/// </summary>
public static class FundingLegAccrual
{
/// <summary>
/// 单利日终计息(纯函数,替换 SwapDealService.CalcDailySimpleInterestByEod 的"纯数学"部分)。
///
/// <para>口径与旧实现逐字对齐(仅命名 DDD 化):</para>
/// <list type="bullet">
/// <item><description>计息基数 baseTdInterestPrincipal = priorAccrualPrincipal + positionPrincipal originalPv</description></item>
/// <item><description>当日利息 = baseTdInterestPrincipal × closeRatio × rate.AllInRate,年化则再 ÷ AnnualDays</description></item>
/// <item><description>累计未实现 = priorUnrealized + 当日利息;末位按资金腿精度 <see cref="SwapInterest.FundingLegPrecision"/> 舍入。</description></item>
/// </list>
///
/// <para>取率与重置日重取浮动利率由适配器(CalcDailySimpleInterestByEod)负责,并封装为 <see cref="FundingLegRate"/> 传入;
/// daycount 语义(年化 / 年化天数)由 <see cref="AccrualPolicy"/> 提供。本方法保持纯函数、可独立单测,不连库、不取价。</para>
/// </summary>
/// <param name="priorUnrealized">上一日日终累计未实现利息(preEod.InterestProfitSum)。</param>
/// <param name="priorAccrualPrincipal">上一日日终计息本金(preEod.TdInterestPrincipal)。</param>
/// <param name="positionPrincipal">存量名义本金(posiPrincipal)。</param>
/// <param name="closeRatio">平仓比例(closePercentEOD 恒为 1)。</param>
/// <param name="originalPv">原始名义本金(orginPv),用于保证金腿差分基数。</param>
/// <param name="rate">当日生效利率(已由适配器按腿型封装:固定腿=FixedRate,浮动腿=Spread+IndexFixing)。</param>
/// <param name="policy">计息政策(daycount:是否年化 / 年化天数)。</param>
/// <returns><see cref="InterestResult"/>Accrued=累计未实现(对应 InterestAmount),AccruedToday=当日利息(对应 TdInterestAmount)。</returns>
public static InterestResult AccrueSimpleEod(
decimal priorUnrealized,
decimal priorAccrualPrincipal,
decimal positionPrincipal,
decimal closeRatio,
decimal originalPv,
FundingLegRate rate,
AccrualPolicy policy)
{
var baseTdInterestPrincipal = priorAccrualPrincipal + positionPrincipal - originalPv;
var baseInterestPrincipal = baseTdInterestPrincipal * closeRatio;
var combinedRate = rate.AllInRate;
var dayInterest = baseInterestPrincipal * combinedRate;
var tdInterest = baseTdInterestPrincipal * combinedRate;
if (policy.IsAnnualized)
{
dayInterest /= policy.AnnualDays;
tdInterest /= policy.AnnualDays;
}
var totalUnrealized = priorUnrealized + dayInterest;
return new InterestResult(
Math.Round(totalUnrealized, SwapInterest.FundingLegPrecision, MidpointRounding.AwayFromZero),
Math.Round(tdInterest, SwapInterest.FundingLegPrecision, MidpointRounding.AwayFromZero));
}
}