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

聚宽平台如何批量获取多股票历史行情?(附 get_bars 最佳实践)

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

问题描述

聚宽高效取数:如何用 get_history_batch 批量获取多股票行情?
聚宽多因子策略需要处理大量股票时,如何通过 get_history_batch 分批获取历史行情,降低 API 调用次数并避免超时或失败?

解决方案

在聚宽(JoinQuant)平台中,当我们需要为多因子策略处理大量股票时,频繁在循环中单只调用数据接口(如 attribute_history 或旧版接口)极易导致策略运行缓慢、超时甚至被系统判定为恶意调用而终止。

为了实现高效取数,聚宽官方推荐使用 get_bars 接口。该接口原生支持传入股票代码列表(List),能够一次性批量获取多只股票的历史 K 线数据,从而大幅降低 API 调用次数,提升回测和模拟交易的运行效率。

一、 为什么选择 get_bars 批量取数?

  1. 支持多标的传入security 参数支持传入 listtuple 格式的标的代码,一次性返回所有标的数据。
  2. 性能更优:内部经过底层优化,批量获取的速度远快于在 Python 循环中单只获取。
  3. 灵活的复权与格式控制:支持通过 fq_ref_date 进行定点复权,并可通过 df=True 直接返回便于多因子计算的 pandas.DataFrame(带 MultiIndex 索引)。

二、 get_bars 核心参数解析

  • security: 标的代码或包含交易代码的列表。例如:['000001.XSHE', '600000.XSHG']
  • count: 大于0的整数,表示获取 bar 的个数。
  • unit: bar 的时间单位,如 '1d'(天)、'1m'(分钟)。
  • fields: 获取数据的字段,如 ['date', 'open', 'high', 'low', 'close', 'volume', 'money']
  • df: 是否返回 pandas.DataFrame 对象。批量取数时,强烈建议设置 df=True,此时返回的 DataFrame 索引为 MultiIndex(第一层为标的代码,第二层为行号/时间),非常适合多因子矩阵运算。

三、 批量高效取数代码示例

以下是在聚宽回测/模拟环境或研究环境中,批量获取沪深300成分股最近5天日 K 线数据的完整示例:

import pandas as pd
import datetime
from jqdata import *

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 每天开盘时运行
    run_daily(market_open, time='09:30')

def market_open(context):
    # 1. 获取沪深300成分股列表(约300只股票)
    stock_list = get_index_stocks('000300.XSHG')
    
    # 2. 设定获取的K线数量和字段
    count_num = 5
    fields_list = ['date', 'open', 'high', 'low', 'close', 'volume']
    
    log.info("开始批量获取 %d 只股票的行情数据..." % len(stock_list))
    
    # 3. 使用 get_bars 批量获取数据(设置 df=True 返回 MultiIndex DataFrame)
    # fq_ref_date=context.current_dt.date() 表示以当前回测日期为基准进行前复权
    df_bars = get_bars(
        security=stock_list, 
        count=count_num, 
        unit='1d', 
        fields=fields_list, 
        include_now=False, 
        end_dt=context.current_dt, 
        fq_ref_date=context.current_dt.date(), 
        df=True
    )
    
    # 4. 数据处理示例
    if not df_bars.empty:
        log.info("数据获取成功!")
        # 打印前5行数据查看结构
        print(df_bars.head())
        
        # 提取所有股票的收盘价矩阵 (行索引为日期,列索引为股票代码)
        # 这种矩阵格式非常适合直接进行多因子计算
        close_matrix = df_bars['close'].unstack(level=0)
        print("收盘价矩阵前5行:")
        print(close_matrix.head())

四、 避免超时与失败的避坑指南

  1. 控制单次请求总量:虽然 get_bars 支持批量获取,但单次请求的“股票数量 × count”不宜过大(建议单次总数据量控制在 20 万条以内)。如果股票池有数千只且需要获取较长历史,建议在代码中将股票列表分批(如每 500 只一组)进行获取,然后使用 pd.concat 合并。
  2. 注意停牌处理get_bars 默认不包含停牌的数据。如果某只股票在查询区间内有停牌,返回的 bar 数量可能会少于 count。在多因子计算时,需注意处理非对齐的数据(如使用 unstack 展开后进行 ffill 填充)。
  3. 复权基准日设置:在回测中,fq_ref_date 务必设置为 context.current_dt.date()(动态复权),以避免引入未来函数。