Vibe-Trading 期货历史分钟行情接入指南:基于 Tushare ft_mins 接口的全市场期货分钟数据获取实战
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
本篇技术指南围绕 Tushare 财经数据接口包中的ft_mins(期货历史分钟行情)接口展开,讲解如何在 Vibe-Trading 项目中获取全市场期货合约的 1/5/15/30/60 分钟行情数据,覆盖输入输出参数、Python SDK 调用方式、8000 行限量下的历史数据循环拉取策略,以及通过主力合约映射(fut_mapping)构建连续主力分钟序列的完整流程。读完本文后,你将能够独立编写可复用的期货分钟数据采集脚本,并理解 Vibe-Trading 回测数据加载层对 Tushare 分钟接口的底层适配逻辑。
接口概览:ft_mins 是什么
ft_mins是 Tushare 提供的期货历史分钟行情接口,用于获取全市场期货合约的分钟级 K 线数据。根据 历史分钟行情文档 的定义,该接口具备以下关键特征:
| 属性 | 说明 |
|---|---|
| 接口名 | ft_mins |
| 数据范围 | 全市场期货合约(上期所、大商所、郑商所、中金所、能源中心、广期所) |
| 分钟频度 | 1min / 5min / 15min / 30min / 60min |
| 单次限量 | 单次最大8000 行数据 |
| 历史深度 | 可提供超过10 年历史分钟数据 |
| 访问方式 | Python SDK 与 HTTP Restful API 两种 |
| 权限要求 | 120 积分可调取 2 次接口查看数据,正式权限需要更高的积分等级 |
需要注意的是,ft_mins返回的是具体月份合约(如CU2310.SHF)的分钟行情。如果需要主力合约的分钟数据,必须先通过主力合约映射接口(fut_mapping)获取每个交易日对应的主力月合约代码,再逐个提取其分钟行情。这一映射关系在 期货主力与连续合约文档 中有完整定义,本文后续章节会给出完整操作流程。
输入参数详解
ft_mins接口共四个输入参数,其中ts_code与freq为必选:
| 名称 | 类型 | 必选 | 描述 |
|---|---|---|---|
ts_code | str | Y | 期货合约代码,如CU2310.SHF |
freq | str | Y | 分钟频度(1min/5min/15min/30min/60min) |
start_date | datetime | N | 开始日期,格式:2023-08-25 09:00:00 |
end_date | datetime | N | 结束时间,格式:2023-08-25 19:00:00 |
合约代码规则(ts_code)
期货合约代码遵循"品种 + 交割年月 + 交易所后缀"的约定,例如:
CU2310.SHF:上期所沪铜 2023 年 10 月合约(CU2310 为沪铜 2310 合约,SHF 为上期所缩写)P0805.DCE:大商所棕榈油 0805 合约(数据样例见 合约信息文档)TF.CFX:中金所十年期国债主力/连续合约
所有交易所代码与标准合约品种均可通过 期货合约信息表 fut_basic 接口查询,该接口输出ts_code、symbol、name、fut_code、list_date、delist_date等字段,可用于校验合约代码合法性以及确定合约的上市与退市区间。
时间参数格式
start_date与end_date使用带时分秒的 datetime 字符串,这是分钟接口与日线接口(日线使用YYYYMMDD格式)最显著的区别。例如拉取沪铜 2310 合约某个交易日的完整分钟行情:
start_date='2023-08-25 09:00:00' end_date='2023-08-25 19:00:00'日盘与夜盘的时间段(如上期所日盘 9:00 开盘、夜盘收盘约 19:00 或次日凌晨)都在一个交易日的时间窗口内被覆盖,因此查询时把结束时间放到当日收盘后,即可一次取全日盘与夜盘分钟数据。
freq 参数说明
freq决定分钟 K 线的聚合粒度,可选值如下:
| freq | 说明 |
|---|---|
| 1min | 1 分钟 |
| 5min | 5 分钟 |
| 15min | 15 分钟 |
| 30min | 30 分钟 |
| 60min | 60 分钟 |
值得注意的是,Tushare 各分钟接口对 freq 的大小写约定并不完全一致:ft_mins使用小写1min/5min/15min/30min/60min,而实时分钟接口rt_fut_min使用大写1MIN/5MIN/15MIN/30MIN/60MIN(见 实时分钟行情文档)。在实际调用时务必与接口文档对齐。
Vibe-Trading 回测数据加载层对频率做了统一封装:在 agent/backtest/loaders/tushare.py 中,内部使用的1m/5m/15m/30m/1H间隔会被映射到 Tushare 的1min/5min/15min/30min/60min:
freq_map = {"1m": "1min", "5m": "5min", "15m": "15min", "30m": "30min", "1H": "60min"} freq = freq_map.get(interval) if not freq: logger.error("unsupported Tushare interval: %s", interval) return {}这意味着在 Vibe-Trading 中配置回测interval='1H'时,底层实际请求的正是freq='60min'的分钟数据。
输出参数详解
ft_mins每次调用返回一个 pandas DataFrame,共 9 个字段:
| 名称 | 类型 | 默认显示 | 描述 |
|---|---|---|---|
ts_code | str | Y | 合约代码 |
trade_time | str | Y | 交易时间 |
open | float | Y | 开盘价(元) |
close | float | Y | 收盘价(元) |
high | float | Y | 最高价(元) |
low | float | Y | 最低价(元) |
vol | int | Y | 成交量(手) |
amount | float | Y | 成交金额(元) |
oi | float | Y | 持仓量(手) |
字段语义与单位
- OHLC 价格字段(
open/close/high/low):单位为元,是期货合约该分钟内的开盘、收盘、最高、最低成交价。 vol(成交量):单位为手。这与股票数据的"股/份"单位不同,期货一手对应合约规定的一定吨数/数量,具体每手数量可在fut_basic的trade_unit/per_unit字段中查询。amount(成交金额):单位为元。注意这与期货日线接口fut_daily的amount(单位为万元)不同,分钟接口直接以元为单位返回。oi(持仓量/未平仓量):单位为手,反映该分钟收盘时刻市场未平仓合约总量,是期货分析中判断资金持仓意图的重要指标。
数据样例解读
原文档给出沪铜CU2310.SHF在 2023-08-25 的部分 1 分钟数据(共 225 行):
ts_code trade_time open close high low vol amount oi 0 CU2310.SHF 2023-08-25 15:00:00 68920.0 68930.0 68940.0 68910.0 373.0 128543250.0 146733.0 1 CU2310.SHF 2023-08-25 14:59:00 68910.0 68920.0 68930.0 68910.0 300.0 103379650.0 146751.0 ... 224 CU2310.SHF 2023-08-25 09:01:00 68680.0 68710.0 68740.0 68680.0 868.0 298156350.0 145178.0从样例中可以观察到几个工程要点:
- 时间倒序返回:接口返回的数据按
trade_time倒序排列(15:00 在前、09:01 在后),拿到数据后应按时间升序排序再进入回测或指标计算流程。Vibe-Trading 的分钟加载逻辑正是这样处理的(见 tushare.py:df = df.sort_values("trade_time"))。 oi随交易推进递增:从早盘 09:01 的 145178 手到晚盘 15:00 的 146733 手,持仓量全天缓慢累积,可用于跟踪资金进场节奏。- 一天分钟数可估算:沪铜含日盘(约 3.75 小时)与夜盘(约 5 小时),1 分钟粒度全天约 225 行左右,与样例 225 行吻合。这提示单日 1min 数据量远小于 8000 行限量,可放心一次拉取多日。
接口用法:Python SDK 实战
原文档给出的最简调用方式如下:
pro = ts.pro_api() df = pro.df = pro.ft_mins(ts_code='CU2310.SHF', freq='1min', start_date='2023-08-25 09:00:00', end_date='2023-08-25 19:00:00')在此基础上,结合 tushare 技能主文档 中的初始化约定,推荐写成一个完整可运行的脚本:
import os import tushare as ts # 方式一:从环境变量读取 token token = os.getenv('TUSHARE_TOKEN') or ts.get_token() # 初始化 pro 接口实例 pro = ts.pro_api(token) # 拉取沪铜 2310 合约 2023-08-25 全天 1 分钟行情 df = pro.ft_mins( ts_code='CU2310.SHF', freq='1min', start_date='2023-08-25 09:00:00', end_date='2023-08-25 19:00:00', ) print(df)初始化前置条件
- 安装 Python 环境(推荐 Python 3.7+)与 tushare 依赖包:
pip install tushare - 注册 Tushare 账号获取 token,并配置环境变量:
export TUSHARE_TOKEN=your_token - 确认账户积分满足接口权限要求(
ft_mins需要 120 积分起步,正式大量调用需更高积分档位)。
同时支持 HTTP Restful API
除 Python SDK 外,ft_mins还提供 HTTP Restful API 方式,可用于非 Python 技术栈(如 Node.js、Go、Shell 脚本)接入,接口路径与参数与 SDK 调用一一对应。Vibe-Trading 的技能生态中,tushare SKILL.md 统一以"标准化 API 方式对外服务数据",两种方式获取到的数据形态一致。
8000 行限量下的历史数据循环拉取策略
ft_mins单次最大返回8000 行,而接口可提供超过 10 年的历史分钟数据,两者叠加意味着批量历史分钟数据必须分片循环拉取。具体策略为:
- 按合约 + 时间窗分片:将目标区间按时间段切分,使每个时间片内的分钟行数不超过 8000 行。例如 1min 数据按"每 30 个交易日"一片(沪铜单日约 225 行,30 天约 6750 行,安全落在限量内);5min 及以上频度可适当扩大时间窗。
- 按交易日循环:更稳健的做法是逐交易日(或逐周)循环调用,对每个时间片追加合并结果:
import pandas as pd pro = ts.pro_api(token) frames = [] cursor = pd.Timestamp('2023-08-01 09:00:00') end = pd.Timestamp('2023-08-31 19:00:00') while cursor < end: # 每次拉取 5 个交易日 slice_end = min(cursor + pd.Timedelta(days=7), end) df = pro.ft_mins( ts_code='CU2310.SHF', freq='5min', start_date=cursor.strftime('%Y-%m-%d %H:%M:%S'), end_date=slice_end.strftime('%Y-%m-%d %H:%M:%S'), ) if df is not None and not df.empty: frames.append(df) cursor = slice_end all_minutes = pd.concat(frames, ignore_index=True) all_minutes = all_minutes.sort_values('trade_time').reset_index(drop=True)- 频率对行数的约束:同样时间区间内,1min 数据行数是 5min 的 5 倍、是 60min 的 60 倍。因此 1min 历史数据建议按"天/周"级切片,而 60min 数据可以按"月/季"级切片,以保证每片不超过 8000 行。
主力合约分钟行情:fut_mapping 映射流程
ft_mins只支持具体月份合约。要构建主力合约连续分钟序列(这是回测中最为常用的数据形态),必须配合 期货主力与连续合约接口 fut_mapping 分两步完成:
第一步:获取主力合约映射
# 获取十年期国债主力合约 TF.CFX 每个交易日对应的具体月合约 df_map = pro.fut_mapping(ts_code='TF.CFX')该接口返回三列:ts_code(连续合约代码)、trade_date(起始日期)、mapping_ts_code(该日对应的期货月合约代码)。样例数据如下:
ts_code trade_date mapping_ts_code 0 TF.CFX 20190823 TF1912.CFX 1 TF.CFX 20190822 TF1912.CFX ... 10 TF.CFX 20190809 TF1909.CFX可见主力合约会随换月发生跳变:2019-08-12 之后主力从TF1909.CFX切换为TF1912.CFX。
第二步:按映射代码逐个提取分钟数据
frames = [] for _, row in df_map.iterrows(): contract = row['mapping_ts_code'] day = row['trade_date'] # YYYYMMDD df = pro.ft_mins( ts_code=contract, freq='60min', start_date=f'{day[:4]}-{day[4:6]}-{day[6:]} 09:00:00', end_date=f'{day[:4]}-{day[4:6]}-{day[6:]} 19:00:00', ) if df is not None and not df.empty: frames.append(df) main_minutes = pd.concat(frames, ignore_index=True).sort_values('trade_time')需要注意,fut_mapping需要至少2000 积分才能调取(期货主力与连续合约文档),积分门槛高于ft_mins本身,规划项目时要预留足够的积分档位。
与其他期货数据接口的协同
ft_mins属于期货数据族中的历史分钟通道,与同族接口组合可构成完整的研究数据底座:
| 接口 | 用途 | 与 ft_mins 的配合场景 |
|---|---|---|
| fut_mapping 主力与连续合约 | 主力/连续合约与月合约映射 | 定位每个交易日的主力月合约,再走 ft_mins 拉分钟 |
| rt_fut_min 实时分钟行情 | 实时分钟数据(支持 WebSocket) | 盘中增量更新,与 ft_mins 历史段拼接成完整分钟序列 |
| fut_basic 合约信息 | 合约列表、上市/退市日期 | 校验 ts_code、确定合约有效数据区间 |
| fut_daily 日线行情 | 日线级 OHLC + 结算价 | 日线/分钟多周期对齐,分钟级策略的日线背景 |
| trade_cal 交易日历 | 各交易所交易日历 | 生成循环拉取的时间序列,跳过休市日 |
| fut_settle 每日结算参数 | 结算价、保证金率、手续费率 | 分钟策略接入真实的保证金与手续费成本模型 |
其中 交易日历 trade_cal 对分钟数据拉取尤其重要:它输出exchange、cal_date、is_open(0 休市 / 1 交易)字段,可以据此生成"只包含交易日"的循环窗口,避免对休市日发请求浪费分钟数据限量额度:
cal = pro.trade_cal(exchange='SHFE', start_date='20230801', end_date='20230831', is_open='1') trade_days = sorted(cal['cal_date'].tolist())Vibe-Trading 中的数据层适配:源码级佐证
在 Vibe-Trading 项目中,Tushare 被封装为回测数据加载器之一,定义于 agent/backtest/loaders/tushare.py。虽然该 Loader 当前主要服务 A 股(markets = {"a_share", "hk_equity", "fund"}),但其对 Tushare 分钟接口的底层处理逻辑对理解ft_mins有直接参考价值:
1. 分钟频率映射
如前述,tushare.py 将回测配置的1m/5m/15m/30m/1H映射为 Tushare 的1min/5min/15min/30min/60min。如果你在项目中通过interval='1H'请求期货数据,理论上对应的正是ft_mins(freq='60min')的数据口径。
2. 数据归一化处理
从源码可以看到分钟数据拉回后的标准处理流水线(tushare.py):
df = df.sort_values("trade_time") # 时间升序 df["trade_date"] = pd.to_datetime(df["trade_time"]) # trade_time -> 时间索引 df = df.set_index("trade_date") df = df.rename(columns={"vol": "volume"}) # vol -> volume 统一命名这对应了ft_mins输出字段与回测框架 OHLCV 口径的适配约定:trade_time转为索引、vol重命名为volume、数值列统一to_numeric强转并剔除 OHLC 缺失行。
3. 限流退避机制
Tushare 分钟接口对调用频率敏感(文档标注"每分钟可以请求 500 次"是针对实时接口,历史接口同样存在每分钟配额)。tushare.py 实现了针对配额拒绝的三级退避:
_RATE_LIMIT_BACKOFF_SECONDS: tuple[float, ...] = (5.0, 20.0, 40.0)并且通过识别异常消息中的"每分钟/每天/抽取/频率/rate limit"等关键词(tushare.py),只对配额拒绝进行重试、对真正失败立即抛出。在为ft_mins编写批量循环拉取脚本时,强烈建议复刻这套策略:命中配额限制后依次等待 5s、20s、40s 再重试,避免高频循环把单次 8000 行限量变成无效调用。
4. 期货数据支持的边界说明
需要如实说明的是:Vibe-Trading 当前 Tushare Loader 明确不声明期货市场支持(源码注释提及futures被有意排除,原因是fut_daily位于积分档位之后,见 tushare.py)。因此,ft_mins在当前仓库中的直接消费方式,是以Tushare 技能文档 + 独立 Python 脚本的形式供研究人员调用;将期货分钟数据接入回测引擎仍需自行在 Loader 层补齐fut_daily/ft_mins的积分与端点适配。这一点从 tushare 技能目录 中完整的期货数据接口文档体系可以看出——仓库以"技能文档 + 示例脚本"的方式沉淀了全套期货数据接入知识。
常见问题与工程建议
Q1:返回数据为什么是倒序的?ft_mins按trade_time倒序返回。任何后续计算前都应执行sort_values('trade_time')升序排序。
Q2:一天的数据超过 8000 行怎么办?单日 1min 数据(约 225 行量级)远小于限量;但若一次请求跨多个合约或多个月份可能触限。按合约 + 时间段切片循环,每片控制在 8000 行以内。
Q3:想拉主力合约分钟数据直接传CU.SHF可以吗?不可以。ft_mins只接受具体月合约代码(如CU2310.SHF),主力连续代码需要先用fut_mapping解析出每个交易日的mapping_ts_code再提取。
Q4:历史 10 年 1min 数据要跑多久?假设单合约日均约 225 行、每片 8000 行,约 35 个交易日一片;10 年约 2450 个交易日,约 70 次请求可拉完单合约全历史 1min。配合限流退避与交易日历跳过休市日,可在合理时间内完成全市场多合约的历史分钟建库。
Q5:如何确认当前合约代码有效?通过 fut_basic 合约信息接口 查询list_date(上市日期)与delist_date(最后交易日期),只对处于上市期内的合约发起ft_mins请求。
总结
ft_mins是获取国内全市场期货历史分钟数据的核心通道,其"单次 8000 行、10 年历史深度、六档频率"的特性决定了正确的使用姿势是合约 + 时间窗口循环分片拉取,而"具体月合约 + fut_mapping 主力映射"的组合则是构建主力连续分钟序列的标准路径。本文给出的调用代码、循环策略、限流退避与字段单位说明,结合 Tushare 技能主文档 及 期货数据参考文档目录,足以支撑你在 Vibe-Trading 项目中独立完成期货分钟数据的研究与工程化接入。
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考