问题描述
回测收益很好但实盘表现差
解决方案
在PTrade量化交易平台中,许多开发者会遇到“回测收益曲线完美,但实盘表现大相径庭”的问题。这种现象在量化交易中被称为“回测过拟合”或“实盘偏差”。结合PTrade的底层机制和API文档,导致这一问题的主要原因及解决方案如下:
1. 未设置合理的滑点(Slippage)
原因:实盘交易中,由于市场波动和盘口买卖价差,你的委托价格往往不是最终的成交价格(即冲击成本)。如果在回测中不设置滑点,系统会默认以理想价格成交,导致回测收益被严重高估。
解决方案:在initialize函数中设置合理的滑点。
- 固定滑点:
set_fixed_slippage(fixedslippage=0.02)(例如设置0.02元价差)。 - 百分比滑点:
set_slippage(slippage=0.002)(例如设置千分之二的滑点)。
2. 忽略或低估了交易成本(Commission)
原因:频繁交易的策略对费率极其敏感。如果回测时未扣除佣金、印花税和过户费,净收益会虚高。
解决方案:使用set_commission函数设置贴近实盘的费率。例如:
set_commission(commission_ratio=0.0003, min_commission=5.0, type="STOCK")
3. 引入了“未来函数”
原因:策略在历史某个时间点使用了当时不可知的数据。在PTrade中,某些API获取的是**当下(最新)**的数据,如果在回测中使用,就会产生未来函数。
典型陷阱:
get_stock_blocks(stock_code)(获取股票所属板块):文档明确指出该函数获取的是当下的数据,回测不能取到真正匹配回测日期的数据。get_industry_stocks(industry_code)(获取行业成份股):同样获取的是当下数据。- 财务数据更新:使用
get_fundamentals时,如果没有正确设置date或使用了merge_type=1(获取最新修正数据),可能会用到未来才发布的修正财报。
4. 忽略了市场流动性限制
原因:回测时,系统默认只要有价格就能成交。但在实盘中,如果你的单子很大,而盘口挂单很少,根本无法全部成交。
解决方案:
- 开启成交量限制:确保不要使用
set_limit_mode('UNLIMITED')(不限制成交量)。 - 设置成交比例:使用
set_volume_ratio(volume_ratio=0.25),限制单笔委托最多只能成交该周期市场总成交量的25%。
5. 涨跌停与停牌处理不当
原因:实盘中,股票涨停时买不进,跌停时卖不出,停牌时无法交易。如果回测引擎没有严格过滤这些情况,或者策略逻辑强行以收盘价成交,会导致虚假收益。
解决方案:
- 下单前检查停牌状态:使用
get_stock_status(stocks, 'HALT')过滤停牌股。 - 检查涨跌停状态:使用
check_limit(security)判断是否触及涨跌停(返回1为涨停,-1为跌停),避免在无法成交时发出无效订单。
6. 价格精度导致实盘废单
原因:PTrade文档强调,不同品种的价格精度不同(股票2位小数,可转债/ETF/LOF 3位小数)。如果策略计算出的委托价格(如均价乘以某个系数)包含多位小数,直接传入order()的limit_price中,实盘柜台会直接拒单(废单),而回测可能宽容处理。
解决方案:下单前务必使用round(price, 2)(股票)或round(price, 3)(可转债/基金)对价格进行截断处理。
总结建议
为了缩小回测与实盘的差距,建议在策略上线前:
- 加入严苛的摩擦成本:调高滑点和手续费,测试策略的抗压能力。
- 检查API使用:排查所有可能引入未来函数的接口。
- 先模拟后实盘:在PTrade中先挂模拟盘运行1-2周,对比模拟盘的成交记录与回测日志,找出未成交或废单的原因。