主页/ 做投资/ 行业结构/ 分析过程
沪深300 · 行业结构 · 方法

偏离度是怎么算出来的

口径设计、取数流程、踩过的坑、三项校验与敏感性分析 · 配套 分析报告 · 2026-09-15

这一页要说明什么

一个结论可不可信,取决于三件事:口径对不对齐、数据有没有读错、结论对假设敏不敏感。本页按这个顺序交代:先定义公式和「可投资利润」口径;再说明数据从哪来、经过了哪几步;然后列出过程中真实遇到的数据问题以及处理方式;最后是校验与敏感性分析——结论在换口径、剔除亏损股之后是否依然成立。

核心公式

偏离度i = 权重占比i ÷ 可投资利润占比i
可投资利润i = 归母净利润TTMi × 自由流通比例i

行业 i 的权重占比 = 行业内成分股权重之和 ÷ 全部权重;利润占比同理,用可投资利润加总。

为什么要乘自由流通比例

沪深300 按自由流通市值加权,而财报净利润是公司 100% 股本对应的利润。两者直接相除,分子分母口径不一致。

例子自由流通比例归母净利TTM(亿)可投资利润(亿)影响
建设银行2.5%——全样本最低,大量股本为国家持有或 H 股
农业银行8.2%2,979.1243.6不调整会把利润放大 12 倍
工商银行8.8%3,741.4327.4同上
工业富联16.2%469.176.0大股东控股比例高
伊利股份91.0%——全样本最高,几乎不受影响
不做这一步的后果:国有大行、央企的「利润占比」被严重高估,金融的偏离度会被压到远低于 0.41,看起来像是「极度低估」——但那只是口径错位造成的假象。

两层分组口径

口径一:六大类

中证一级行业按固定映射合并为科技制造、金融地产、上游资源品、消费、医药生物、公用事业/交运,与此前 2005–2026 历史分析保持同一口径,便于纵向对比。
信息技术 + 工业 + 通信服务 → 科技制造

口径二:中证一级行业

不做合并,直接按中证一级行业分组。计算函数与口径一完全相同,只替换分组列。用来拆开「科技制造」内部——它混合了芯片、光模块、宁德时代,也混合了中国建筑、京沪高铁和三大运营商。

推导:偏离度 ≈ 相对 PE

若行业权重占比 ≈ 自由流通市值占比(记 M 为自由流通市值,P 为可投资利润):

偏离度i ≈ (Mi/ΣM) ÷ (Pi/ΣP) = (Mi/Pi) ÷ (ΣM/ΣP) = PEi ÷ PE指数

前提是否成立要实测:本期 300 只个股「权重 ÷ 自由流通市值占比」中位数 1.002,90% 落在 0.85–1.15。行业层面用两种口径算出的偏离度最大差 0.17(通信服务 2.27 vs 2.10),其余均在 0.06 以内。

五个步骤

成分股与权重:中证指数官网

下载 000300closeweight.xls,300 只,权重合计 100.00%。文件只有代码、名称、交易所、权重,没有行业列。
输出:000300closeweight.xls(2026-08-31)

中证一级行业:iFinD 股票数据

每批 25 只查询「所属中证行业(2021)」,校验指标参数为「一级行业」,行业名必须能映射到六大类,否则报错。合并进权重表。
输出:000300weights_with_industry.csv · 300/300

归母净利润TTM + 自由流通比例:iFinD

每批 25 只,两类指标分两次请求,批次间隔 3 秒;每批结果立即追加写入缓存,中断后重跑自动跳过已取到的股票。
输出:profits_partial.csv(code, net_profit_ttm, free_float_pct)· 300/300

先试跑前 30 名,再扩到全部

前 30 名覆盖 42.6% 权重,允许缺失上限临时放宽到 80%,先做三项人工校验;全部通过后再取剩余 270 只,缺失上限恢复为 3%。
试跑隐含 PE 17.2x → 通过 → 正式跑

计算与输出两层口径

同一个计算函数跑两次(六大类 / 一级行业),另取 2026-08-31 自由流通市值用于隐含 PE 与敏感性分析。
输出:报告文本 + 个股明细 CSV

解析原则:宁可报错,不猜字段

数据接口返回的是自然语言问答结构,最容易出现「列读错位但不报错」的静默错误。此前在恒生指数系统上吃过亏:兜底逻辑把 PE 读成了股息率。所以这次每一层都要求精确命中:

层级检查内容不符时
业务状态code == 1报错
data 字段必须是 JSON 字符串,解码后含 answer报错并提示「返回结构又改了」
表头按完整列名精确匹配,不按位置报错并打印实际表头
行对齐按证券代码对齐;出现重复或未请求的代码报错
指标口径行业级别 = 一级行业;利润单位 = 元报错
数值只接受纯数字或「万 / 亿 / 万亿」后缀报错
自由流通比例必须在 (0,100],且与「自由流通股 ÷ 总股本」相差 ≤ 0.5 个百分点报错,拒绝写入
缺失值仅「--」「-」、空值等显式标记算缺失记为缺失并列出,不补 0

过程中真实遇到的问题

