3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
回测收益高但模拟交易(或实盘)表现不一致,是量化交易中非常常见的问题,通常被称为“回测与实盘的偏差”。在 JoinQuant 聚宽平台上,造成这种差异的原因主要集中在未来函数、撮合机制差异、数据处理方式以及代码逻辑的不确定性上。
以下是导致回测与模拟交易结果不一致的详细原因分析及排查建议:
这是最常见的原因。策略在回测时“看到”了当时不应该知道的数据。
before_trading_start 或 09:30 的 handle_data 中使用了当天的 close、high、low 等数据。initialize 中开启防未来数据选项:set_option("avoid_future_data", True)
回测和模拟交易对价格的处理机制可能不同,导致信号触发点不一致。
initialize 中开启真实价格模式,使回测和模拟环境保持一致:set_option('use_real_price', True)
回测通常是理想化的,而模拟交易更接近真实市场环境。
match_with_order_book),系统会根据买一/卖一的挂单量进行严格撮合。如果对手盘量不足,订单可能无法成交或仅部分成交。如果策略代码中包含不确定的逻辑,会导致每次运行结果都不同。
for stock in context.portfolio.positions 的顺序来卖出股票,可能导致回测和模拟的卖出顺序不同,进而影响资金占用和后续买入。random 库但未固定随机种子。# 推荐做法
for stock in sorted(context.portfolio.positions.keys()):
# 逻辑处理
initialize 函数中加入以下代码:def initialize(context):
set_option('use_real_price', True) # 开启真实价格
set_option("avoid_future_data", True) # 开启防未来数据
# 统一手续费设置
set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
get_open_orders(),看是否有因为涨跌停或流动性不足导致的废单。Q: 什么是“未来函数”?如何避免?
A: 未来函数是指在策略回测时使用了当时时间点实际上无法获取的数据(如在周一开盘时就使用了周一的收盘价)。在 JoinQuant 中,可以通过 set_option("avoid_future_data", True) 来让系统自动检测并报错,同时编程时应避免在盘中直接调用当天的 close 数据,除非是分钟级回测且只调用已结束分钟的数据。
Q: 为什么开启 use_real_price 很重要?
A: 开启后,回测和模拟交易都会基于真实的除权除息机制运行,账户会在分红送股日自动调整持仓和现金,这与真实的股票账户逻辑一致。如果不开启,系统会使用后复权价格模拟,虽然计算结果理论上近似,但在处理分红税费、挂单价格精度以及模拟盘对接时容易产生偏差。
Q: 模拟交易中订单一直未成交(Open状态)是什么原因?
A: 这通常是因为开启了盘口撮合(match_with_order_book)或受限于流动性。如果您的委托价格偏离当前盘口价格太远,或者标的处于涨跌停状态、停牌状态,订单就会一直处于 Open 状态直到收盘自动撤销。建议检查下单价格逻辑(如是否使用了市价单或合理的限价单)。