🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

聚宽 get_fundamentals 接口连续调用报错怎么办?

joinquant | 发布时间: 2026/6/2
以下内容由 EasyQuant 生成。

问题描述

使用get_fundamentals报错

必现:
使用get_fundamentals接口传参date的时候,第一次可以调用,第二次继续调用该接口的时候date日期与上一次日期不一样,然后会报如下图的错。请问这个怎么使用?我回测的时候每天要拉一下换手率,市值,但是现在跑起来的第二天就报错了

解决方案

在 JoinQuant (聚宽) 的回测环境中,使用 get_fundamentals 接口时,强烈建议不要手动传入 date 参数

报错原因分析

在回测引擎中,系统维护了一个严格的时间上下文(context.current_dt)。根据 API 文档,当 datestatDate 都不传入时,date 的默认值会自动随着回测日期变化而变化,等于 context.current_dt 的前一天(因为在实际交易中,今天只能看到昨天的财务和市值数据)。

如果您手动传入 date,可能会遇到以下问题:

  1. 未来函数报错:如果传入的日期大于当前回测逻辑时间,会触发未来数据异常。
  2. Query 对象复用冲突:在循环中不断修改日期参数,可能会导致底层 SQLAlchemy 的 Query 对象状态异常,从而引发报错。

正确的使用方法

如果您需要在回测中每天拉取换手率(turnover_ratio)和市值(market_cap),只需在 handle_data 或定时运行函数中直接调用 get_fundamentals(q) 即可,不要传 date 参数

代码示例

以下是一个每天获取指定股票池市值和换手率的标准写法:

import jqdata

def initialize(context):
    # 设定要操作的股票池
    g.stocks = ['000001.XSHE', '600000.XSHG']
    # 每天开盘前运行
    run_daily(before_market_open, time='09:00')

def before_market_open(context):
    # 构造查询对象:查询代码、换手率、总市值
    q = query(
        valuation.code,
        valuation.turnover_ratio,
        valuation.market_cap
    ).filter(
        valuation.code.in_(g.stocks)
    )
    
    # 直接调用,不传 date 参数!
    # 系统会自动获取 context.current_dt 前一天的最新数据
    df = get_fundamentals(q)
    
    # 打印查看结果
    log.info("当前回测时间: %s" % context.current_dt)
    log.info("\n%s" % df)
    
    # 您可以将获取到的数据存入全局变量供盘中使用
    g.fund_data = df

总结

  • 回测/模拟中:直接 get_fundamentals(q),系统自动处理时间对齐,避免未来函数。
  • 研究环境中:可以手动传入 date 参数(如 date='2023-01-01')来探究历史特定日期的数据。