23、订单流交易中的回测与优化:回测框架搭建、参数优化、过拟合识别
做订单流交易,最怕什么?
怕你辛辛苦苦写出来的策略,实盘一跑就崩。我见过太多人,拿着回测曲线漂亮得不像话的策略冲进去,结果三个月亏掉半年利润。说白了,回测没做好,参数优化没搞明白,过拟合没识别出来。
今天这一章,我就把这三件事掰开揉碎了讲清楚。
一、回测框架搭建:别让细节坑了你
回测框架,听起来高大上,其实核心就三件事:数据怎么喂、订单怎么撮合、结果怎么算。我个人习惯用Python搭一个轻量级框架,不依赖任何第三方回测库,因为自己写的才可控。
第一步:数据准备
订单流数据跟K线不一样。K线只有OHLC,订单流数据你得有逐笔成交、买卖盘口、Delta、累积Delta这些字段。我建议至少准备以下字段:
| 字段名 | 说明 | 示例值 |
|---|---|---|
| timestamp | 时间戳(毫秒级) | 1696003200000 |
| price | 成交价 | 100.25 |
| volume | 成交量 | 1500 |
| side | 买卖方向(B/S) | B |
| bid_volume | 当前买一挂单量 | 3200 |
| ask_volume | 当前卖一挂单量 | 2800 |
第二步:撮合引擎
这里有个坑。很多人直接用收盘价撮合,但订单流策略往往依赖盘口挂单。我建议用限价单模拟,考虑滑点和流动性。举个例子:
def execute_order(signal, current_price, bid_volume, ask_volume):
if signal == 'BUY':
# 假设吃卖一,考虑滑点
fill_price = current_price * 1.0001
# 检查流动性是否足够
if ask_volume < order_size:
fill_price = current_price * 1.0002 # 滑点扩大
return fill_price
elif signal == 'SELL':
fill_price = current_price * 0.9999
if bid_volume < order_size:
fill_price = current_price * 0.9998
return fill_price
嗯,这里要注意。滑点参数别拍脑袋定。我一般会拿历史数据跑一遍,统计实际成交价和信号触发价的偏差,取中位数作为默认滑点。
第三步:绩效统计
别只看收益率。夏普比率、最大回撤、胜率、盈亏比,这四个指标必须看。我习惯再加一个「卡玛比率」——年化收益除以最大回撤,这个指标对订单流策略特别敏感。
核心指标速查表
- 夏普比率 > 1.5:及格
- 最大回撤 < 15%:可接受
- 胜率 40%-60%:正常范围
- 盈亏比 > 1.5:有优势
二、参数优化:别掉进「最优解」陷阱
参数优化,说白了就是找一组参数让回测曲线最好看。但这里有个致命问题——你找到的「最优解」,很可能只是历史数据的巧合。
我建议用「网格搜索 + 交叉验证」的组合拳。先划定参数范围,比如移动平均线周期从5到50,步长5。然后做滚动交叉验证:用前70%数据训练,后30%数据验证,再往前滚动。
# 参数网格示例
param_grid = {
'ma_period': [5, 10, 15, 20, 25, 30],
'delta_threshold': [100, 200, 300, 500],
'stop_loss': [0.5, 1.0, 1.5, 2.0]
}
# 滚动交叉验证
for train_end in range(0.7 * len(data), 0.9 * len(data), 0.1 * len(data)):
train_data = data[:train_end]
test_data = data[train_end:train_end + 0.1 * len(data)]
# 在train_data上优化参数
# 在test_data上验证
我曾经遇到过一个策略,在全部数据上回测年化收益40%,但滚动验证时发现,只有2018年到2020年表现好,2021年以后直接崩了。为什么?因为那段时间市场结构变了,参数没跟上。
避坑指南
我曾经犯过一个错误:参数优化时用了全部历史数据,结果找出来的参数只对那段特定行情有效。后来我学乖了,每次优化只用最近两年的数据,并且每季度重新优化一次。
三、过拟合识别:别被漂亮曲线骗了
过拟合,是量化交易的头号杀手。怎么识别?我总结了三招。
第一招:样本外测试
把数据分成三份:训练集(60%)、验证集(20%)、测试集(20%)。训练集用来优化参数,验证集用来调参,测试集只用来做最终验证。如果测试集表现远差于训练集,基本可以断定过拟合了。
第二招:参数敏感性分析
把最优参数稍微偏移一点,看看绩效变化。如果参数从10变成11,收益就从40%掉到10%,那这个参数就是「悬崖参数」,极度不稳定。我一般要求参数在±20%范围内波动时,绩效下降不超过30%。
第三招:蒙特卡洛模拟
把交易信号随机打乱,重新跑回测。如果随机信号也能赚钱,说明你的策略跟市场噪声没什么区别。我习惯跑1000次随机模拟,如果真实策略的夏普比率在随机模拟的95%分位数以上,才算通过。
警告
别迷信「多策略组合」。两个过拟合的策略组合在一起,只会产生一个更大的过拟合策略。我见过有人把20个策略组合在一起,回测曲线平滑得像教科书,实盘一个月亏了15%。
四、知识体系总览
下面这张图,是我做订单流回测优化的核心流程。你照着这个框架走,至少能避开80%的坑。
你看,整个流程是闭环的。数据准备 -> 回测引擎 -> 绩效统计 -> 参数优化 -> 过拟合检测 -> 决策。如果过拟合检测没通过,就回到参数优化重新来。我一般要跑3到5轮,才能确定一个策略是否真的可用。
最后说一句。回测只是工具,不是目的。你的目的是在实盘中赚钱,而不是让回测曲线好看。记住这一点,很多坑你自然就绕过去了。
本章核心要点
- 回测框架要自己搭,别依赖第三方库
- 参数优化用网格搜索 + 滚动交叉验证
- 过拟合识别三招:样本外测试、参数敏感性分析、蒙特卡洛模拟
- 实盘部署前,至少跑3轮完整的回测优化流程