refactor(swap): GetInterests 传参语义显式化——盘中/EOD平仓后收盘拆双显式入口

问题:GetInterests 同名参数在两类调用方下语义相反,约定只存在于注释(2035e1df 固化):
  盘中(:489链)                EOD平仓后收盘(:1311链)
  posiNotionalValue  平仓前剩余本金  vs  平仓后剩余本金
  closePercent       实际平仓比例(B)  vs  恒1(全额结息)
  均走 settment:false 盘中重放算法。6fdc7d80 修的错账即两语义混用产物,
  mode2 无条件覆盖/mode9 全平兜底是粘合补丁。

改动(纯机械,零行为变化):
- SwapDealService 新增 GetIntradayUnwindInterests(preCloseNotional/closedNotional/
  closePercentRemaining 具名),GetUnwindInterests 切换调用;needPrice/grossPrice 为
  GetInterests 死参数(体内零消费),新入口不再暴露
- SwapEodPositionService 新增虚接缝 CalcEodPostCloseSettleInterests
  (remainingNotionalAfterClose/closedNotional/恒1),默认实现经 CalcSwapInterests
  转发——既有测试替身对该接缝的拦截不变;SaveAutoEodWithCloseInterestPosition 切换调用
- 原 GetInterests/CalcSwapInterests 签名与行为不动(测试直调兼容);EOD 增量路径
  (:1148/:1563, settment:true, closePosi=posi 同值) 语义自洽,本次不动

验证:全量 899 测试 145失败/742通过/12跳过——与 e2431e9d 基线逐位一致,零回归。
This commit is contained in:
hjhan
2026-08-14 15:39:44 +08:00
parent e2431e9d44
commit 01447ffe04
2 changed files with 70 additions and 4 deletions
+38 -1
View File
@@ -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
/// <param name="tdClose"></param>
/// <param name="add"></param>
/// <returns></returns>
/// <summary>
/// 【盘中平仓/互换结息】显式入口——GetInterests(settment:false) 盘中语义的具名封装(2026-08 显式化重构)。
///
/// 语义契约(与 EOD 平仓后收盘的 CalcEodPostCloseSettleInterests 相反,勿混用):
/// preCloseNotional = 平仓【前】实时剩余本金(原 GetUnwindInterests 的 stockEqvNotional);
/// closedNotional = 本次实际平掉本金(= preCloseNotional × closePercentRemaining);
/// closePercentRemaining = 平仓比例,B 语义【占剩余】(前端传 A 占期初,须先经 ToRemainingClosePercent 转换);
/// 计息走 CalcUnwindInterest 全区间重放(orginPv 参与保证金腿差分)。
///
/// needPrice/grossPrice 为 GetInterests 的历史死参数(方法体内无消费),本入口不再暴露。
/// </summary>
public List<swap_flow_event> GetIntradayUnwindInterests(
trade td,
trade_extend tradeExtend,
DateTime valueDate,
DateTime unwindDate,
List<eod_swap_position> eodPositions,
List<swap_position> positions,
decimal preCloseNotional,
decimal preCloseLongNotional,
decimal preCloseShortNotional,
decimal closedNotional,
decimal closePercentRemaining,
int eventType,
bool tdClose,
decimal orginPv,
bool add,
bool newCalcLast,
List<swap_flow_event> 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<swap_flow_event> GetInterests(
trade td,
trade_extend tradeExtend,
@@ -102,6 +102,33 @@ namespace YLErp.Modules.SwapModule
grossPrice, orginPv, add, settment, newCalcLast, closeList);
}
/// <summary>
/// 【EOD 当日有平仓后的收盘结息】显式入口——原 SaveAutoEodWithCloseInterestPosition 直调
/// CalcSwapInterests(settment:false) 的具名封装(2026-08 显式化重构)。
///
/// 语义契约(与盘中 SwapDealService.GetIntradayUnwindInterests 相反,勿混用):
/// remainingNotionalAfterClose = 平仓【后】剩余本金(GetInterests.posiNotionalValue 形参位);
/// closedNotional = 本次实际平掉本金(GetInterests.closePosiNotionalValue 形参位);
/// 结息比例恒 1(本次事件全额结息)。该组合会触发 GetInterests 内 mode2 无条件覆盖 /
/// mode9 全平兜底(见其"根因位置"注释,勿删)。
/// 计息走 CalcUnwindInterest 全区间重放(settment:false)。
///
/// 默认实现仍经 CalcSwapInterests 转发,保持既有测试替身对该虚接缝的拦截不变。
/// </summary>
protected virtual List<swap_flow_event> CalcEodPostCloseSettleInterests(
trade td, trade_extend tradeExtend,
DateTime valueDate, DateTime unwindDate,
List<eod_swap_position> eodPositions, List<swap_position> 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(三子类实现一致,消除重复)
/// <summary>查找交易扩展(生产: DbContext.trade_extend;测试: 内存字典)</summary>
@@ -1306,9 +1333,11 @@ namespace YLErp.Modules.SwapModule
List<eod_swap_position> preEodPositions = new List<eod_swap_position>();
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:本次事件发生前理论应结的高精度利息。
// manualSettledInterestAmountswap_flow_event 实际落库的手工结息,金额已按分处理。