Files
zszq-trs/YLErpDAL/Modules/SwapModule/docs/eod-continuation-proposal.md
T
hjhan 89eae7555f docs: 任务4 EOD续接风险分析 + SwapDealService方向比例收口
新增 docs/eod-continuation-proposal.md:
- 记录4个风险(并本金起点/consumedInterest语义/resetCarry/全平重放)
- 记录验证方案(6场景影子测试)
- 标注待立项,不混入日常重构

SwapDealService 收尾: 3处内联方向比例→DirectionRatio.ReceivePay
- line389: PosiDirection收取?-1:1 → -ReceivePay
- line1104/1235: InterestDirection==1?1:-1 → ReceivePay

SwapModule零回归(7基线/510通过)
2026-08-12 15:24:15 +08:00

67 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 任务 4:盘中复利从 EOD 续接(而非 PosiStartDate 全程重放)
## 状态:待立项(高风险,需专项验证)
## 现状
`CalcDailyCompoundInterest``position.PosiStartDate` 全程重放到 `endDate`,每个重置日把累计利息并入本金(复利),最后扣 `consumedInterest * closePercent`
**调用链**`InitSwapDealInterest``CalcDailyCompoundInterest(endDate, PosiStartDate→endDate 全程重放)`
**问题**:交易存续期长(数月~数年)时,每次盘中平仓都从起息日重放,计算量随天数线性增长。
## 提议
改为从上一日终快照(`preEodPosition`)续接:
- 起点 = `preEodPosition.ValueDate + 1`
- 初始本金 = `preEodPosition.TdInterestPrincipal`(已含历史滚入利息)
- 只算 `ValueDate+1``endDate` 的增量利息
## 风险分析(为什么不能直接改)
### 风险 1:并本金起点不同导致终值不等
| | 全程重放(当前) | EOD 续接(提议) |
|---|---|---|
| 起点 | `principal`(原始平仓名义本金) | `preEod.TdInterestPrincipal`(已滚利息) |
| 滚法 | 每段 `basis = principal + accrued` | 每段 `basis = preEod.TdInterestPrincipal + segmentAccrued` |
两段路径在**中间重置日的四舍五入路径不同**(精度 12 的 Round 作用在不同的中间值上),终值**不一定逐分相等**。
### 风险 2consumedInterest 语义翻转
- 全程重放:总利息 - consumedInterest × closePercent = 增量
- EOD 续接:直接算增量,**不需要**扣 consumedInterest
如果 EOD 快照的 `InterestIncomeSum` 与 consumedInterest 口径不完全一致,直接去掉扣减会引入误差。
### 风险 3resetCarryInterest 耦合
当前逻辑:`resetCarryInterest`(上一日终待实现 × remainingPercent)只在 `endDate` 恰好是重置日时并入本金。EOD 续接模式下,重置日的判定、remainingPercent 的计算、carry 的注入时机都不同。
### 风险 4:全平重放逻辑(lines 1293-1304
`InitSwapDealInterest``closePrecent == 1m` 时做 **两次** `CalcDailyCompoundInterest` 重放(截至平仓日 + 截至上一日终),取差值。EOD 续接模式下这段逻辑需要完全重新设计。
## 验证方案(立项前提)
1. 构造测试用例:同一笔复利交易,跨越 ≥2 个重置周期,有 preEod 快照
2. 用**旧全程重放**算出 `(InterestAmount, TdInterestAmount, finalBasis)`
3. 用**新 EOD 续接**算出同样三个值
4. 断言差额 < 0.01(到分)
5. 覆盖场景:
- 部分平仓(closePercent < 1
- 全平(closePercent == 1
- 平仓日 = 重置日
- 平仓日 ≠ 重置日
- 有/无 consumedInterest
- 有/无 resetCarryInterest
## 建议排期
单独 sprint 处理,不混入日常重构。改动范围:
- `CompoundInterestAccrual.AccruePeriod` 新增 `startBasis` 参数(或新方法 `AccrueFromEod`
- `CalcDailyCompoundInterest` wrapper 改为传 `preEod.TdInterestPrincipal` 作为起点
- `InitSwapDealInterest` 全平重放逻辑简化(不再需要两次重放取差值)
- `consumedInterest` 扣减逻辑移除或调整