#问题如果没发现会怎样处理
1最初拿到的「指数成分股数据.xlsx」只有 50 行,仅前 10 只有权重(合计 23.66%),行业为申万三级样本严重不完整,行业口径也不对弃用,改从中证官网下载正式权重文件
2中证列名写作「成份券」而非「成分券」,权重列为小写 weight找不到列补充列名别名;删除会同时匹配中英文名称两列的歧义别名
3原配置把「交易所英文名称」列为行业列的第一候选「Shanghai Stock Exchange」被当成行业删除该候选;行业改由 iFinD 补齐
4接口的 data 字段是 JSON 字符串(需二次解码),业务数据在 markdown 表格里典型的「'str' object has no attribute 'get'」显式两层解码 + 表格解析
5同一接口两次返回的列顺序不同,行顺序也与请求顺序无关按位置取值会列错位——正是恒指事故的同类问题只按表头名取列、按证券代码对齐行
6自由流通比例以百分数返回(43.27 而非 0.4327)可投资利润放大 100 倍除以 100,并用股本数交叉验证
7批量查询漏行:沪硅产业(TTM 亏损 21.06 亿)在 25 只一批的查询里没有返回,单独查询则有数据若按缺失剔除,亏损股被悄悄移出,信息技术利润被高估脚本显式列出缺失,断点续传单独补取;另换批次组合随机抽检 20 只,数值 20/20 一致
8走本机代理时连接在第 8 批中途断开取数中断国内接口改为直连;仅对网络层错误重试,业务错误不重试;断点续传保证已取数据不丢
9只查自由流通市值时,返回表不带日期列无法确认取到的是否为 2026-08-31 的值附带查询收盘价,使返回带「日期」列,并逐行断言日期
第 5 条和第 7 条最危险。它们都不会让程序崩溃:列顺序变化会产出「看起来正常」的错位数据,批量漏行会让亏损公司悄无声息地消失。能发现它们,靠的是「按名取列 + 显式缺失 + 抽检」这三道防线,而不是事后看结果顺不顺眼。

三项人工校验

校验判据结果结论
利润口径是 TTM贵州茅台应在 850 亿量级;若为 200 多亿则误取单季度8.14e10(814.3 亿)通过
自由流通比例是小数全部应在 0–1;出现 35、68 说明是百分数0.025(建设银行)~ 0.910(伊利股份),越界 0 条通过
隐含 PE 量级可投资利润合计反推,应在 12–18 倍;3 倍或 60 倍说明数据有误试跑 30 只 17.2x;全样本 24.31 万亿 ÷ 1.43 万亿 = 17.05x通过
批量取数一致性换批次组合重查,数值应完全一致随机 20 只:一致 20,不一致 0,漏行 0通过
权重 vs 自由流通市值两者占比之比应接近 1(中证采用分级靠档,会有偏差)中位 1.002;5%–95% 分位 0.85–1.15通过

第 1 项:茅台 814 亿比预设的 850 亿低约 4%,属真实利润水平差异;与单季度(约 200 亿)差距明确,口径无误。

敏感性分析:结论扛不扛得住换口径

三列分别对应:原口径(中证权重);把权重替换为 iFinD 自由流通市值(检验分级靠档误差);剔除全部亏损股后重算(检验亏损股是否扭曲比值)。

行业权重%原口径自由流通市值口径剔除亏损股亏损股权重%结论是否变化
科技制造48.681.881.871.891.52不变
 信息技术22.562.942.963.030.64不变
 通信服务9.882.272.102.440.06不变
 工业16.241.171.191.120.82不变(贴近 1.2 上沿)
金融地产20.170.440.460.440.22不变
上游资源品12.280.930.921.010.05不变
消费11.791.111.101.090.77不变
医药生物4.311.831.791.570.19仍 ≥1.5,但受亏损股影响明显
公用事业/交运2.771.051.101.140.00不变
结论:所有行业的判读档位在三种口径下都没有改变。可以放心使用的分辨率是「3.0 与 1.0」这种量级差异;「1.4 与 1.6」这种贴近阈值的差异,落在口径误差范围内,不宜据此做判断。

试跑与正式跑的差异(为什么不能用前 30 名下结论)

行业前 30 名试跑全部 300 只
科技制造2.341.88
金融地产0.420.44
医药生物1.591.83
上游资源品0.800.93

前 30 名里集中了四大行和中国平安,金融拿走了样本内 54% 的利润,其他行业的偏离度被系统性抬高;样本内工业只有宁德时代一家。试跑的用途只是验证数据质量。

已知局限

没有增速维度

偏离度约等于相对 PE,只说明「贵多少」,不说明「值不值」。高增长行业天然偏离度高,需叠加利润增速才能判断溢价是否合理。

时点错配

权重为 2026-08-31 收盘;利润 TTM 基于最新已披露报表(2026 半年报)。8 月下旬后公布半年报的公司,其市值与利润存在数周错位。

行业分类偏粗

中证一级行业无法区分光模块与运营商、半导体与消费电子。本期「算力链」数据按具体公司名单计算,尚未建立系统的二级分类映射。

单期截面

目前只有一个数据点。偏离度的变化方向(在收敛还是扩大)比单期水平更有信息量,需按季度重跑积累序列。前期讨论中关于美股 2000 / 2026 年、日本 1989 年的历史类比,本期未用同口径数据复核。

复现步骤(每季度重跑)

# 1. 从中证指数官网下载最新 000300closeweight.xls 放入项目目录
# 2. 清掉上期缓存
del profits_partial.csv industry_partial.csv

# 3. 取数(行业 + 利润TTM + 自由流通比例,分批、可断点续传)
python fetch_profits.py --weights 000300closeweight.xls

# 4. 两层口径报告
python report_levels.py --weights 000300weights_with_industry.csv ^
       --profits profits_partial.csv --save detail_full_industry.csv
文件作用
weight_profit_gap.py计算核心:解析权重、口径对齐、行业聚合、判读与渲染(仅按实际列名补了别名表)
ifind_client.pyiFinD 数据接口客户端:两层解码、表格解析、中文数值解析,结构不符即报错
fetch_profits.py分批取数、口径参数校验、自由流通比例交叉验证、断点续传
report_levels.py同一计算函数输出六大类与中证一级行业两层结果
数据来源:中证指数有限公司(成分股权重);同花顺 iFinD(行业分类、归母净利润TTM、股本结构、自由流通市值)。仅供研究参考。