fix(swap): 修复EOD平仓后收盘时结息本金计算错误

- 修正SwapDealService.GetInterests方法中平仓后结息本金语义错位问题
- 区分EOD平仓后收盘与盘中平仓前本金传参的不同语义
- 针对模式2合约名义本金规模强制覆盖为实际平仓额
- 保持模式9标的期初全价在全平时的零值处理逻辑
- 添加债券份额调整公司行动支持和记录日期资格判断
- 实现EOD仓位复制和更新时的公司行动应用逻辑
This commit is contained in:
张名锐
2026-08-12 14:40:03 +08:00
parent c86633479d
commit 2035e1df4c
2 changed files with 17 additions and 2 deletions
@@ -1293,6 +1293,11 @@ namespace YLErp.Modules.SwapModule
var tradeExtend = td.trade_extend.ExtendObj;
// oriPosiNotionalValue 是平仓前规模,posiNotionalValue 是收盘后剩余规模,closeNational 是本次关闭规模。
// 例如 30% 平仓:303139117.80 = 212197382.46 + 90941735.34。
// 注意:此处的 posiNotionalValue 与盘中 GetUnwindInterests 传给 GetInterests 的语义不同:
// 盘中传平仓前的当前剩余本金,EOD 此处传平仓后的剩余本金;后面又以 closePercent=1
// 调用共享计息器。因此策略的 "posiNotional × closePercent" 在本例会得到 212197382.46
// 而本次实际应结的平仓本金是 closeNational=90941735.34。该语义错位由
// SwapDealService.GetInterests 的模式2无条件修正、模式9全平零值兜底分流处理,不能删除。
decimal oriPosiNotionalValue = posiLongNotional + posiShortNational + closeNational;
decimal posiNotionalValue = posiLongNotional + posiShortNational;
// ratio 只负责把腿内原始金额转换为本方盈亏方向,不参与计息金额本身的计算。
@@ -1360,6 +1365,8 @@ 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);
// TdInterestAmount:计息器返回的全腿当日/累计参考值,用于拆出 EOD 的当日新增。
// interestAmountBeforeSettlement:本次事件发生前理论应结的高精度利息。