Vibe-Trading 数据接入实战:Tushare fina_mainbz 主营业务构成接口深度指南
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
上市公司主营业务构成(按产品、地区、行业三个维度拆分收入与成本)是基本面分析与量化研究中最具信息量的结构化数据之一。本文以 Vibe-Trading 仓库内 Tushare 技能包的核心参考文档 主营业务构成.md 为主体,完整展开fina_mainbz接口的权限门槛、输入输出参数、代码示例与数据样例,并结合仓库内的 Tushare 技能文档、环境变量配置与预检实现,说明如何在 Vibe-Trading 环境中完成 Token 配置、接口调用与数据落地。读完本文,你将掌握按单只股票拉取全历史主营业务构成、按报告期筛选、按产品/地区/行业三种口径取数,以及使用fina_mainbz_vip批量获取某一季度全市场数据的完整方案。
一、接口概览:主营业务构成数据能回答什么问题
fina_mainbz(Main Business Composition)接口用于获取上市公司主营业务构成数据,支持分地区和分产品两种维度,同时提供按行业口径的组织方式。其核心价值在于:
- 收入质量审计:对比
bz_sales(主营业务收入)与bz_profit(主营业务利润)、bz_cost(主营业务成本),可以拆解公司利润的真实来源——是依赖核心产品、单一客户,还是靠"其他"项目撑起收入; - 多元化与集中度研究:按产品计算收入占比与赫芬达尔指数,量化业务集中度风险;
- 地区结构分析:按地区口径观察国内外收入结构,服务出口链、内需链等主题研究;
- 行业景气跟踪:按行业口径对照申万/中信行业分类,辅助判断公司所处赛道的景气位置。
在 Vibe-Trading 中,该文档收录于 agent/src/skills/tushare/references/股票数据/财务数据/ 目录下,与利润表、资产负债表、现金流量表、财务指标等接口文档并列,构成完整的 A 股财务数据接口家族,接口编号为 81(见 SKILL.md 的数据接口列表)。
二、权限要求与积分门槛
接口文档明确标注了访问控制条件,这是调用前必须满足的前提:
| 项目 | 要求 |
|---|---|
| 最低积分 | 2000 积分方可调取 |
| 单次提取行数 | 最大100 行 |
| 总量限制 | 不限制,可通过循环分批获取 |
| 数据粒度 | 只能按单只股票获取其历史数据 |
同时文档给出一个重要提示:如果需要在单个季度获取全部上市公司的数据,请改用fina_mainbz_vip接口(参数一致),需要积攒 5000 积分。
积分不达标时的表现通常是接口直接抛出权限异常,因此在实际项目中,建议先通过 Vibe-Trading 的预检流程确认 Token 与积分状态(详见第六节)。
三、输入参数详解
fina_mainbz的请求参数如下,其中ts_code为必选:
| 名称 | 类型 | 必选 | 描述 |
|---|---|---|---|
| ts_code | str | Y | 股票代码 |
| period | str | N | 报告期(每个季度最后一天的日期,比如 20171231 表示年报) |
| type | str | N | 类型:P 按产品、D 按地区、I 按行业(请输入大写字母 P 或 D) |
| start_date | str | N | 报告期开始日期 |
| end_date | str | N | 报告期结束日期 |
参数使用要点:
ts_code格式遵循 Tushare 全局约定,即000001.SZ、600000.SH这类"代码 + 交易所后缀"格式(见 SKILL.md 的参数格式说明),日期统一为YYYYMMDD格式(如20241231);type三选一:P(产品)与D(地区)为文档明确支持的主口径,I表示按行业口径。注意文档强调请输入大写字母,小写可能导致参数不识别;period与start_date/end_date二选一使用:period用于精确定位某个报告期;而start_date+end_date用于提取一段报告期区间内的数据,适合做跨期对比。两者混用时应以实际返回结果校验;- 未传
period或日期范围时,默认返回该股票全部历史报告期数据(受 100 行/次的限制,可能需要分页循环)。
四、输出参数详解
每次调用返回以下字段:
| 名称 | 类型 | 描述 |
|---|---|---|
| ts_code | str | TS 代码 |
| end_date | str | 报告期 |
| bz_item | str | 主营业务来源 |
| bz_sales | float | 主营业务收入(元) |
| bz_profit | float | 主营业务利润(元) |
| bz_cost | float | 主营业务成本(元) |
| curr_type | str | 货币代码 |
| update_flag | str | 是否更新 |
字段语义与使用提示:
bz_item是整张表的主键语义字段,同一报告期内按不同的拆分口径(产品/地区/行业)给出不同的"主营业务来源"条目;当type=P时,bz_item即产品名,如"聚丙烯""原料药产品""保险业务";bz_sales/bz_profit/bz_cost单位均为元,三者满足收入 − 成本 ≈ 利润的勾稽关系(少数条目仅有收入而无利润/成本,参考下方数据样例中None的情况,此时计算占比时应以收入为主口径);curr_type给出货币代码(A 股通常为CNY),跨境或多币种公司应据此判断是否需要进行汇率归一;update_flag表示该条记录是否为新更新/修订数据,在增量同步与回填校验场景中有用。
五、数据样例解读
文档给出的真实样例(000627.SZ 天茂集团 2017 年报,按产品口径):
ts_code end_date bz_item bz_sales bz_profit bz_cost curr_type 0 000627.SZ 20171231 其他产品 1.847507e+08 None None CNY 1 000627.SZ 20171231 其他主营业务 1.847507e+08 None None CNY 2 000627.SZ 20171231 聚丙烯 6.629111e+07 None None CNY 3 000627.SZ 20171231 原料药产品 2.685909e+08 None None CNY 4 000627.SZ 20171231 保险业务 5.288595e+10 None None CNY对样例的观察结论:
- 多业务并存:该公司同时拥有保险业务、原料药、聚丙烯、其他产品等多条业务线,
bz_item直接给出各业务线的名称,便于做收入贡献排序; - 量级差异悬殊:保险业务收入 5.29e10 元(约 529 亿元),而聚丙烯仅 6.63e7 元(约 6600 万元),说明这是一家以保险为绝对主业的公司——这一结论可直接支撑"业务集中度"类的量化因子;
- 利润/成本缺失:该样例中
bz_profit、bz_cost均为None,说明部分公司/报告期只披露收入不披露分业务的利润与成本。做因子计算时必须对None做缺失值处理,切勿直接求和。
六、代码实战:从 Token 配置到数据落地
6.1 前置准备:配置 Tushare Token
Tushare 的接入以 Token 为核心凭证。在 Vibe-Trading 中,Token 通过环境变量TUSHARE_TOKEN注入,其在 环境变量 Schema 中定义为tushare_token: str = Field(alias="TUSHARE_TOKEN", default=""),即配置名TUSHARE_TOKEN、缺省为空字符串。
配置方式:
# 设置环境变量(或写入项目 .env 文件) export TUSHARE_TOKEN=your_token_here项目启动时,preflight.py 的_check_tushare会读取该 Token,并校验其非空、非占位符"your-tushare-token",同时尝试import tushare验证依赖是否安装,从而在预检阶段就暴露配置问题。
6.2 最小可用调用
import os import tushare as ts # 读取环境变量中的 token token = os.getenv('TUSHARE_TOKEN') # 初始化 pro 接口实例 pro = ts.pro_api(token) # 获取 000627.SZ 按产品口径的主营业务构成 df = pro.fina_mainbz(ts_code='000627.SZ', type='P') print(df.head())也可以参照仓库 股票数据获取示例脚本 的写法,通过项目的统一配置访问器读取 Token(get_env_config().data.tushare_token),在 Vibe-Trading 的 Python 环境下与项目配置体系保持一致:
from src.config.accessor import get_env_config token = get_env_config().data.tushare_token or ts.get_token() pro = ts.pro_api(token)6.3 三种口径与报告期筛选
# 按产品口径 df_p = pro.fina_mainbz(ts_code='000627.SZ', type='P') # 按地区口径 df_d = pro.fina_mainbz(ts_code='000627.SZ', type='D') # 按行业口径 df_i = pro.fina_mainbz(ts_code='000627.SZ', type='I') # 精确指定报告期(2017 年年报) df_2017 = pro.fina_mainbz(ts_code='000627.SZ', type='P', period='20171231') # 报告期区间筛选(2017-2019 三个年度的年报) df_range = pro.fina_mainbz(ts_code='000627.SZ', type='P', start_date='20171231', end_date='20191231')6.4 分页循环取全量历史
由于单次最多返回 100 行,而一只股票在多报告期 × 多产品组合下很容易超过 100 行,需要按报告期逐期循环获取:
import tushare as ts import pandas as pd pro = ts.pro_api(os.getenv('TUSHARE_TOKEN')) ts_code = '000627.SZ' # 先取股票的全部报告期(示例:用 trade_cal / daily 辅助生成,或用固定季度序列) periods = ['20161231', '20171231', '20181231', '20191231'] # 按需补充 frames = [] for period in periods: part = pro.fina_mainbz(ts_code=ts_code, type='P', period=period) if part is not None and not part.empty: frames.append(part) full = pd.concat(frames, ignore_index=True) print(full)要点:period传季度末日期即可命中对应报告期;每个报告期的条目数通常远小于 100 行,因此按报告期分页是最稳妥的全量方案。
6.5 全市场批量取数:fina_mainbz_vip
如需获取某一季度全部上市公司的数据,文档明确要求改用fina_mainbz_vip接口(参数与fina_mainbz完全一致,但需要5000 积分):
df = pro.fina_mainbz_vip(period='20181231', type='P', fields='ts_code,end_date,bz_item,bz_sales')该示例同时展示了fields参数的使用:只取需要的列可以减少网络传输与内存占用。fina_mainbz_vip适用于截面研究——例如在某个报告期对全市场所有公司的主营业务构成做横向扫描,输出行业集中度因子或"收入主要来源"标签。
七、在 Vibe-Trading 技能体系中的定位与配合
主营业务构成不是孤立数据点,它在 Vibe-Trading 中与多个技能和模块形成配合:
- Tushare 技能包:本文档所在的 agent/src/skills/tushare/ 目录以"标准化 API 统一数据资产服务"为设计目标(见 SKILL.md),覆盖股票、基金、期货、数字货币行情与公司财务等基本面数据,
fina_mainbz是其中"股票数据 → 财务数据"分类下的 10 个财务接口之一(同目录还包含利润表、资产负债表、现金流量表、业绩预告/快报、财务审计意见、财务指标、分红送股、财报披露日期等接口文档); - A 股 ST 风险预测技能:A股ST风险预测技能 遵循"tushare 优先、akshare 兜底"的数据规范,其中利润表、财务指标等接口按
ts_code+period拉取并做多期对比。主营业务构成数据可进一步补充"营收红线"判定的证据面——例如判断营收下滑是否由核心产品萎缩导致; - 回测引擎数据加载:仓库 backtest/loaders/tushare_fundamentals.py 展示了 Tushare 财务类接口(如
fina_indicator、income)在回测框架中如何被建模为"表 Schema + 列 Schema",并支持点-in-time(PIT)截断查询。fina_mainbz输出的字段(bz_sales、bz_profit、bz_cost)同样可以采用相同的 Schema 化方式接入因子库。
八、常见问题与边界条件
- 积分不足:
fina_mainbz需 2000 积分,fina_mainbz_vip需 5000 积分。积分不足时接口报权限错误,可参考官方积分获取办法提升积分,或改用免费数据源兜底(如仓库 AKShare 技能 中描述的"tushare 不可用时回退 akshare"策略); type大小写:文档要求传大写P或D,小写可能被拒绝或返回空,建议调用前做type.upper()归一化;- 100 行上限:多报告期全量数据必须分页循环,否则数据被截断;
- 单只股票限制:普通接口无法按季度做全市场截面扫描,截面场景必须使用
fina_mainbz_vip; - 利润/成本字段缺失:
bz_profit、bz_cost可能为None,因子计算需显式处理缺失值(fillna(0)或按口径剔除); - 单位:
bz_sales等字段单位为元,与部分其他接口(如市值为万元)不一致,跨接口拼表时务必统一量纲。
九、总结
fina_mainbz是 A 股财务数据接口中"颗粒度最细、维度最灵活"的一类——它把一家公司的收入从"一个总数"拆解为"产品/地区/行业 × 报告期"的二维网格,为业务集中度、多元化溢价、地区结构与收入质量等研究提供直接数据支撑。本文以 主营业务构成.md 为骨架,完整覆盖了 2000 积分权限门槛、输入输出参数表、按产品/地区/行业三种口径的取数方式、单只股票历史数据的分页循环,以及fina_mainbz_vip的全市场批量方案,并结合 Vibe-Trading 的 Token 配置、preflight 预检与技能体系说明了落地路径。实践中建议将本接口与利润表(income)、财务指标(fina_indicator)配合使用,形成"总量 + 结构"的完整基本面分析闭环。
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考