停牌数据怎么处理?标记、填充与回测约束
我的掌握程度:
先掌握这个答案
标准三步:①标记:suspended=True列(成交量=0或日期缺失对齐后识别);②填充:价格类字段ffill(净值连续性),但必须带着标记;③回测约束:停牌日禁止开/平仓(无对手盘),复牌首日谨慎(跳空风险)。原则:数据层保留完整(可分析),交易层禁止成交(守现实)。
先读结论,再核对下方使用边界;数字例题为教学情景,涉及实际行情与规则时请核对原始来源。
从理解到使用
每一笔收益都要有可执行时间线
打印数据截止时间、信号时间、订单时间、成交时间和持仓收益区间。收盘信号不能乘当天完整收益;次日开盘成交也不能无条件拿到整个close-to-close收益。用原始价格判断可成交性,并纳入停牌与涨跌停。
本阶段实战方法 · 把行情数字变成可比较的收益
看股票、基金或策略业绩时,先对齐本金、起止日期、现金流与费用。
- 选一个固定区间,记录期初价值、期末价值、分红、出入金和交易费用。
- 没有中途出入金时,用(期末价值+已取出分红-期初价值-费用)÷期初价值计算收益;有出入金时先区分时间加权与资金加权。
- 用相同区间的基准作比较,同时记录最大亏损;不要单凭一次盈利评价能力。
使用边界
- 不同期限的收益不可直接排名;年化只是换算,不是未来收益承诺。
- 模拟价格不是实时行情。普通股票交易手数、T+1和费用应按具体市场规则核对。
背景 · 从一个困惑说起
q-046从市场机制认识了停牌。数据层面它是个两难:删掉停牌日→股票「凭空消失」引入偏差;保留并前向填充→价格「冻结」在旧值,回测可能假设你在冻结价成交(现实中根本无法交易)。
由此产生的问题
停牌数据的正确处理组合拳是什么?「标记+填充+交易约束」三者怎么配合?
核心概念
标准三步:①标记:suspended=True列(成交量=0或日期缺失对齐后识别);②填充:价格类字段ffill(净值连续性),但必须带着标记;③回测约束:停牌日禁止开/平仓(无对手盘),复牌首日谨慎(跳空风险)。原则:数据层保留完整(可分析),交易层禁止成交(守现实)。
为什么需要它
①偏差防线:删除停牌=幸存者偏差变种(停牌股集中在危机期,删掉它们=低估危机亏损);②回测真实性:在冻结价上「成交」是最隐蔽的作弊之一(尤其复牌大跌前的卖出);③组合估值:持有停牌股的组合净值要用标记价+风险准备(阶段7的估值话题)。
实际应用场景
选股池:当日停牌股自动剔除(信号无法执行);持仓中停牌:保留权重、冻结价格、禁止调仓计算把它「卖出」;风险模型:停牌股的波动率用行业均值替代(它是未知的,不是零)。
与之前知识的联系
q-046的机制知识+q-065的清洗框架在停牌上落地。下一题的幸存者偏差是「数据完整性」的最后一课:消失的股票去哪了。
⚠ 常见误解
- ffill停牌价就是正确处理:填充让图表连续,但若回测按填充价成交=虚构交易;必须叠加交易约束
- 停牌股波动率为零:冻结价格≠零风险,复牌补跌一次兑现全部积累的风险
- 停牌期间因子可以照常计算:基于价格的因子全部冻结失真,因子更新应跳过停牌期
🛠 本题实践任务
构造一个含停牌的迷你数据框(如代码示例),实现三步处理,并验证:停牌期间tradable=False、复牌日跳空在close_ffill中正确体现。
💡 提示(先自己想5分钟再看)
直接跑通本题代码再改参数即可;尝试把复牌价改成+50%(复牌暴涨),看ffill的跳空方向。
✅ 验收标准
代码跑通+一句话总结「分析口径」与「交易口径」为什么必须分离。
在你的浏览器内运行。首次需联网下载 Python;支持标准库和 Pyodide 提供的 NumPy、pandas 等包。行情抓取、系统文件访问和部分第三方库请在本地环境运行。输出自检仅比对结果关键词,不代替逻辑审查。
Python · 独立工作线程 · 执行限时10秒
🤖 AI导师
导师会先检查你的前置知识(停牌、脏数据),再用案例、公式和代码帮助理解。此功能需要先启用服务。