3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个非常经典且令许多量化交易者头疼的问题。在量化领域,这种现象通常被称为“回测过拟合”或“幸存者偏差”,但也可能源于代码逻辑中的“未来函数”或对市场环境的设定不切实际。
以下是导致策略回测表现优异但实盘亏损的几个核心原因,以及针对 PTrade 平台的具体分析:
这是最常见也是最致命的错误。它指的是策略在决策时使用了当时实际上无法获取的数据(即使用了“未来的数据”)。
handle_data 中获取日线数据时,如果回测频率是日线,data 或 get_history 获取的是当天的收盘数据。如果在逻辑上认为这是“盘中”数据并进行交易,就会产生偏差。high、low、close,却在当天的 open 或盘中时间成交。策略参数被调整得完美适配历史数据,捕捉了历史上的“噪音”而非“规律”。
回测通常假设你可以以理想价格成交,而忽略了实际交易中的摩擦成本。
initialize 中是否使用了 set_commission 设置真实的佣金费率?set_slippage 或 set_fixed_slippage 来模拟滑点?如果回测中滑点设为0,实盘必然亏损。回测引擎通常假设“只要有成交量,我就能成交”,而忽略了你的订单对市场的影响。
回测时只选择了当前还在上市的股票,忽略了历史上已经退市或暴雷的股票。
set_universe 动态调整股票池,或者使用指数成分股(如 get_index_stocks)随时间动态变化的历史数据,而不是固定一个今天的股票列表。回测引擎的撮合逻辑是简化的,而实盘是复杂的。
open 价格成交。但在实盘中,当你收到 09:31 的数据并计算完信号下单时,价格可能已经变动,你只能以更差的价格成交。handle_data,此时全天交易已结束。如果在日线回测中下单,通常是在下一个交易日开盘成交(除非使用了特定的盘后撮合逻辑)。如果你的理解是“当天成交”,就会产生巨大偏差。数据处理不当导致的价格失真。
get_history 或 get_price 时,注意 fq(复权)参数的设置(通常使用 'pre' 前复权进行技术分析,但需注意实际账户资产是按不复权计算的)。set_volume_ratio 限制单笔成交量不超过该分钟总成交量的 10% 或更低。frequency='minute')来模拟真实的盘中交易,因为日线回测的撮合逻辑与实盘差异较大。Q: 什么是未来函数?如何避免?
A: 未来函数是指在策略回测时使用了当时不可预见的数据(如当天的收盘价、最高价等)。避免方法是严格遵守时间序列,只使用当前时间点之前的数据(如昨天收盘价、当前tick的最新价),并确保下单动作发生在信号产生之后。
Q: PTrade 中如何设置滑点以模拟真实环境?
A: 可以在 initialize 函数中使用 set_slippage 或 set_fixed_slippage。例如 set_slippage(PriceRelatedSlippage(0.002)) 表示设置 0.2% 的滑点,这能让回测结果更接近实盘。
Q: 为什么我的策略在小市值股票上回测特别好?
A: 小市值股票波动大且流动性差。回测往往忽略了流动性冲击,假设你能以当前价格买入任意数量。实盘中,大资金买入小盘股会推高价格(冲击成本),导致实际收益大幅缩水。建议在回测中剔除流动性过差的标的。
Q: 回测时应该使用前复权还是后复权数据?
A: 计算技术指标(如均线、MACD)通常使用前复权(fq='pre'),因为这能保持价格走势的连续性,消除分红配股造成的缺口。计算账户收益和持仓市值时,系统会自动处理实际价格。