🚀 AI 一键生成 joinquant 策略代码

JoinQuant API 对比:get_price, history, attribute_history 和 get_bars 应该如何选择?

joinquant | 发布时间: 2025/12/11
以下内容由 EasyQuant 生成。

问题描述

获取历史数据的函数有好几个,比如 get_price, history, get_bars,它们有什么区别?在什么情况下应该用哪个?

解决方案

在聚宽(JoinQuant)平台中,get_pricehistory(以及 attribute_history)和 get_bars 是获取行情数据的三个核心函数。虽然它们的功能有重叠,但在使用场景数据包含范围返回类型以及运行效率上有显著区别。

以下是详细的对比和使用建议:

1. get_price:研究与数据获取的“万能工具”

get_price 是最通用的数据获取函数,既可以在研究环境中使用,也可以在回测/模拟中使用。

  • 核心特点
    • 指定日期范围:可以通过 start_dateend_date 获取指定绝对时间段的数据。
    • 数据处理:默认会对停牌数据进行填充(使用前一交易日数据),保证时间轴连续。
    • 返回类型pandas.DataFrame(多标的时曾返回 Panel,现多建议设 panel=False 返回 DataFrame)。
  • 适用场景
    • 研究环境:主要用于在 Notebook 中拉取历史数据进行分析、绘图或因子研究。
    • 回测中:当你需要获取一段固定时间范围的数据,或者需要获取包含当前时间点(视参数而定)的数据时。
  • 局限性
    • 相比 get_bars,速度稍慢。
    • 在回测中如果 end_date 设置不当,容易引入未来函数。

2. history / attribute_history:回测专用的“防未来函数”工具

这两个函数是回测/模拟交易专用的 API,无法在研究环境中直接调用。它们的设计初衷是为了方便策略编写并防止未来函数。

  • 核心特点
    • 相对时间:不需要指定日期,它自动基于策略当前的运行时间(context.current_dt)向前获取 count 个单位的数据。
    • 不包含当前数据:这是最重要的特性。history 获取的数据严格不包含当前单位时间的数据
      • 例如:在日频回测的 handle_data 中调用 history(5, '1d', ...),获取的是昨天及过去4天的数据,不包含今天。
    • 返回类型
      • history:可查询多个标的、单个字段,返回 DataFrame 或 Dict。
      • attribute_history:查询单个标的、多个字段,返回 DataFrame 或 Dict。
  • 适用场景
    • 计算技术指标:例如计算 5日均线(MA5),通常使用 attribute_history 获取过去5天的收盘价求平均。因为在盘中决策时,当天的收盘价尚未确定,使用过去的数据才符合逻辑。
  • 局限性
    • 无法获取当前时刻的实时数据(如当前最新价)。

3. get_bars:高性能与实时数据的“利器”

get_bars 是较新的 API,旨在提供更快的速度和更灵活的数据获取方式,支持获取当前时刻的数据。

  • 核心特点
    • 高性能:底层优化,获取速度快,默认返回 numpy.ndarray(也可设 df=True 返回 DataFrame)。
    • 包含当前数据:通过参数 include_now=True,可以获取包含当前分钟/当天的 bar。
    • 原始数据不跳过停牌,也不填充停牌数据。如果请求 100 个 bar,中间有停牌,它会跨过停牌日期往前找,直到凑齐 100 个实际交易的 bar(除非上市时间不足)。
    • 复权灵活:支持指定复权基准日。
  • 适用场景
    • 需要包含当前数据:例如策略需要在 14:50 分利用包含当天的 K 线计算指标。
    • 性能敏感:策略计算量大,需要极快的数据读取速度。
    • 非标准周期:支持如 '3m' (3分钟) 等非标准 K 线合成。
  • 局限性
    • 数据未填充停牌,如果策略依赖时间轴对齐(如多股票协方差计算),需要自己处理对齐。

总结对比表

特性 get_price history / attribute_history get_bars
主要环境 研究环境 / 回测 仅回测/模拟 研究环境 / 回测
时间指定 绝对时间 (Start/End) 相对时间 (Count) 相对时间 (Count) + 截止时间
包含当前Bar 视 end_date 而定 否 (严格不包含) 可配置 (include_now)
停牌处理 默认填充 (Fill) 默认填充 不填充 (跳过)
返回类型 DataFrame DataFrame / Dict Array (默认) / DataFrame
运行速度 中等 中等
典型用途 研究分析、获取特定日期数据 策略中计算MA、MACD等指标 高频策略、获取实时K线、高性能计算

场景决策指南

  1. 我在写策略,需要计算过去5天的平均收盘价,用来做判断:

    • 👉 用 attribute_history
    • 理由:它自动处理时间,且不包含今天(避免未来函数),代码最简洁。
  2. 我在做研究,想拉取平安银行2020年全年的数据做分析:

    • 👉 用 get_price
    • 理由:可以直接指定 start_date='2020-01-01'end_date='2020-12-31'
  3. 我在写策略,需要在盘中(如10:00)获取包含刚才这一分钟(09:59-10:00)在内的最新10根分钟K线:

    • 👉 用 get_bars
    • 理由:设置 include_now=True 即可拿到最新的数据,且速度快。
  4. 我的策略涉及几千只股票,循环获取数据太慢了:

    • 👉 用 get_bars
    • 理由:配合 df=False 返回 numpy 数组,计算效率最高。

Q&A

Q: 为什么 history 不包含当前数据?
A: 为了防止“未来函数”。在日频回测中,handle_data 通常在开盘或盘中运行,此时当天的“收盘价”尚未产生。如果包含了当天的数据(且该数据在回测引擎中通常是全天收盘后的数据),策略就会利用收盘价去指导开盘的交易,导致回测结果虚高,实盘必亏。

Q: get_bars 获取的数据和 get_price 的复权数据一致吗?
A: 一致,但前提是复权参数设置相同。get_barsfq_ref_date 默认为当前时间(动态复权),而 get_pricefq 默认为 'pre'(前复权)。在回测开启 set_option('use_real_price', True) 后,两者逻辑基本一致。

Q: 如果我想获取当前的最新价格(Tick级),应该用哪个?
A: 以上三个都是获取 K 线(Bar)数据的。如果需要当前的最新瞬时价格(Tick),请使用 get_current_data()get_current_tick()