第四节:数据获取——用Tushare和AkShare抓取期货主力合约

做跨品种套利,数据是地基。地基不稳,房子再漂亮也得塌。

我个人习惯,先把数据源搞定再谈策略。今天咱们就聊聊怎么用Tushare和AkShare这两个库,把期货主力合约数据拿到手。

4.1 为什么选主力合约?

期货市场有个特点——每个品种都有好多月份合约同时交易。比如螺纹钢,有RB2101、RB2105、RB2110……你总不能全拿来做套利吧?

主力合约,说白了就是当前成交量最大、持仓量最多的那个合约。它流动性好,滑点小,最能代表这个品种的真实价格。

我在项目中遇到过一个问题:有次用次主力合约做回测,结果策略表现很好,实盘却亏得一塌糊涂。后来一查,原来是次主力流动性太差,滑点把利润全吃掉了。嗯,从那以后我只用主力合约做套利分析。

核心原则: 跨品种套利必须使用同一时间窗口的主力合约数据,否则价差计算会失真。

4.2 Tushare获取主力合约

Tushare是老牌数据源了,数据质量高,但需要注册获取token。我个人习惯用pro版接口,稳定。

先安装:

pip install tushare

然后获取主力合约连续行情:

import tushare as ts

# 设置token(去tushare官网注册获取)
ts.set_token('你的token')
pro = ts.pro_api()

# 获取螺纹钢主力合约日线数据
df = pro.fut_daily(
    ts_code='RB.SHF',  # 螺纹钢,上海期货交易所
    start_date='20230101',
    end_date='20231231',
    fields='trade_date,open,high,low,close,vol,oi'
)

print(df.head())
小技巧: ts_code的格式是「品种代码.交易所缩写」。SHF是上期所,DCE是大商所,CZCE是郑商所,CFFEX是中金所。记不住?我刚开始也老搞混,后来直接写了个映射表贴在显示器上。

Tushare返回的数据里,vol是成交量,oi是持仓量。主力合约的判定标准就是看这两个指标——谁最大谁就是主力。

4.3 AkShare获取主力合约

AkShare是国产开源库,免费且无需注册。我个人觉得它更适合快速原型开发,数据更新也及时。

安装:

pip install akshare

获取主力合约数据:

import akshare as ak

# 获取螺纹钢主力合约行情
df = ak.futures_main_sina(
    symbol='RB0',  # RB0代表螺纹钢主力连续
    start_date='20230101',
    end_date='20231231'
)

print(df.head())
注意: AkShare的symbol命名规则是「品种代码+0」。比如铁矿石是I0,豆粕是M0,甲醇是MA0。别把0写成O,我见过有人因为这个报错查了半天。

AkShare返回的数据包含日期、开盘价、收盘价、最高价、最低价、成交量、持仓量。跟Tushare结构类似,但字段名略有不同。

4.4 两种数据源对比

对比项 Tushare AkShare
注册 需要 不需要
费用 基础免费,高级付费 完全免费
数据质量 高,有校验 较高,偶尔有延迟
接口稳定性 稳定 偶尔变动
适合场景 生产环境 研究/原型开发

我个人建议:做研究用AkShare,跑实盘用Tushare。为什么?AkShare免费且方便,但接口偶尔会改,实盘时突然报错就麻烦了。Tushare虽然要token,但稳定多了。

4.5 主力合约切换处理

这里有个坑——主力合约不是一成不变的。比如螺纹钢,可能1月是RB2105是主力,2月就变成RB2110了。两个合约价格有差异,直接拼接会出现跳空。

我曾经吃过这个亏:回测时没处理主力切换,结果策略显示年化收益50%,实盘直接亏了。后来才发现是数据拼接出了问题。

处理方法有两种:

  • 向前复权: 把历史数据按当前主力合约调整,消除跳空。Tushare的fut_daily接口默认做了复权处理。
  • 向后复权: 把当前数据按历史合约调整。AkShare的futures_main_sina返回的是原始数据,需要自己处理。

我个人习惯用向前复权,因为更直观——你看到的价格就是当前主力合约的实际价格。

避坑指南: 做跨品种套利时,两个品种的主力切换时间可能不同。比如螺纹钢和热卷,主力切换月份不一样。这时候要确保两个品种的数据在同一时间窗口内都是主力合约,否则价差会失真。

4.6 实战:获取多品种主力数据

咱们来写一个完整的例子,同时获取螺纹钢和热卷的主力数据,为后续套利做准备:

import akshare as ak
import pandas as pd

def get_main_contract(symbol, start, end):
    """
    获取主力合约连续数据
    symbol: 品种代码,如RB0, HC0
    """
    df = ak.futures_main_sina(
        symbol=symbol,
        start_date=start,
        end_date=end
    )
    # 重命名列,统一格式
    df.rename(columns={
        '日期': 'date',
        '开盘价': 'open',
        '收盘价': 'close',
        '最高价': 'high',
        '最低价': 'low',
        '成交量': 'volume',
        '持仓量': 'open_interest'
    }, inplace=True)
    df['date'] = pd.to_datetime(df['date'])
    df.set_index('date', inplace=True)
    return df

# 获取螺纹钢和热卷数据
rb = get_main_contract('RB0', '20230101', '20231231')
hc = get_main_contract('HC0', '20230101', '20231231')

# 合并成一个DataFrame
data = pd.DataFrame({
    'RB_close': rb['close'],
    'HC_close': hc['close'],
    'RB_volume': rb['volume'],
    'HC_volume': hc['volume']
})

# 计算价差
data['spread'] = data['RB_close'] - data['HC_close']

print(data.head())

这段代码我用了好几年,基本没出过问题。唯一要注意的是,AkShare偶尔会返回空数据,建议加个重试机制。

4.7 本章知识体系

下面这张图帮你理清数据获取的整个流程:

期货主力合约数据获取流程 数据源选择 Tushare(生产环境) AkShare(研究环境) 主力合约判定 成交量最大 持仓量最大 流动性最好 数据处理 向前复权 向后复权 主力切换处理 套利价差数据

这张图把整个流程串起来了。你从Tushare或AkShare拿到数据,判定主力合约,处理切换问题,最后得到干净的价差数据。每一步都有坑,但踩过一次就记住了。

我的建议: 刚开始做套利,先用AkShare跑通流程。等策略稳定了,再切换到Tushare做生产环境。别一上来就搞复杂的,先让数据跑起来再说。

专注资料整理