3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在JoinQuant(聚宽)平台上,遇到回测环境与研究环境(如通过 get_backtest 获取数据)中同一个变量值不一致,甚至在研究环境中为 0 的情况,通常是由环境上下文差异或数据获取机制引起的。以下是常见的几个原因及排查建议:
record() 函数的调用时机问题如果你是在回测中通过 record(var=xxx) 记录变量,然后在研究环境中通过 get_backtest(id).get_records() 获取数据,发现值为 0,这通常是因为 记录时机不对。
before_trading_start(开盘前)调用了 record(),此时当天的交易尚未发生,很多基于盘中交易或持仓计算的变量(如当日收益、动态持仓价值等)可能尚未更新,初始值即为 0。record() 函数的调用移动到 handle_data(盘中)或 after_trading_end(收盘后)中,确保变量已经完成了当天的计算更新。回测环境和研究环境在调用数据API时,如果不显式传入日期参数,默认行为是不同的:
context.current_dt(回测的当前逻辑时间)或其前一个交易日(如 get_fundamentals 默认取前一天以避免未来函数)。get_price, get_fundamentals)时,务必显式传入 date 或 end_date 参数,确保与回测时的逻辑时间完全对齐。在回测中,我们通常会在 initialize 中设置 set_option('use_real_price', True)。这会导致回测中获取的历史价格是基于回测当前日期的前复权价格。
fq_ref_date),默认是基于当天的前复权价格。如果回测日期和研究环境当前日期之间发生了分红派息,复权因子不同,计算出的均线、指标等变量就会产生差异。fq 的设置,必要时使用 get_bars 并显式指定 fq_ref_date 为回测当天的日期。某些 API 和对象是回测/模拟盘专用的,例如 get_current_data()、context.portfolio 等。如果在研究环境中尝试复现回测的逻辑,直接调用这些对象会失败或返回空值/0。
context 对象的动态变化。必须依赖 get_backtest(id).get_positions() 或 get_backtest(id).get_portfolio() 等专用方法来提取回测的历史切片状态。history 和 attribute_history 默认不跳过停牌日(使用前一交易日数据填充)。如果在研究环境中使用了不同的参数(如 skip_paused=True),会导致计算周期内的数据长度或数值不同,进而导致计算结果(如移动平均线)不一致。skip_paused 和 fill_paused 参数是否保持一致。context.current_dt,然后在研究环境中严格传入该时间戳获取底层数据,对比底层数据是否一致。0 或 NaN,导致最终结果被异常处理为 0。