3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(JoinQuant)量化平台上,同一套策略在模拟盘和回测中出现显著的收益差异是量化交易者经常遇到的棘手问题。要彻底解决这一“不一致”痛点,需要从复权模式、交易撮合时点、未来函数、随机因素及系统机制四个维度进行系统化排查:
1. 检查是否开启了动态复权(真实价格)模式
initialize 函数中加入以下代码:def initialize(context):
# 开启真实价格(动态复权)模式
set_option('use_real_price', True)
history、attribute_history 等 API 返回的结果,因为不同日期看到的前复权价格可能不同。1. 盘中运行时间偏差
context.current_dt 仍显示为 09:30。这可能导致模拟盘下单时,某些标的(如股指期货)尚未产生集合竞价,从而因“成交量为0”被拒绝交易。run_monthly > run_weekly > run_daily。请确保您的策略不依赖于这些计划任务的微观执行顺序。2. 撮合规则差异
set_option('match_with_order_book', True)),而回测通常使用 Bar(K线)撮合。如果模拟盘开启了盘口撮合,而回测没有,会导致成交价和成交量出现偏差。set_option('order_volume_ratio', value) 限制单笔订单成交量不超过当日总成交量的一定比例,而模拟盘在未启用盘口撮合时,市价单超出部分会撤单,限价单会挂单。请检查两者的成交量限制参数是否完全一致。1. 开启避免未来数据模式
initialize 中开启未来数据检测:set_option("avoid_future_data", True)
开启后,如果策略尝试获取未来数据,系统会抛出 FutureDataError 异常或自动剔除未来数据。2. 财务数据获取时点
get_fundamentals 在盘后(15:00)才能获取当天交易日的数据。如果在盘中或开盘前调用并使用了当天的财务数据,就会引入未来函数。请确保传入的 date 参数不大于 context.current_dt 的前一天。1. 模拟盘系统延迟与状态保存
g 的序列化限制:模拟盘每天收盘后会休眠并使用 pickle 保存 g 对象。如果 g 中保存了无法序列化的对象(如数据库连接 query、打开的文件、网络连接等),重启后这些变量会丢失或抛出异常。请将这些不可序列化的初始化操作放在 process_initialize(context) 中,并以双下划线 __ 开头命名(如 g.__q),以便系统在序列化时自动忽略。2. 代码修改未在模拟盘生效
initialize 函数不会重新执行。如果修改了全局变量的初始值,必须在 after_code_changed(context) 函数中进行显式修改,否则模拟盘仍会沿用旧的代码逻辑和变量值。3. 排除代码中的随机性
numpy.random)、对 dict 进行无序遍历、或使用了不稳定的排序算法,这些都会导致模拟盘与回测产生分歧。