Vibe-Trading Tushare 数据接入指南:申万行业分类接口 index_classify 全解析与量化应用
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
申万行业分类是 A 股量化研究中最常用的行业划分标准之一。本文以 Vibe-Trading 仓库内 Tushare 技能文档为骨架,系统讲解index_classify接口的权限要求、入参与出参约定、调用示例,并完整呈现 2021 版申万行业分类体系(31 个一级行业、134 个二级行业、346 个三级行业)的清单与变动规律,同时结合仓库内 sector-rotation 技能、申万行业成分(分级).md)、申万行业指数日行情 等资源,说明如何把行业分类数据串联成完整的行业轮动与行业配置分析流水线。读完本文,你将能够独立获取申万行业分类清单,理解新旧版本差异,并将分类数据接入自己的因子库与策略框架。
一、申万行业分类体系概览
申万行业分类是申万宏源证券研究所发布的上市公司行业划分标准,也是 A 股行业研究、指数编制和量化投资中事实上的行业基准。Tushare 通过index_classify接口提供两个历史版本的分类列表:
| 版本 | 一级分类 | 二级分类 | 三级分类 | 说明 |
|---|---|---|---|---|
| 申万 2014 年版(SW2014) | 28 个 | 104 个 | 227 个 | 早期常用版本 |
| 申万 2021 年版(SW2021) | 31 个 | 134 个 | 346 个 | 当前默认推荐版本 |
从文档与仓库使用情况看,2021 版是当前主推版本:申万行业指数日行情 明确注明"默认是申万 2021 版行情",sector-rotation 技能 也直接以"31 个一级行业"作为行业轮动分析的分类基础。
2021 版与 2014 版的差异要点
相较于 2014 版,2021 版的主要变化体现在:
- 一级行业数量增加:由 28 个扩充到 31 个,新增了煤炭、石油石化、环保、美容护理等独立一级行业(如 740000 煤炭、750000 石油石化、760000 环保、770000 美容护理均为
2021新增); - 细分颗粒度提升:三级行业由 227 个增加到 346 个,细分方向明显变多(如电池、光伏设备、风电设备、电网设备从旧体系中拆分为独立二级/三级行业);
- 命名规范化:大量行业名称统一加"Ⅱ""Ⅲ"后缀以区分层级(如"中药Ⅱ""中药Ⅲ""动物保健Ⅱ""动物保健Ⅲ"),避免上下级名称混淆;
- 代码替换与迁移:部分三级行业沿用旧代码或整体迁移到新父级(变动原因标注为"2021替换代码xxx"),例如农化制品下的氮肥
850331替换旧代码220301。
从仓库内 申万行业分类.md 的完整清单看,变动原因字段取值主要有四类:2021保留(新旧版本沿用)、2021新增(本次新设)、2021改名(名称调整)、2021替换代码(代码归属迁移)。理解这些变动标识,有助于在历史回测时正确跨版本映射行业归属,避免使用过时分类。
二、接口基本信息与权限
index_classify接口的核心定位是获取申万行业分类的静态列表信息(行业代码、层级、父级关系、发布状态),它不提供行情数据,而是为后续获取行情、成分等数据提供行业代码字典。
- 接口名:
index_classify - 功能描述:获取申万行业分类,可获取 2014 年版本(28/104/227)和 2021 年版本(31/134/346)列表信息
- 权限要求:用户需 2000 积分方可调取,具体积分获取办法见 Tushare 官方积分文档(原文档中链接指向官方积分获取办法,doc_id=13)
需要特别说明的是,行业指数有"发布门槛":指数成分股小于 5 条的行业,其指数行情不发布。这一点对后续拉取行情影响很大——例如上表中"粮食种植"(成分 2 条)、"食用菌"(4 条)、"林业Ⅱ"(3 条)等行业的is_pub字段为 0,意味着这些行业虽然存在分类,但没有对应发布的行业指数行情,不能用于sw_daily等行情接口回测。
三、输入参数详解
index_classify支持以下四个输入参数,全部为可选参数(N),可根据需要组合使用以缩小查询范围:
| 名称 | 类型 | 必选 | 描述 |
|---|---|---|---|
index_code | str | N | 指数代码 |
level | str | N | 行业分级(L1/L2/L3) |
parent_code | str | N | 父级代码(一级为 0) |
src | str | N | 指数来源(SW2014:申万 2014 年版本,SW2021:申万 2021 年版本) |
参数组合的使用逻辑
src是最关键的筛选维度:决定返回哪一套分类体系。实践中绝大多数场景应显式指定src='SW2021',避免默认行为与预期不符;level控制层级粒度:传L1获取一级行业(31 条)、L2获取二级行业(134 条)、L3获取三级行业(346 条)。不传则返回全部层级;parent_code支持按父级过滤:一级行业的父级代码为 0,二级行业的父级代码是一级行业代码(如 110000 农林牧渔),三级行业的父级代码是二级行业代码。利用该参数可以一次性取回"某个一级行业下所有二级行业"或"某个二级行业下所有三级行业";index_code精确匹配:传入行业指数代码(如 801010.SI)可精确返回该行业及其子级信息。
常见查询范式
# 取某一级行业下的全部二级/三级行业 df = pro.index_classify(parent_code='110000', src='SW2021') # 农林牧渔及其下所有子级 df = pro.index_classify(parent_code='110000', level='L2', src='SW2021') # 仅二级 # 按指数代码精确查询 df = pro.index_classify(index_code='801010.SI', src='SW2021')四、输出参数详解
接口返回的 DataFrame 包含以下字段(默认显示为 Y 的字段在默认输出中返回):
| 名称 | 类型 | 默认显示 | 描述 |
|---|---|---|---|
index_code | str | Y | 指数代码 |
industry_name | str | Y | 行业名称 |
parent_code | str | Y | 父级代码 |
level | str | Y | 行业层级 |
industry_code | str | Y | 行业代码 |
is_pub | str | Y | 是否发布了指数 |
src | str | N | 行业分类(SW 申万) |
字段语义与实战要点
industry_code与index_code的区别:industry_code是申万内部行业编码(如110000、110100),index_code是对应的行情指数代码(如801010.SI)。前者用于行业归类标识,后者用于行情接口(sw_daily、rt_sw_k)的数据拉取;parent_code构建树形关系:借助该字段可以复原"一级 → 二级 → 三级"的完整行业树。一级行业parent_code为 0;is_pub决定可回测性:值为 1 表示该行业发布了指数行情,值为 0 表示未发布(成分股 < 5 条)。构建行业动量/轮动因子时必须过滤is_pub == 1的行业,否则行情数据为空;level用于层级筛选:L1/L2/L3与输入参数level对应。
五、接口调用示例(完整可运行)
原文档给出如下标准示例,直接调用即可获取申万 2021 版各层级行业列表:
# 获取申万一级行业列表 df = pro.index_classify(level='L1', src='SW2021') # 获取申万二级行业列表 df = pro.index_classify(level='L2', src='SW2021') # 获取申万三级级行业列表 df = pro.index_classify(level='L3', src='SW2021')在此基础上,结合仓库内 Tushare 技能快速上手文档 中的初始化方式,可以写出一个完整的可运行脚本:
import os import tushare as ts # 读取环境变量中的 token,或读取本地记录的 token token = os.getenv('TUSHARE_TOKEN') or ts.get_token() # 初始化 pro 接口实例 pro = ts.pro_api(token) # 获取申万 2021 版一级行业列表 df_l1 = pro.index_classify(level='L1', src='SW2021') print(df_l1[['industry_code', 'index_code', 'industry_name', 'is_pub']]) # 获取申万 2021 版全部二级行业 df_l2 = pro.index_classify(level='L2', src='SW2021') print(df_l2[['industry_code', 'index_code', 'industry_name', 'parent_code', 'is_pub']]) # 获取申万 2021 版全部三级行业 df_l3 = pro.index_classify(level='L3', src='SW2021') print(df_l3[['industry_code', 'index_code', 'industry_name', 'parent_code', 'is_pub']]) # 只取已发布指数的行业(排除成分股不足 5 条、无行情的行业) df_pub = df_l3[df_l3['is_pub'] == '1'] print(df_pub.shape)前提说明:运行以上代码需要已安装
tushare依赖包(推荐 Python 3.7+,可从清华 PyPI 镜像安装),并完成 Tushare 官网注册、获取 token、配置TUSHARE_TOKEN环境变量,同时账户积分达到 2000 分。仓库内还提供了 股票数据获取示例 与 基金数据获取示例 两个脚本,展示了 token 读取与 pro 接口调用的完整模式。
六、2021 版申万一级行业分类全览
原文档的数据示例展示了level='L1'的部分返回结果,实际 2021 版一级行业共 31 个。结合原文档完整分类表可整理出以下一级行业清单(行业代码、指数代码、成分股数来自原文档清单,含"是否发布"信息):
| 行业代码 | 指数代码 | 一级行业 | 变动原因 | 成分股数 |
|---|---|---|---|---|
| 110000 | 801010 | 农林牧渔 | 2021保留 | 100 |
| 220000 | 801030 | 基础化工 | 2021改名 | 311 |
| 230000 | 801040 | 钢铁 | 2021保留 | 43 |
| 240000 | 801050 | 有色金属 | 2021保留 | 125 |
| 270000 | 801080 | 电子 | 2021保留 | 284 |
| 280000 | 801880 | 汽车 | 2021保留 | 221 |
| 330000 | 801110 | 家用电器 | 2021保留 | 77 |
| 340000 | 801120 | 食品饮料 | 2021保留 | 113 |
| 350000 | 801130 | 纺织服饰 | 2021改名 | 113 |
| 360000 | 801140 | 轻工制造 | 2021保留 | 131 |
| 370000 | 801150 | 医药生物 | 2021保留 | 331 |
| 410000 | 801160 | 公用事业 | 2021保留 | 120 |
| 420000 | 801170 | 交通运输 | 2021保留 | 128 |
| 430000 | 801180 | 房地产 | 2021保留 | 131 |
| 450000 | 801200 | 商贸零售 | 2021保留 | 104 |
| 460000 | 801210 | 社会服务 | 2021改名 | 72 |
| 480000 | 801780 | 银行 | 2021保留 | 41 |
| 490000 | 801790 | 非银金融 | 2021保留 | 87 |
| 510000 | 801230 | 综合 | 2021保留 | 40 |
| 610000 | 801710 | 建筑材料 | 2021保留 | 76 |
| 620000 | 801720 | 建筑装饰 | 2021保留 | 147 |
| 630000 | 801730 | 电力设备 | 2021改名 | 239 |
| 640000 | 801890 | 机械设备 | 2021保留 | 379 |
| 650000 | 801740 | 国防军工 | 2021保留 | 97 |
| 710000 | 801750 | 计算机 | 2021保留 | 239 |
| 720000 | 801760 | 传媒 | 2021保留 | 149 |
| 730000 | 801770 | 通信 | 2021保留 | 100 |
| 740000 | 801950 | 煤炭 | 2021新增 | 38 |
| 750000 | 801960 | 石油石化 | 2021新增 | 47 |
| 760000 | 801970 | 环保 | 2021新增 | 97 |
| 770000 | 801980 | 美容护理 | 2021新增 | 27 |
其中"2021改名"的一级行业包括:基础化工(原化工)、纺织服饰(原纺织服装)、社会服务(原休闲服务)、电力设备(原电气设备);"2021新增"的四个一级行业为煤炭、石油石化、环保、美容护理——这些行业在旧版中属于其他一级行业下的二级分类,2021 版将其独立出来,反映了分类体系对能源、环保与消费细分赛道的重视。
从二级行业层面看,2021 版共 134 个二级行业,覆盖从农林牧渔(种植业、渔业、林业Ⅱ、饲料、农产品加工、养殖业、动物保健Ⅱ、农业综合Ⅱ)到美容护理(个护用品、化妆品、医疗美容)的全部产业环节。三级行业更是细到"种子""粮食种植""食用菌""生猪养殖""锂电池""光伏电池组件"等具体赛道,例如:
- 农林牧渔 → 种植业 → 种子(850111)、粮食种植(850112)、食用菌(850114)
- 电子 → 半导体 → 数字芯片设计(850814)、模拟芯片设计(850815)、集成电路制造(850816)、集成电路封测(850817)、半导体设备(850818)
- 电力设备 → 电池 → 锂电池(857371)、电池化学品(857372)、燃料电池(857374)
- 机械设备 → 自动化设备 → 机器人(850781)、工控设备(850782)、激光设备(850783)
完整的三级行业明细(346 个)可通过pro.index_classify(level='L3', src='SW2021')一次性获取,无需从静态文档手工抄录,这也是接口相比文档表格的核心优势。
七、分类变动规律与跨版本注意事项
从原文档清单中的"变动原因"列可以总结出 2021 版分类调整的四大规律:
- 保留为主、增量拆分:大量行业标注"2021保留",说明 2014 版的骨干结构得到延续;变化主要集中在"新增"与"替换"——新设了电池、光伏设备、风电设备、电网设备、煤炭开采等成长型与能源型赛道;
- 命名层级规范化:二级/三级行业普遍使用"Ⅱ/Ⅲ"后缀(如"白酒Ⅱ/白酒Ⅲ""特钢Ⅱ/特钢Ⅲ"),一级行业不加后缀,规避同名歧义;
- 代码替换可追溯:部分三级行业标注"2021替换代码-改名"(如磷肥及磷化工替换 220302 并改名),这类行业在历史回测时需要建立新旧代码映射表,否则会因代码不连续而漏算成分股;
- 成分股数差异巨大:从 0 条(如镍、本地生活服务Ⅲ)到 379 条(机械设备)不等,成分股数少于 5 条的行业不发布指数行情(
is_pub=0)。例如银行板块的"其他银行Ⅱ"成分 0 条、传媒板块"社交Ⅱ"成分 0 条、社会服务板块"本地生活服务Ⅱ"成分 0 条,这些行业无法直接用于指数收益计算。
量化使用建议
- 构建行业池时,优先用
level='L1'+is_pub='1'过滤得到可回测的 31 个一级行业(其中煤炭、石油石化等新增行业的历史长度较短,回测起点需相应调整); - 做细分赛道轮动时,使用
level='L3'并结合 申万行业成分(分级) 接口 index_member_all.md) 获取每个三级行业的成分股(如l3_code='850531.SI'提取黄金板块全部成分股),实现"分类 → 成分 → 行情 → 因子"的完整链路; - 做跨版本长周期研究时,以 2021 版代码为基准,对 2014 版行业的迁移关系建立映射字典(原文档"变动原因"字段中的替换/改名记录即为天然映射素材)。
八、仓库内的实战串联:从行业分类到行业轮动
在 Vibe-Trading 仓库中,申万行业分类并不是孤立的一张静态表,而是行业研究数据链路的入口。围绕 申万行业分类.md 形成的数据链如下:
1. 分类字典层:index_classify
提供行业代码、指数代码、层级与发布状态。这是所有后续申万数据的"主键字典"。
2. 成分映射层:index_member_all
申万行业成分(分级).md) 接口index_member_all按三级分类提取成分股,支持l1_code/l2_code/l3_code/ts_code四个查询维度,单次最大 2000 行、总量不限制,输出in_date(纳入日期)与out_date(剔除日期),可用于成分股口径下的行业组合构建与历史回放:
# 获取黄金分类(850531.SI)的成份股 df = pro.index_member_all(l3_code='850531.SI') # 获取 000001.SZ 所属行业 df = pro.index_member_all(ts_code='000001.SZ')3. 行情层:sw_daily 与 rt_sw_k
- 申万行业指数日行情 接口
sw_daily返回申万行业日线行情(默认 2021 版),输出开高低收、涨跌幅、成交量、成交额以及pe、pb、float_mv、total_mv等估值与市值字段,单次最大 4000 行、需 5000 积分。用index_classify拿到的ts_code(如 801010.SI)可以直接作为sw_daily的输入:
# 获取 20230705 当日所有申万行业指数的行情与估值 df = pro.sw_daily(trade_date='20230705', fields='ts_code,name,open,close,vol,pe,pb')- 申万实时行情 接口
rt_sw_k提供申万行业指数最新截面数据(现价、昨收、最高、最低、成交量、成交额、涨跌幅),支持按ts_code逗号分隔批量查询,适合盘中行业监控。
4. 策略应用层:sector-rotation 技能
仓库内的 sector-rotation 技能 正是建立在"31 个申万一级行业"基础上的行业轮动分析框架,从景气度评分(盈利增速 30% + 盈利趋势 20% + 景气指标 20% + 政策支持 15% + 估值安全 15%)、行业动量排名、产业链传导、估值/盈利/资金流多维比较四个维度输出行业超配/低配建议。其行业动量计算可直接套用申万行业指数收益数据:
def sector_momentum(sector_returns: pd.DataFrame, lookback: int = 60, skip: int = 5) -> pd.Series: """ Args: sector_returns: 行业日收益率,columns=行业名 lookback: 回看窗口(交易日) skip: 跳过最近N天(避免短期反转) Returns: 行业动量得分排名 """ cum_return = (1 + sector_returns).rolling(lookback).apply(lambda x: x[:-skip].prod() - 1) return cum_return.iloc[-1].rank(ascending=False)行业收益数据正是由sw_daily(历史)与rt_sw_k(实时)供给,而index_classify负责确认哪些行业有指数、口径是哪个版本——三者构成了完整的"行业分类 → 行业行情 → 行业轮动策略"闭环。
九、最佳实践与注意事项
- 积分门槛是硬约束:
index_classify需 2000 积分,sw_daily需 5000 积分,rt_sw_k需单独申请权限。设计数据管道时,应先用分类接口建立代码白名单,再按权限逐级开通行情接口; - 必须过滤
is_pub:成分股 < 5 条的行业无指数行情,拉取sw_daily前务必用is_pub == '1'过滤,否则会出现大量空数据并污染动量/轮动计算; - 显式指定
src:新旧版本分类差异显著(28 vs 31 个一级行业),所有调用都应显式传src='SW2021'(或SW2014),不要依赖默认值; - 层级树从
parent_code复原:parent_code(一级为 0)提供了完整的父子关系,可用于递归展开任一行业的下属子行业,构建自下而上的行业聚合; - 行情限量与循环提取:
sw_daily单次最大 4000 行,跨多行业、多日期提取时应按指数代码和日期循环分页;index_member_all单次 2000 行但总量不限,同样适合循环拉取; - 区分分类代码与指数代码:行业归类和跨版本映射用
industry_code,行情拉取用index_code(带.SI后缀),二者不可混用。
综上,index_classify是 Vibe-Trading 中所有申万行业量化分析的起点接口。掌握其参数语义、版本差异与is_pub过滤逻辑,再配合index_member_all(成分)、sw_daily/rt_sw_k(行情)以及 sector-rotation 技能(策略框架),即可在仓库内构建一套数据口径一致、可回测、可跟踪的行业研究体系。
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考