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

3.1 KiB
Raw Blame History

任务 4:盘中复利从 EOD 续接(而非 PosiStartDate 全程重放)

状态:待立项(高风险,需专项验证)

现状

CalcDailyCompoundInterestposition.PosiStartDate 全程重放到 endDate,每个重置日把累计利息并入本金(复利),最后扣 consumedInterest * closePercent

调用链InitSwapDealInterestCalcDailyCompoundInterest(endDate, PosiStartDate→endDate 全程重放)

问题:交易存续期长(数月~数年)时,每次盘中平仓都从起息日重放,计算量随天数线性增长。

提议

改为从上一日终快照(preEodPosition)续接:

  • 起点 = preEodPosition.ValueDate + 1
  • 初始本金 = preEodPosition.TdInterestPrincipal(已含历史滚入利息)
  • 只算 ValueDate+1endDate 的增量利息

风险分析(为什么不能直接改)

风险 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

InitSwapDealInterestclosePrecent == 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 扣减逻辑移除或调整