feat(interest): 融资腿计息接入 trace 并常驻落盘

FundingLegAccrual.AccrueSimpleEod 接 InterestTrace;SwapCalcTrace 新增 Persist
把收集器条目经 Critical 无条件落盘(与开关无关);已迁移的 EOD 单利适配器
CalcDailySimpleInterestByEod 创建并 Persist trace。纯增量、数值逻辑不变。
This commit is contained in:
hjhan
2026-08-12 06:05:02 +08:00
parent fba87bd7cc
commit fcf52a305e
3 changed files with 32 additions and 3 deletions
@@ -1,4 +1,5 @@
using System;
using YLErp.Core.Interest;
using YLErp.Derivatives.Interest;
namespace YLErp.Modules.SwapModule.Accrual;
@@ -35,6 +36,8 @@ public static class FundingLegAccrual
/// <param name="originalPv">原始名义本金(orginPv),用于保证金腿差分基数。</param>
/// <param name="rate">当日生效利率(已由适配器按腿型封装:固定腿=FixedRate,浮动腿=Spread+IndexFixing)。</param>
/// <param name="policy">计息政策(daycount:是否年化 / 年化天数)。</param>
/// <param name="eodDate">本次日终计息对应的日期(用于 trace 标注"哪一天")。</param>
/// <param name="trace">可选追踪收集器;传 null 时行为与旧版完全一致(纯计算、无副作用)。</param>
/// <returns><see cref="InterestResult"/>Accrued=累计未实现(对应 InterestAmount),AccruedToday=当日利息(对应 TdInterestAmount)。</returns>
public static InterestResult AccrueSimpleEod(
decimal priorUnrealized,
@@ -43,7 +46,9 @@ public static class FundingLegAccrual
decimal closeRatio,
decimal originalPv,
FundingLegRate rate,
AccrualPolicy policy)
AccrualPolicy policy,
DateTime eodDate,
InterestTrace? trace = null)
{
var baseTdInterestPrincipal = priorAccrualPrincipal + positionPrincipal - originalPv;
var baseInterestPrincipal = baseTdInterestPrincipal * closeRatio;
@@ -58,8 +63,13 @@ public static class FundingLegAccrual
}
var totalUnrealized = priorUnrealized + dayInterest;
return new InterestResult(
var result = new InterestResult(
Math.Round(totalUnrealized, SwapInterest.FundingLegPrecision, MidpointRounding.AwayFromZero),
Math.Round(tdInterest, SwapInterest.FundingLegPrecision, MidpointRounding.AwayFromZero));
// 单日追踪:当日利率 / 计息基数 / 当日利息 / 累计未实现。纯函数只产出收集器,落盘由适配器负责。
trace?.Day(0, eodDate, combinedRate, baseInterestPrincipal, dayInterest, totalUnrealized);
trace?.MarkEnd(result.Accrued, result.AccruedToday);
return result;
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using YLErp.Core.Interest;
using YLErp.Helpers;
namespace YLErp.Modules.SwapModule
@@ -83,5 +84,17 @@ namespace YLErp.Modules.SwapModule
public static string Dump() => string.Join(Environment.NewLine, GlobalLines);
public static string DumpForRequest() => _reqBuf.Value?.ToString() ?? "";
/// <summary>
/// 把纯函数产出的 <see cref="InterestTrace"/> 常驻落盘(关键路径日志)。
/// 每条目经 <see cref="Critical"/> 写出——<b>无条件</b>落盘,与开关无关;
/// 开关打开时同时进内存 buffer 供实时查看 / 单测断言。这是事后 diff 新旧引擎的主通道。
/// </summary>
public static void Persist(InterestTrace? trace)
{
if (trace == null) return;
foreach (var entry in trace.Entries)
Critical(entry.Line);
}
}
}
@@ -3,6 +3,7 @@ using Newtonsoft.Json;
using YLErp.BLL;
using YLErp.BLL.Eod;
using YLErp.DBModels.Enums;
using YLErp.Core.Interest;
using YLErp.Derivatives.Interest;
using YLErp.Helpers;
using YLErp.Modules.DataProviderModule;
@@ -1591,6 +1592,8 @@ namespace YLErp.Modules.SwapModule
resetPeriodDays: position.interest_rest_days ?? 1,
annualDays: annualDays,
isAnnualized: position.IsAnnualized);
// 完整计息 trace:收集器由适配器创建,随后经 SwapCalcTrace 常驻落盘(关键路径日志,无条件)。
var interestTrace = new InterestTrace();
var result = FundingLegAccrual.AccrueSimpleEod(
priorUnrealized: preEodPosition.InterestProfitSum,
priorAccrualPrincipal: preEodPosition.TdInterestPrincipal,
@@ -1598,9 +1601,12 @@ namespace YLErp.Modules.SwapModule
closeRatio: closePercent,
originalPv: orginPv,
rate: legRate,
policy: accrualPolicy);
policy: accrualPolicy,
eodDate: endDate,
trace: interestTrace);
InterestAmount = result.Accrued;
TdInterestAmount = result.AccruedToday;
SwapCalcTrace.Persist(interestTrace);
}
/// <summary>