diff --git a/YLErpDAL/Modules/SwapModule/Accrual/FundingLegAccrual.cs b/YLErpDAL/Modules/SwapModule/Accrual/FundingLegAccrual.cs
index a621e489..cba457b8 100644
--- a/YLErpDAL/Modules/SwapModule/Accrual/FundingLegAccrual.cs
+++ b/YLErpDAL/Modules/SwapModule/Accrual/FundingLegAccrual.cs
@@ -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
/// 原始名义本金(orginPv),用于保证金腿差分基数。
/// 当日生效利率(已由适配器按腿型封装:固定腿=FixedRate,浮动腿=Spread+IndexFixing)。
/// 计息政策(daycount:是否年化 / 年化天数)。
+ /// 本次日终计息对应的日期(用于 trace 标注"哪一天")。
+ /// 可选追踪收集器;传 null 时行为与旧版完全一致(纯计算、无副作用)。
/// :Accrued=累计未实现(对应 InterestAmount),AccruedToday=当日利息(对应 TdInterestAmount)。
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;
}
}
diff --git a/YLErpDAL/Modules/SwapModule/SwapCalcTrace.cs b/YLErpDAL/Modules/SwapModule/SwapCalcTrace.cs
index 98d4378e..93dd6011 100644
--- a/YLErpDAL/Modules/SwapModule/SwapCalcTrace.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapCalcTrace.cs
@@ -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() ?? "";
+
+ ///
+ /// 把纯函数产出的 常驻落盘(关键路径日志)。
+ /// 每条目经 写出——无条件落盘,与开关无关;
+ /// 开关打开时同时进内存 buffer 供实时查看 / 单测断言。这是事后 diff 新旧引擎的主通道。
+ ///
+ public static void Persist(InterestTrace? trace)
+ {
+ if (trace == null) return;
+ foreach (var entry in trace.Entries)
+ Critical(entry.Line);
+ }
}
}
diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
index 818d1d3c..dd61e24f 100644
--- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
@@ -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);
}
///