3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant(聚宽)量化平台中,使用 get_bars 获取多个标的的行情数据并设置 df=True 时,系统会返回一个带有 MultiIndex(双层复合索引) 的 pandas.DataFrame。理解并高效处理这种数据结构是编写多股票/期货策略的核心技能。
当传入标的列表(如 ['000001.XSHE', '600000.XSHG'])并设置 df=True 时,返回的 DataFrame 的行索引(Index)包含两层:
000001.XSHE)2023-01-03)列字段(Columns)通常包括:date, open, high, low, close, volume, money 等。
xs 方法)使用 .xs() 可以按指定层级快速提取某一标的的数据:
# 获取 000001.XSHE 的所有历史 Bar 数据
df_pingan = df.xs('000001.XSHE', level=0)
print(df_pingan.head())
unstack 方法)在多因子策略或配对交易中,常常需要构建“行是时间,列是股票代码”的价格矩阵,使用 unstack 最为高效:
# 提取 close 列并重构索引,生成以时间为行、标的为列的 DataFrame
close_matrix = df['close'].unstack(level=0)
print(close_matrix)
reset_index 方法)如果希望以常规的列形式处理 code 和 date,可以使用 reset_index:
# 将复合索引转换为普通列
flat_df = df.reset_index()
# 提取特定条件的数据
pingan_bars = flat_df[flat_df['level_0'] == '000001.XSHE']
IndexSlice 进行多维高效切片利用 pd.IndexSlice 可以精准筛选特定标的和时间段:
idx = pd.IndexSlice
# 筛选 000001.XSHE 在指定时间段的数据
sub_df = df.loc[idx['000001.XSHE', '2023-01-01':'2023-01-10'], :]
以下代码展示了如何在 JoinQuant 策略中通过 get_bars 获取多标的数据并进行 MultiIndex 解析与信号计算:
from jqdata import *
import pandas as pd
def initialize(context):
g.securities = ['000001.XSHE', '600000.XSHG', '000002.XSHE']
run_daily(market_open, time='9:30')
def market_open(context):
# 1. 获取多标的最近 20 个交易日日 K 线数据
bars = get_bars(
security=g.securities,
count=20,
unit='1d',
fields=['date', 'close'],
include_now=False,
df=True
)
# 2. 转换成以时间为行、股票为列的收盘价矩阵
close_df = bars['close'].unstack(level=0)
# 3. 批量计算各标的的 5 日与 20 日均线
ma5 = close_df.tail(5).mean()
ma20 = close_df.mean()
# 4. 遍历提取判断计算结果
for code in g.securities:
current_ma5 = ma5[code]
current_ma20 = ma20[code]
log.info(f"{code} MA5: {current_ma5:.2f}, MA20: {current_ma20:.2f}")
unstack(level=0):将多标的的长表(Long format)转为宽表(Wide format),方便直接进行矩阵运算与向量化操作(如计算收益率、计算相关系数等),比循环遍历快数十倍。fields 参数:仅获取策略所需的字段(如 ['date', 'close']),可显著减少内存开销与数据解析耗时。get_bars:一次性传入标的列表获取 MultiIndex DataFrame,比在 for 循环中逐个标的调用 get_bars 效率更高。