移除标注"切勿在未迁移前接入生产"的 AccrueDay/AccruePeriod 骨架(含 IIndexFixer/ Func 取价),保留与旧实现逐字对齐的纯函数,消除两套计息逻辑并存的隐患。
66 lines
3.9 KiB
C#
66 lines
3.9 KiB
C#
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">平仓比例(closePercent,EOD 恒为 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));
|
||
}
|
||
}
|