2. 量化回测基础
回测是量化策略研究的第一道“实验室”。它用历史数据模拟策略在过去的交易过程,回答一个核心问题:如果这套规则在当时被执行,结果会怎样?但回测不是预言机,它更像一台显微镜——用得好能看清策略逻辑,用不好会把噪声当成规律。本节围绕回测的基本概念、常见误区、过拟合与未来函数、以及回测与实盘的差异展开,帮助你建立正确的回测观。
一、回测的基本概念与核心流程
一个完整的回测系统通常包含五个要素:数据、信号、组合、执行和评估。数据提供历史行情与基本面信息;信号根据规则生成买卖意图;组合决定仓位分配与风险约束;执行模拟成交价格、滑点和手续费;评估则输出收益、风险与归因指标。
从时间维度看,回测必须严格遵循“先有数据,后有决策,再有成交”的因果顺序。任何在决策时点使用了未来信息的操作,都会让回测结果虚高。下面是一个最小化的回测循环伪代码,展示了这一顺序:
for t in range(lookback, len(data)):
# 1. 仅使用 t 时刻及之前的数据
history = data[:t+1]
# 2. 生成信号
signal = strategy.generate_signal(history)
# 3. 在 t+1 时刻开盘或收盘执行
price = data[t+1].open
portfolio.execute(signal, price)
# 4. 记录净值
portfolio.mark_to_market(data[t+1].close)
这个循环看似简单,却决定了回测是否可信。很多初学者把信号生成和成交放在同一根K线上,导致“用收盘价决策,又用同一收盘价成交”,这已经隐含了未来函数。
二、常见误区:回测中的“美丽陷阱”
回测中最常见的误区可以归纳为以下几类:
- 幸存者偏差:只使用当前仍存续的股票或基金,忽略了已退市、被并购或清盘的样本,导致收益被高估。
- 前视偏差:在决策时使用了当时无法获得的信息,例如用年报数据在报告期前交易,或用当日收盘价决定当日开盘交易。
- 过度优化:反复调整参数直到回测曲线完美,本质是把历史噪声拟合成了规律。
- 忽略交易成本:不计算佣金、印花税、滑点和冲击成本,尤其在高频或小盘股策略中,成本可能吞噬全部利润。
- 样本内过拟合:在全部历史数据上训练和评估,没有留出独立的样本外区间。
警示:如果一条回测净值曲线过于平滑、夏普比率高得离谱、最大回撤极小,首先要怀疑的不是策略太强,而是回测有漏洞。真实市场的收益曲线通常伴随波动、回撤和阶段性失效。
三、过拟合与未来函数:两大核心敌人
过拟合是指策略过度适应历史数据中的随机噪声,导致样本外表现急剧下降。判断过拟合的常用方法包括:样本外测试、滚动前向验证、参数敏感性分析和多市场验证。一个稳健的策略,其参数在小幅变动时绩效不应剧烈变化。
未来函数则更隐蔽。它不一定表现为代码错误,而可能藏在数据对齐、财报发布日期、指数成分股调整等细节中。例如,使用“当前成分股”回测过去十年的指数增强策略,就引入了未来函数,因为当时的成分股名单与现在不同。
| 问题类型 | 典型表现 | 检测方法 | 修正思路 |
|---|---|---|---|
| 未来函数 | 回测收益异常高,信号与价格高度同步 | 检查数据时间戳与成交时点 | 严格对齐决策与执行时间 |
| 过拟合 | 样本内极好,样本外崩溃 | 样本外测试、滚动验证 | 简化模型、减少参数、增加约束 |
| 幸存者偏差 | 选股池只有当前存续标的 | 核对历史成分股与退市记录 | 使用Point-in-Time数据 |
| 成本低估 | 换手率高但收益不降 | 加入滑点与手续费重跑 | 按真实交易成本建模 |
四、回测与实盘的差异:从实验室到战场
即使回测完全正确,实盘表现仍可能偏离。差异主要来自四个方面:
- 执行差异:实盘存在滑点、部分成交、排队延迟,回测通常假设即时全额成交。
- 流动性差异:回测中可无限买卖的标的,实盘可能因流动性不足而无法建仓或平仓。
- 市场冲击:大资金交易会改变价格,回测往往忽略自身交易对市场的影响。
- 心理与运营:实盘中的回撤会引发人为干预,运营故障也可能导致信号漏发或错发。
建议:在回测阶段就加入保守假设——提高滑点、降低成交率、限制单票仓位、加入随机延迟。如果策略在这些“恶劣条件”下仍能盈利,实盘才更值得期待。
总结来看,回测的价值不在于证明策略“一定赚钱”,而在于用可重复的方式检验策略逻辑是否成立、风险是否可控、成本是否可承受。只有正视过拟合、未来函数和实盘差异,回测才能真正成为量化研究的可靠起点。