diff --git a/YLErpDAL/Modules/SwapModule/TEST-MATRIX.md b/YLErpDAL/Modules/SwapModule/TEST-MATRIX.md index fa5bc94d..7f3e2341 100644 --- a/YLErpDAL/Modules/SwapModule/TEST-MATRIX.md +++ b/YLErpDAL/Modules/SwapModule/TEST-MATRIX.md @@ -133,3 +133,7 @@ InterestMode = 9 标的期初全价 × FR007 浮动(±点差) × InterestType = 3. 任何触碰 `GetInterests`/`CalcUnwindInterest`/`SaveAutoEodWithCloseInterestPosition` 的 PR: 跑 `DealInterestsGoldenReplayTest` 全量 + 保证金黄金回放(防共享管线殃及)。 4. 登记 fix 时发现同格已有用例而 bug 仍发生 → 先修断言投影,再修代码。 +5. **oracle 用例与裁决材料一律取 §8 生产参数**(7 天重置 / A365 / 真实点差 ±0.25%·−2.10% / + 千万级名义本金,如 5000 万)。玩具参数(千元级/重置 3 天/点差 1%)仅限字符化钉子测试—— + 其用途是锁行为防漂移,不承担"证明数字正确"职责;用玩具数字做裁决依据会掩盖金额量级 + (0.03 vs 0.06 看着"不大",同参数放大到生产即 7.6 万 vs 25 万/笔)。 diff --git a/项目文档/双入口口径裁决-复利mode2部分平仓-20260816.md b/项目文档/双入口口径裁决-复利mode2部分平仓-20260816.md index 11432d30..c02c4529 100644 --- a/项目文档/双入口口径裁决-复利mode2部分平仓-20260816.md +++ b/项目文档/双入口口径裁决-复利mode2部分平仓-20260816.md @@ -5,6 +5,23 @@ ## 一、分歧事实(生产代码实测,已钉住) +### 1.1 真实规模复算(确认书生产参数,裁决请以此为准) + +参数全部取自确认书规定与生产实配(见 TEST-MATRIX §8/§8a): +名义本金 **5000 万**;FR007=1.8% + 点差 **+0.25%** = all-in 2.05%;重置频率 **7 天**; +计息基准 **A/365**;持有 **90 天**(12×7 天完整重置期 + 6 天末段);**部分平仓 30%**(平掉 1500 万,剩余 3500 万)。 + +| 口径 | 结息额 | 计算方式 | +|---|---:|---| +| 契约公式(应结) | **75,999.04 元** | 平掉额 1500万 × 参考利率(90天)= ∏公式,手算见 §二 | +| 盘中平仓试算 | **75,999.04 元** | 与契约公式一致(引擎实测,容差内) | +| EOD 平仓后收盘(现结) | **251,355.08 元** | 平仓前全仓 5000万 截至上一日终待实现(250,508.61) + 平掉额末段增量(846.43) | + +**一笔事件多结 175,356.04 元,结了应结金额的 3.3 倍**(多出部分 ≈ 剩余 3500 万份额对应的待实现利息, +在只平 30% 时被全额结走,且剩余 70% 持仓后续到期/全平时会**再结一次** → 双重结算敞口)。 + +### 1.2 可复现实测锚点(玩具参数,字符化钉子) + 场景:合约名义本金(mode2)×复利×浮动 FR007×部分平仓 30% 参数:本金 1000,平掉 300,剩余 700;FR007=0.1%,利差=1.0%;[4/27 起息,4/30 平仓] 算头算尾 4 天;重置周期 3 天。 @@ -13,7 +30,7 @@ | 盘中平仓试算 | **0.036165** | 平掉额 300 从 4/27 到 4/30 全程复利重放 | | EOD 平仓后收盘 | **0.059042** | 剩余持仓全部待实现利息(0.05) + 平掉额 4/30 末段增量(0.009042) | -**EOD 比盘中多结 63%**(多出的 0.023 ≈ 剩余 700 份额对应的待实现利息,却在平 30% 时被全额结走)。 +EOD 比盘中多结 63%(同一分歧在玩具参数下的比例;比例随持有天数/平仓比例变化,真实规模见 §1.1)。 ## 二、契约验算(确认书公式,模板:国联民生收益互换确认书-现券/ETF 四份一致) @@ -22,11 +39,32 @@ 结息额(平仓部分) = 实际平掉额 × 参考利率(绝对) ``` -手算(300×[(1+0.011×3/365)×(1+0.011×1/365)−1])= **0.0361652** +真实规模手算(利率恒定 2.05% 时 ∏ 可合并): +- 90 天 = 12×7 天 + 6 天末段 → 参考利率 = (1+0.0205×7/365)^12 × (1+0.0205×6/365) − 1 = **0.0050666026** +- 应结 = 1500万 × 0.0050666026 = **75,999.04 元** = 盘中口径(引擎实测一致) -**= 盘中口径**(差 3.7e-7 为引擎利率舍入量级)。EOD 口径无法由契约公式推出。 +EOD 口径(全仓待实现 250,508.61 + 末段增量 846.43 = 251,355.08)**无法由契约公式推出**—— +契约里不存在"平掉 30% 却结走 100% 持仓利息"的条款。 -## 三、机制定位(为什么 EOD 会算成这样) +玩具参数手算(300×[(1+0.011×3/365)×(1+0.011×1/365)−1])= 0.0361652,同样 = 盘中口径。 + +## 三、触发链:谁在 EOD"平仓"(命名澄清) + +**"EOD 平仓后收盘"不是自动平仓本身,是收盘归档任务对当日平仓事件的重算结息。** 完整链条: + +1. **人工盘中部分平仓**(正确):交易员平仓页操作 → `GetUnwindInterests` 传**真实比例 30%** → + 结息 75,999 落 swap_flow_event(正确); +2. **自动归并部分平仓**(平仓当下也正确):`SwapTradeAutoService` 每日任务按券商柜台反向成交流水 + (swap_flow_merge)自动平仓(`AuotoSwapUnwind`,SwapTradeAutoService.cs:1229/1290/1411)—— + `unwindQty` 按实际流水量算,**流水量<持仓量时天然就是部分平仓**;该方法内部同样走盘中语义 + (SwapDealService.cs:1644 传真实 unwindPercent); +3. **当晚 EOD 重算(分歧所在)**:收盘归档 `DealInterests`(SwapEodPositionService.cs:511/:524) + 发现当日有平仓事件 → `EodPostCloseSettle` 惯例传 **closePrecent 恒 1**("结算本次事件覆盖的全部") + → 掉进 `closePrecent == 1m` 全平专属分支(:1220)→ 251,355 覆盖/修正归档。 + +即:**平仓动作本身(人工/自动)当下结息都是对的;错发生在当晚收盘归档重算这一步**。 + +## 四、机制定位(为什么 EOD 会算成这样) `SwapDealService.cs:1220` 的 `closePrecent == 1m` 分支,设计意图是**最终全平专属** (注释原文:"最终全平只重放上一日终之后的新增利息……以上一日 InterestIncomeSum 为起点,保证之前攒下的尾差最后一次带走")—— @@ -36,21 +74,25 @@ "结算本次事件覆盖的全部")。于是 **EOD 部分平仓 30% 也掉进全平专属分支**,把剩余 100% 持仓的 待实现利息全部结走。数字 1 承载了两种语义:"平仓比例=100%" vs "本次事件全额结息"。 -## 四、请业务裁决 +## 五、请业务裁决 -1. **部分平仓(含 EOD 自动平仓)应结利息**:是否 = 确认书公式下"实际平掉额 × 全程利率"? - (即盘中口径 0.036165)——契约公式直接支持,推荐。 +1. **部分平仓(含 EOD 归档重算)应结利息**:是否 = 确认书公式下"实际平掉额 × 全程利率"? + (即盘中口径;真实规模例:平 30% 应结 75,999.04 而非 251,355.08)——契约公式直接支持,推荐。 2. **最终全平应结利息**:维持现公式"剩余持仓待实现 + 末段增量"(尾差一次带走)——合理,建议维持。 -## 五、裁决后的修复方案(技术侧已就绪,预计 1~2 天) +## 六、裁决后的修复方案(技术侧已就绪,预计 1~2 天) - EOD 入口改为传**真实比例**(实际平掉额/剩余)而非恒 1;部分平仓自然走重放路径(与盘中同语义) - 全平保留 percent=1,1220 分支回归"全平专属"设计意图 - `GetInterests` 内 mode2 无条件覆盖/mode9 兜底(2035e1df 粘合)随之退役删除 - 钉住测试翻转为"两入口相等" oracle 断言;黄金回放 diff 仅允许出现在本格子的 EOD 结息额(=裁决修正值) -## 六、生产影响面(待查证) +## 七、生产影响面(待内网查证) -- 受影响格子:EOD 自动平仓 × mode2/9 × 复利 × **部分**平仓(若生产存在此路径的存量交易) -- 建议内网查:swap_flow_event 中 EventType=平仓 且当日 closePercent<1 的复利 mode2/9 事件, - 与盘中口径重算值比对差值 +受影响格子:**当日发生部分平仓 × 复利 × mode2/9 × 当晚 EOD 归档重算**——含两个来源: +- 人工盘中部分平仓后的当晚归档(常见); +- `SwapTradeAutoService` 自动归并部分平仓(反向流水量<持仓量)后的当晚归档。 + +建议内网查:swap_flow_event 中 EventType=平仓 且当日 closePercent<1 的复利 mode2/9 交易, +取当日 EOD 归档利息事件 InterestAmount 与"平掉额×契约参考利率"重算值比对差值; +差值 ≈ 剩余持仓待实现利息即坐实(单笔量级参考 §1.1:5000万名义/30%平仓 ≈ 多结 17.5 万)。