Files
fidc-backtest-engine/docs/late-fill-lot-lifecycle-20260914.md
T
2026-09-14 19:27:10 +08:00

44 lines
4.9 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.
# 迟到成交、批次成本与持有保护
2026-09-14。阶段修复;完整股票池目标仍未完成,未据此发布生产。
## 根因与修复
旧持仓账本按收到买入回报的顺序追加批次,卖出直接扣列表首批。当较早成交的回报晚到,或旧证券换股并入已有新证券持仓时,列表先后不再等于取得日期。T+1 校验计算了合法老批次数量,却实际扣掉新批次;剩余旧批次可能再次被当作可卖。FIFO 成本与已实现/未实现盈亏随之错配。
另一问题是已有持仓收到更早买入事实时,`opened_date` 没有更新,最长持有期从较晚日期起算。
修复在账本扣减入口按真实取得日期稳定执行 FIFO;同日回报及其费用保持原关联,不重排收到的外部事件,不补单、不回写历史结果。正常日期顺序不排序,零股操作不排序。连续持仓的已知开仓日取较早日期,最近买入日仍取较晚日期;缺失的原始建仓日期不靠新买入猜测填充。移动均价展示合同与固定精度现金/费用不变。
## 负向证据
基线 `b2eaaa0d269d4aee5e2e500cd0f2b2edbda648b8` 上新增两个测试实际失败:
- 9月14日新买100股先被观察,9月11日老买100股随后才被观察。旧 `opened_date` 仍为9月14日,期望9月11日。
- 随后卖出100股时,旧代码扣了新批次,剩余未实现盈亏为 -0.75,而按老批次先卖应为 -1000.25。该样例分别使用20元/10元买入、0.25/0.75元买入费用和0.5元卖出费用;只有证券身份数据,不冒充真实市场行情。
## 回归覆盖
- 回报仍按原观察序号应用;老买入不得在收到之前进入持仓。
- 合法卖出老100股后,新100股仍不可在9月14日卖出。第二次冲突卖出拒绝且现金、股数、游标原子保留;现金7998.5、出入金0、剩余FIFO成本2000.25,费用没有串到另一批次。
- 最长持有期使用9月11日,买后3个交易日保护使用最新买入日9月14日,保护优先于最长持有退出。
- 整段引擎换股:旧股较早买入100股、已有新股较晚买入100股,旧股按2倍换成新股200股。随后卖200股先扣旧来源,留下新买100股;不重置开仓/最近买入日,成交来源及换股事件保留,已实现不含费用盈亏200。
- 整段平台表达式:真实手工两买一卖、次日送转、3日买后保护/卖后禁买、16日至17日显式锁定、最长持有退出同时配置。14日至15日审计分别记录保护和禁买,16日至17日记录锁定;18日只生成一笔卖200股、5元的最长持有退出,不重复附加显式卖单。三笔手工来源保留、不计出入金,旧股转成200股后计时不重置。
- 同一整段测试另验16日锁定期间的已确认手工卖出200股:与14日保护期间卖100股两个变体分别验证。前者15日送转后400股,手工卖出后200股;两个变体最终都在18日仅自动退出剩余200股。锁定仍阻止自动交易,不阻止已授权手工事实入账;T+1未绕过,买后保护和卖后禁买分别沿实际日期计算。
本机Core889、Trading625、Runner460/API127通过,ignore另计;针对性完整审计断言另行通过。两次测试编写阶段的私有方法/辅助函数名编译错误已修正,不计作框架失败或通过证据。不是实际Source或GT交易验收。
## 仍须继续
实际 Source/Runner 联合回放和未准入 Arrow 性能门禁尚未通过;Source明确冻结仍待独立解除授权。另需继续验证迟到回报跨越已经执行过的除权/派息/换股事件、跨模式历史持有事实及其余参数矩阵。本节只证明列出的组合,不能外推全部公司行为或关闭完整目标。
旧opening-clock-UUx5ru与FewUWP收据均不包含本次账本修复,不得覆盖。后续新的Linux/发布证据另附,本轮不修改原池、任务、历史或交易开关。
## Linux复验与当前状态
代码修复e9c9ecb、两组锁定/保护变体b4c68be均已提交推送;177引擎开发树已更新到b4c68be、tracked clean。新的`lot-lifecycle-20260914-AEGDYL`只读快照绑定Engineb4c68be/Service49f2800/Tradingae83fd3962个文件、独立build根、4CPU/12GiB及1GiB容量线。
Core889、Trading625、Runner/API589(含Linux额外2项平台测试)通过,源码前后不变,测试已结束。收据[linux-tests.json](evidence/late-fill-lifecycle-20260914/linux-tests.json)及[runtime.json](evidence/late-fill-lifecycle-20260914/runtime.json)。本轮只是新快照测试,没有再构建release或创建发布tag,不覆盖已完成批次。
Source仍d5/PID1700096、tracked clean,生产UI及五后端PID/实际二进制SHA与上一轮相同;保留Service并行开发5991e77。没有委托/撤单/任务配置写入,没有解冻Source或重启生产。完整Goal继续上述剩余矩阵及正式Source/Runner验收,不把这些确定性测试外推为真实交易通过。