diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
index 7e69e78b..b22c70e7 100644
--- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
@@ -486,7 +486,10 @@ namespace YLErp.Modules.SwapModule
&& eventTypes.Contains(x.EventType)
&& x.DataState == (int)SwapFlowDateStateEnum.完成).ToList();
bool tdClose = closeList.Count > 0;
- interests = GetInterests(td, tradeExtend, valueDate, unwindDate, lastEodPositions, positions, stockEqvNotional, posiLongNotionalValue, posiShortNotionalValue, posiNotionalValue, closePercent, eventType, tdClose, false, grossPrice ?? 0, orginPv, true, false,false, closeList);
+ // 显式入口(语义见 GetIntradayUnwindInterests 注释):平仓前剩余本金 + 实际平掉额 + B语义比例,盘中重放
+ interests = GetIntradayUnwindInterests(td, tradeExtend, valueDate, unwindDate, lastEodPositions, positions,
+ stockEqvNotional, posiLongNotionalValue, posiShortNotionalValue, posiNotionalValue,
+ closePercent, eventType, tdClose, orginPv, add: true, newCalcLast: false, closeList);
return interests;
}
@@ -616,6 +619,40 @@ namespace YLErp.Modules.SwapModule
///
///
///
+ ///
+ /// 【盘中平仓/互换结息】显式入口——GetInterests(settment:false) 盘中语义的具名封装(2026-08 显式化重构)。
+ ///
+ /// 语义契约(与 EOD 平仓后收盘的 CalcEodPostCloseSettleInterests 相反,勿混用):
+ /// preCloseNotional = 平仓【前】实时剩余本金(原 GetUnwindInterests 的 stockEqvNotional);
+ /// closedNotional = 本次实际平掉本金(= preCloseNotional × closePercentRemaining);
+ /// closePercentRemaining = 平仓比例,B 语义【占剩余】(前端传 A 占期初,须先经 ToRemainingClosePercent 转换);
+ /// 计息走 CalcUnwindInterest 全区间重放(orginPv 参与保证金腿差分)。
+ ///
+ /// needPrice/grossPrice 为 GetInterests 的历史死参数(方法体内无消费),本入口不再暴露。
+ ///
+ public List GetIntradayUnwindInterests(
+ trade td,
+ trade_extend tradeExtend,
+ DateTime valueDate,
+ DateTime unwindDate,
+ List eodPositions,
+ List positions,
+ decimal preCloseNotional,
+ decimal preCloseLongNotional,
+ decimal preCloseShortNotional,
+ decimal closedNotional,
+ decimal closePercentRemaining,
+ int eventType,
+ bool tdClose,
+ decimal orginPv,
+ bool add,
+ bool newCalcLast,
+ List closeList)
+ => GetInterests(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
+ preCloseNotional, preCloseLongNotional, preCloseShortNotional, closedNotional,
+ closePercentRemaining, eventType, tdClose, needPrice: false, grossPrice: 0m,
+ orginPv, add, settment: false, newCalcLast, closeList);
+
public List GetInterests(
trade td,
trade_extend tradeExtend,
diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
index be097caf..795b5829 100644
--- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
@@ -102,6 +102,33 @@ namespace YLErp.Modules.SwapModule
grossPrice, orginPv, add, settment, newCalcLast, closeList);
}
+ ///
+ /// 【EOD 当日有平仓后的收盘结息】显式入口——原 SaveAutoEodWithCloseInterestPosition 直调
+ /// CalcSwapInterests(settment:false) 的具名封装(2026-08 显式化重构)。
+ ///
+ /// 语义契约(与盘中 SwapDealService.GetIntradayUnwindInterests 相反,勿混用):
+ /// remainingNotionalAfterClose = 平仓【后】剩余本金(GetInterests.posiNotionalValue 形参位);
+ /// closedNotional = 本次实际平掉本金(GetInterests.closePosiNotionalValue 形参位);
+ /// 结息比例恒 1(本次事件全额结息)。该组合会触发 GetInterests 内 mode2 无条件覆盖 /
+ /// mode9 全平兜底(见其"根因位置"注释,勿删)。
+ /// 计息走 CalcUnwindInterest 全区间重放(settment:false)。
+ ///
+ /// 默认实现仍经 CalcSwapInterests 转发,保持既有测试替身对该虚接缝的拦截不变。
+ ///
+ protected virtual List CalcEodPostCloseSettleInterests(
+ trade td, trade_extend tradeExtend,
+ DateTime valueDate, DateTime unwindDate,
+ List eodPositions, List positions,
+ decimal remainingNotionalAfterClose, decimal remainingLongNotional, decimal remainingShortNotional,
+ decimal closedNotional,
+ int eventType, bool tdClose,
+ decimal grossPrice, decimal orginPv,
+ bool add, bool newCalcLast)
+ => CalcSwapInterests(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
+ remainingNotionalAfterClose, remainingLongNotional, remainingShortNotional,
+ closedNotional, 1m, eventType, tdClose, needPrice: true, grossPrice, orginPv,
+ add, settment: false, newCalcLast, closeList: null);
+
// FindTrade 已上提到基类 SwapTradeBaseService(三子类实现一致,消除重复)
/// 查找交易扩展(生产: DbContext.trade_extend;测试: 内存字典)
@@ -1306,9 +1333,11 @@ namespace YLErp.Modules.SwapModule
List preEodPositions = new List();
preEodPositions.Add(eodPayPosition);
var calcLast = tradeExtend?.InterestCalcMode?.EndsWith("1") ?? true;
- // 此处 closePercent=1 表示 EOD 计算本次事件时走全额结息;它不是 closeNational / oriPosiNotionalValue。
- // 与上方“收盘后剩余本金”同时传入会触发共享计息器的模式2/9本金修正,见 GetInterests。
- var interests = CalcSwapInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, closeNational, 1, eventType, false, true, grossPrice, orginPv, true, settment: false, newCalcLast: autoSwap || calcLast);
+ // 显式入口(语义见 CalcEodPostCloseSettleInterests 注释):平仓后剩余本金 + 实际平掉额 + 恒1全额结息。
+ // 该组合会触发 GetInterests 内共享计息器的模式2/9本金修正(见其"根因位置"注释,勿删)。
+ var interests = CalcEodPostCloseSettleInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions,
+ posiNotionalValue, posiLongNotional, posiShortNational, closeNational,
+ eventType, tdClose: false, grossPrice, orginPv, add: true, newCalcLast: autoSwap || calcLast);
// TdInterestAmount:计息器返回的全腿当日/累计参考值,用于拆出 EOD 的当日新增。
// interestAmountBeforeSettlement:本次事件发生前理论应结的高精度利息。
// manualSettledInterestAmount:swap_flow_event 实际落库的手工结息,金额已按分处理。