01学完你能做到
你能区分不复权、前复权和后复权,识别停牌、涨跌停和退市造成的回测偏差;理解 point-in-time(PIT,时点可得)财务数据;会从年初至今累计数计算单季度和 TTM,并用时间轴检查未来函数。
02这课解决什么问题
一条价格或财务数据看起来只是一个数字,但它可能经过复权、修订、补录,甚至在决策时还没有公布。数据的时间和口径错了,回测即使代码完全正确,也会得到无法实现的结果。
03行情数据:公司行为与可交易性
复权的目的
分红、送股、转增和配股会让价格机械跳变。为了计算持有期收益,需要把公司行为纳入总回报。数据库应尽量保留不复权价格和累计复权因子,使用时再按需求计算。
除息且没有送转时,除权除息参考价约为:
P_ex = P_(t−1) − D
更一般地,含送转和配股时,常见参考价形式为:
P_ex = [(P_(t−1) − D) + K × r] ÷ (1 + r)
D 是每股现金红利,K 是配股价,r 是股份变动比例。具体计算应以对应交易所规则和公司公告为准。
累计复权因子记为 F_t:
- 后复权价 = 不复权价 × F_t。
- 前复权价 = 不复权价 × F_t ÷ F_T。
在同一段历史内,两种复权价格计算收益率通常一致,但前复权的价格水平会随着未来分红更新而改变。因此,“价格低于某个金额”这类特征应使用不复权价格。
停牌、涨跌停和退市
停牌期间没有成交,把价格填成前一天会制造一串 0 收益;复牌时的累计变化又集中出现。回测若在停牌期间按停牌价卖出,就假设了现实中不存在的成交。
涨跌停也不等于一定能成交。一字涨停时可能买不到,一字跌停时可能卖不掉。回测应给每天建立可交易标记,例如:
tradable_i,t = 未停牌 × 可按目标方向成交 × 满足上市时间等筛选条件
每一项可以是 0 或 1。上市满多少天、是否排除风险警示股票等,应在策略规则中提前写清楚。
退市股票不能只在当前股票列表里研究。样本还需要包含退市前的价格、退市整理阶段和最后可实现的处理规则,否则会产生幸存者偏差。示意:100 只股票中 3 只退市,退市者平均收益 −70%,幸存者平均收益 8%。只看幸存者得到 8%,全体平均收益为 0.97 × 8% + 0.03 × (−70%) = 5.66%,偏差为 2.34 个百分点。
04财务数据:时点可得与口径
一条数据的多个时间
财务数据至少要区分报告期末、首次公告日、修订日和入库时间。PIT 原则是:
在决策时刻 τ 能使用的值 = 所有可得时间不晚于 τ 的版本中,最新的一个。
不能把报告期末当成可得日,也不能默认数据库中今天看到的修订值当时已经存在。较保守的规则是公告后下一个交易日才能使用,实际研究应把这条规则写入回测说明。
固定滞后与公告日对齐
固定滞后法简单稳健,例如把上一个财年的账面数据延迟到下半年再使用;代价是信息较旧。逐条公告日对齐更及时,但要求数据源保留准确公告日和每个历史版本。
无论选择哪种方法,都不能用报告期一结束就可得的朴素对齐。例如一季报通常不会在 3 月 31 日当天出现,模型若在 3 月末直接使用,就发生前视偏差。
单季度和 TTM
A 股利润表常见的是年初至今累计值(YTD)。单季度利润为:
单季度_Qk = YTD_Qk − YTD_Q(k−1)
一季度直接使用一季度 YTD。最近十二个月(TTM)为:
TTM = 最新 YTD + 上一年年报 − 上一年同期 YTD
示意:最新一季 YTD 为 268.47 亿元,上年年报为 862.28 亿元,上年同期 YTD 为 240.65 亿元,则 TTM = 268.47 + 862.28 − 240.65 = 890.10 亿元。资产负债表是时点数,不能照搬 TTM 公式。
05面板与未来函数检查
时间轴和标签
如果 t 日收盘后计算特征,最早在 t+1 日开盘交易,持有 h 天的开盘到开盘标签可写成:
y_i,t = P_open(i,t+1+h) ÷ P_open(i,t+1) − 1
不能用 t 日收盘到 t+h 日收盘的收益替代,否则会把信号生成后无法成交的那一段收益计入结果。
三个工程检查
- 时间戳检查:每个字段都有可得时间,按“截至时刻取最新值”拼接。
- 截断检查:把数据截断在某一天,重新运行流程;截断日及以前的特征必须与全量运行一致。
- 扰动检查:随机改变截断日之后的数据,截断日及以前的特征和回测结果不应变化。
代码可以保留关键逻辑:
# t 日收盘生成信号,t+1 日开盘起算标签
label = open_price.shift(-(h + 1)) / open_price.shift(-1) - 1
# 只取决策时刻之前可得的最近版本
available = reports[reports.avail_time <= decision_time]
latest = available.sort_values("period_end").iloc[-1]06延伸阅读
- Stefan Jansen《Machine Learning for Algorithmic Trading》
- Shumway《The Delisting Bias in CRSP Data》
- Fama & French 因子数据说明
6 道自测
先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。
01为什么前复权价格不适合直接构造“低价股”特征?
02停牌期间把价格保持不变,会怎样影响波动率和交易模拟?
03100 只股票中 3 只退市,幸存者平均收益 8%,退市者平均收益 −70%,只看幸存者会高估多少?
04YTD 为 300 亿元,上年年报为 1000 亿元,上年同期 YTD 为 240 亿元,TTM 是多少?
05t 日收盘生成信号,为什么标签不能从 t 日收盘价开始?
06截断测试和扰动测试分别在检查什么?
已看 0/6 题
练动手练习
任务:选一只股票,建立一张小型数据字典,记录价格口径、复权因子、分红日期、财务报告期、首次公告日和可交易标记;再做一次截断测试,确认截断日以前的特征不会因未来数据变化。
完成这一课
读完讲义、看完自测答案,这一课就算学完了。
- 读完讲义
- 看完全部自测
本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。