问题描述
解决方案
在聚宽(JoinQuant)平台中,get_price、history(以及 attribute_history)和 get_bars 是获取行情数据的三个核心函数。虽然它们的功能有重叠,但在使用场景、数据包含范围、返回类型以及运行效率上有显著区别。
以下是详细的对比和使用建议:
1. get_price:研究与数据获取的“万能工具”
get_price 是最通用的数据获取函数,既可以在研究环境中使用,也可以在回测/模拟中使用。
- 核心特点:
- 指定日期范围:可以通过
start_date和end_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天的收盘价求平均。因为在盘中决策时,当天的收盘价尚未确定,使用过去的数据才符合逻辑。
- 计算技术指标:例如计算 5日均线(MA5),通常使用
- 局限性:
- 无法获取当前时刻的实时数据(如当前最新价)。
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线、高性能计算 |
场景决策指南
-
我在写策略,需要计算过去5天的平均收盘价,用来做判断:
- 👉 用
attribute_history。 - 理由:它自动处理时间,且不包含今天(避免未来函数),代码最简洁。
- 👉 用
-
我在做研究,想拉取平安银行2020年全年的数据做分析:
- 👉 用
get_price。 - 理由:可以直接指定
start_date='2020-01-01'和end_date='2020-12-31'。
- 👉 用
-
我在写策略,需要在盘中(如10:00)获取包含刚才这一分钟(09:59-10:00)在内的最新10根分钟K线:
- 👉 用
get_bars。 - 理由:设置
include_now=True即可拿到最新的数据,且速度快。
- 👉 用
-
我的策略涉及几千只股票,循环获取数据太慢了:
- 👉 用
get_bars。 - 理由:配合
df=False返回 numpy 数组,计算效率最高。
- 👉 用
Q&A
Q: 为什么 history 不包含当前数据?
A: 为了防止“未来函数”。在日频回测中,handle_data 通常在开盘或盘中运行,此时当天的“收盘价”尚未产生。如果包含了当天的数据(且该数据在回测引擎中通常是全天收盘后的数据),策略就会利用收盘价去指导开盘的交易,导致回测结果虚高,实盘必亏。
Q: get_bars 获取的数据和 get_price 的复权数据一致吗?
A: 一致,但前提是复权参数设置相同。get_bars 的 fq_ref_date 默认为当前时间(动态复权),而 get_price 的 fq 默认为 'pre'(前复权)。在回测开启 set_option('use_real_price', True) 后,两者逻辑基本一致。
Q: 如果我想获取当前的最新价格(Tick级),应该用哪个?
A: 以上三个都是获取 K 线(Bar)数据的。如果需要当前的最新瞬时价格(Tick),请使用 get_current_data() 或 get_current_tick()。