数据清洗:复权、停牌、缺失值
读完你会知道
- 复权处理会影响收益计算,前复权和后复权不能混用。
- 停牌、涨跌停和缺失值不是小问题,它们会直接改变回测结果。
- point-in-time 数据能避免「当时拿不到的信息」进入策略。
回测的第一个坑通常不在策略,而在数据。价格少了一天、复权方式选错、停牌被当成正常交易,都会让净值曲线变得好看,但实盘复制不出来。
数据清洗不是把数据「洗干净」这么简单,而是把每个字段的时间含义和交易约束弄清楚。下面四个问题,是搭最小回测前必须处理的。
一、复权:前复权和后复权
股票分红、送股、配股后,价格会出现跳空。复权就是把历史价格调整到可比口径。前复权以当前价格为基准调整历史价格,适合看技术图形和近期收益;后复权以历史价格为基准调整未来价格,适合计算长期持有收益。
两者不能混用。用前复权数据算历史买入价,再用当前真实价格算收益,会把分红和拆股的影响算错。回测里更重要的是保持口径一致:信号、成交价、净值都使用同一套复权规则。
二、停牌与涨跌停
停牌期间不能交易,但很多数据源会重复上一日价格或直接缺失。如果你把停牌日当成正常交易日,策略会在不可成交的价格上「成交」,回测收益会被高估。
涨跌停也一样。一字涨停买不进,一字跌停卖不出。回测必须显式检查:当日是否停牌、是否一字板、成交量是否足够。处理不了这些约束,回测就只是数学游戏。
| 异常 | 常见错误 | 正确处理 |
|---|---|---|
| 停牌 | 用上一日价格成交 | 标记不可交易,顺延或放弃 |
| 一字涨停 | 按收盘价买入 | 视为买不进 |
| 一字跌停 | 按收盘价卖出 | 视为卖不出 |
| 缺失值 | 直接前向填充 | 先判断是停牌、退市还是数据缺口 |
三、缺失值怎么处理
缺失值有三种常见来源:停牌、退市、数据源缺口。处理方式不同。停牌可以标记并顺延;退市要从样本中移除或按退市规则处理;数据源缺口需要补数据或剔除该区间。直接前向填充会把「没有交易」伪装成「价格不变」,是最危险的做法之一。
成交量和成交额也要检查。价格存在但成交量为 0,通常意味着不可交易;成交额异常小,可能意味着流动性不足,实盘成交价会偏离收盘价。
四、point-in-time:当时能拿到什么
财报有披露延迟,指数成分会调整,评级和公告也有发布时间。如果你用「后来修订过的数据」回测「当时的决策」,就会产生前视偏差。point-in-time 数据记录的是每个信息在当时是否已经可得,而不是最终版本。
最低限度也要做到:财报按公告日而不是报告期使用,指数成分按调整生效日切换,退市股票保留在历史样本里。做不到完全 point-in-time,至少要知道自己的回测高估了多少。
五、清洗后的检查清单
- 复权口径统一,信号和成交价使用同一套价格。
- 停牌、涨跌停、成交量为 0 的日期已标记。
- 缺失值按来源分类处理,没有无脑前向填充。
- 财报和指数成分按可得时间使用。
- 样本包含退市和失败案例,不只留下活到今天的股票。
数据清洗做得好,回测收益通常会变差。这不是坏事,而是把不可复制的部分提前挤掉了。
最后给数据留一个版本号。每次修改清洗规则,记录改了什么、影响哪些日期、回测结果变化多少。否则三个月后你很难解释,为什么同一套策略跑出了两个不同的净值。
数据与口径
- 复权定义以数据提供方说明为准;不同平台的复权因子可能有差异。
- 停牌、涨跌停和退市规则以交易所公告为准,本文只讨论回测处理方式。
- 本文不构成任何投资建议。