get_bars,attribute_history区别?
close_data = attribute_history(security, 5, '1d', ['close'])
MA5 = close_data['close'].mean()
close_data = get_bars(security, count=5, unit='1d', fields=['close'])
MA5 = close_data['close'].mean()
问题描述
解决方案
在 JoinQuant (聚宽) 平台中,get_bars 和 attribute_history 都可以用来获取历史行情数据,但它们在默认参数、返回值类型、复权处理以及停牌处理上存在显著差异。
核心区别对比
| 特性 | attribute_history |
get_bars |
|---|---|---|
| 支持标的数量 | 仅支持单个标的 | 支持单个或多个标的 |
| 返回值类型 | 默认返回 pandas.DataFrame (df=True) |
默认返回 numpy.ndarray (df=False) |
| 复权方式 | 默认前复权 (fq='pre') |
默认不复权 (fq_ref_date=None) |
| 停牌处理 | 默认跳过停牌 (skip_paused=True),用前一交易日数据填充 |
无跳过停牌选项,直接返回实际交易的 Bar,不足 count 个不填充 |
| 包含当前 Bar | 默认不包含当前 Bar(无未来函数) | 可通过 include_now 参数控制是否包含当前 Bar |
对您提供的代码分析
代码 1:使用 attribute_history
close_data = attribute_history(security, 5, '1d', ['close'])
MA5 = close_data['close'].mean()
分析:
- 这段代码运行完全正常。
close_data是一个 DataFrame,包含了过去 5 天的前复权收盘价,并且自动处理了停牌(如果这 5 天内有停牌,会用停牌前的价格填充)。- 计算出的
MA5是准确的复权均线。
代码 2:使用 get_bars
close_data = get_bars(security, count=5, unit='1d', fields=['close'])
MA5 = close_data['close'].mean()
分析:
- 这段代码存在两个潜在问题:
- 数据类型问题:
get_bars默认返回numpy.ndarray。虽然 numpy 结构化数组支持close_data['close'].mean()的写法,但如果您后续想使用 pandas 的高级特性,会不太方便。 - 复权问题(致命):
get_bars默认获取的是不复权数据。如果这 5 天内股票发生了分红派息或拆股,计算出的MA5将会出现严重跳空,导致策略发出错误信号。
- 数据类型问题:
如何正确替换为 get_bars?
如果您想使用 get_bars 来替代 attribute_history 计算均线,需要显式指定返回 DataFrame 并设置复权基准日(通常设为当前时间以获取前复权数据):
# 正确的 get_bars 用法(在回测/模拟的 handle_data 中)
close_data = get_bars(security, count=5, unit='1d', fields=['close'],
df=True, # 指定返回 DataFrame
fq_ref_date=context.current_dt.date() # 指定复权基准日,获取前复权数据
)
MA5 = close_data['close'].mean()
总结建议
- 如果您只是在
handle_data中获取单只股票的历史数据计算技术指标(如均线),使用attribute_history更简单直接,因为它的默认参数就是为此设计的。 - 如果您需要同时获取多只股票的数据,或者需要获取包含当前时刻 (include_now=True) 的快照数据,则必须使用
get_bars,但请务必注意手动设置df=True和fq_ref_date参数。