ROIC 计算(定稿口径 v2)
这是通用方法论,不绑定任何具体公司。 参数已由用户逐项拍板,除触发提问条件的情形外不要擅自改动。
何时使用
- 用户要求计算/对比某家公司或一批公司的 ROIC
- 做 ROIC − WACC 的价值创造判断
- 需要把"主业经营回报"从一次性收益、闲置现金、并购溢价中剥离出来时
一、核心公式
ROIC = NOPAT ÷ IC_avg
【分子】NOPAT = EBIT_op × (1 − t)
EBIT_op = 营业利润
+ 利息支出 ① 加回(用明细科目,非财务费用净额)
− 利息收入 ③ 剔除(与分母剔超额现金配对)
± 汇兑损益 ④ 中性化=剔除(主口径)
− 投资收益
− 公允价值变动损益
− 资产处置收益
− 其他收益
− 营业外收支净额
② 租赁负债利息:已并入①,无单列则不加
⑤ 手续费及其他:保留在营业利润中(无独立字段,实际随④一并处理)
减值:不加回(用户收口)
t = 所得税费用 ÷ 利润总额 实际有效税率,不用 25% 法定税率
【分母】IC = 有息负债 + 股东权益合计 − 超额现金 − Σ(ωⱼ × 资产ⱼ)
有息负债 = 短期借款 + 一年内到期非流动负债 + 长期借款 + 应付债券 + 租赁负债
股东权益合计 = 归母权益 + 少数股东权益
超额现金 = 货币资金 + 交易性金融资产 − 营业收入 × θ
IC_avg = (IC_期末 + IC_期初) ÷ 2 分子是期间流量,分母必须取平均
二、参数(用户已拍板)
| 参数 | 取值 | 说明 |
|---|---|---|
| 财务费用① | 加回 | 利息支出明细科目 |
| 财务费用② | 加回 | 租赁负债利息,通常已含在① |
| 财务费用③ | 剔除 | 利息收入。分母已剔超额现金,必须配对 |
| 财务费用④ | 中性化(剔除) | 用户理由:"希望 ROIC 主要看经营性"。同时输出「保留汇兑」版作对照 |
| 财务费用⑤ | 保留 | 手续费及其他 |
| 非经营项 δ 组 | 全部剔除 | 投资收益、公允变动、资产处置、其他收益、营业外净额 |
| 减值 | 不加回 | 资产减值与信用减值均留在营业利润中 |
| θ | 5% | 经营所需现金占营收 |
| ω 组 | 默认全额剔除 | 长期股权投资、其他非流动金融资产、其他权益工具投资、商誉 |
| ω 提问阈值 | 单项 ÷ 期末总资产 > 10% | 触发时必须停下来问用户,不得自行假定 |
财务费用倒轧(汇兑无独立字段,必须倒轧):
汇兑 + 手续费 = 财务费用 − 利息支出 + 利息收入
实现恒等式:剔除汇兑后,财务费用整体调整量 = + 财务费用净额。
三、两个输出口径(用户明确要求)
| 口径 | 定义 | 回答的问题 |
|---|---|---|
| ROIC_主 | ω 组(含商誉)全额剔除 | 纯经营资产的回报率 |
| ROIC_含商誉 | 商誉保留在分母,其余 ω 组仍剔除 | 含并购溢价的总资本回报 |
两者之差即商誉对 ROIC 的拖累。商誉占比高的公司(如康龙化成 10%~13%)差异可达 2 个百分点以上,必须两个都给。
另需输出数据库口径(有息负债 + 权益,不剔不扣)用于对照与复现校验。
四、执行步骤
- 确认标的与年份:需要 N 年结果时,要连带取 N−1 年数据(IC 平均需要期初值)
- 跑脚本:
python scripts/roic_calc.py <代码> <年份...>
- 代码格式:SH603259/SZ300759(必须带交易所前缀)
- 例:python scripts/roic_calc.py SH603259 2024 2025 - 检查
[0b]字段缺失行:缺失字段按 0 处理,会失真,需提示用户 - 检查 ω 触发提示:触发阈值时停下来问用户,确认后再出结论
- 汇报:给两个 ROIC + 数据库口径 + 关键敏感性,并提示 ROIC 需减 WACC 才有结论价值
脚本路径:~/.workbuddy/skills/roic-calc/scripts/roic_calc.py
依赖:akshare、pandas(pip install akshare pandas,用已装 akshare 的那个 Python 解释器即可)
> 本机运行环境(Python 解释器绝对路径、输出目录、本机特有的坑)见同目录 ENV.local.md。
> 该文件每台机器各有一份、不参与跨机同步;本文件(SKILL.md)与 scripts/ 为机器无关内容,两台机器保持一致。
五、数据字段对照(东财 via akshare)
已验证的字段名,脚本内已做多候选容错:
| 用途 | 字段 |
|---|---|
| 利润表 | OPERATE_PROFIT FINANCE_EXPENSE FE_INTEREST_EXPENSE FE_INTEREST_INCOME INVEST_INCOME FAIRVALUE_CHANGE_INCOME ASSET_DISPOSAL_INCOME OTHER_INCOME NONBUSINESS_INCOME/EXPENSE ASSET_IMPAIRMENT_INCOME CREDIT_IMPAIRMENT_INCOME TOTAL_PROFIT INCOME_TAX OPERATE_INCOME |
| 资产负债表 | MONETARYFUNDS TRADE_FINASSET_NOTFVTPL SHORT_LOAN NONCURRENT_LIAB_1YEAR LONG_LOAN BOND_PAYABLE LEASE_LIAB TOTAL_PARENT_EQUITY MINORITY_EQUITY LONG_EQUITY_INVEST OTHER_NONCURRENT_FINASSET OTHER_EQUITY_INVEST GOODWILL TOTAL_ASSETS |
| 旧准则(≈2018 前) | AVAILABLE_SALE_FINASSET(可供出售金融资产,属 ω 组)FVTPL_FINASSET(旧版交易性金融资产,超额现金候选) |
脚本开头必须清理代理环境变量(若环境中残留已失效的代理配置,会导致请求间歇性失败且极难排查):
import os
for k in list(os.environ):
if "proxy" in k.lower():
os.environ.pop(k, None)
os.environ["NO_PROXY"] = "*"
六、易错点(全部踩过)
- "非流动性资产处置损益" ≠ 利润表"资产处置收益"科目。前者是非经常性损益明细项,实际落在投资收益科目。出售子公司股权的收益计入投资收益。按科目名找必然搞错。
- 交易性金融资产在
TRADE_FINASSET_NOTFVTPL,不是TRADE_FINASSET(后者常为空)。取错会导致超额现金少算几十亿,ROIC 严重偏低。 - 减值在
ASSET/CREDIT_IMPAIRMENT_INCOME(负值为损失),ASSET_IMPAIRMENT_LOSS字段全空。pandas 的sum()默认 skipna,全空列静默返回 0,与"金额为 0"无法区分——取数必须用count检查非空数量。 FE_INTEREST_INCOME存的是正数金额,不是负数。倒轧公式是财务费用 − 利息支出 + 利息收入。- 加回的是"利息支出"明细,不是财务费用净额。财务费用常被利息收入冲抵为负。
- 数据库(Choice/Wind)的 ROIC 是不做任何调整的直接套用:
EBIT(含非经常) × (1−t) ÷ 平均(有息负债+权益),不剔非经常损益、不扣超额现金。已实测复现。 - 不要依赖数据库的"息税前利润率"等衍生指标,不同数据库定义可能不一致,应从利润表自下而上算。
- IC 必须取期初期末平均,分子是期间流量。
- ROIC 单独看没有意义,必须减 WACC 才能判断是否在创造价值。
- 上市前/早年份数据:季度利润接口(
stock_profit_sheet_by_quarterly_em)2017Q1 起才有数据;算 2017 年以前的年份必须用年报接口(stock_profit_sheet_by_yearly_em)兜底补齐,且注意早年利息明细/研发费用可能缺失(脚本会警告,按 0 处理并标注)。资产负债表/现金流量表年报接口覆盖正常。 - 旧准则科目必须逐年兜底,不能全局选列:新金融工具准则(≈2018)前的年份里,ω 组漏掉
AVAILABLE_SALE_FINASSET、超额现金漏掉FVTPL_FINASSET是实测踩过的坑。pick(df, cands)若按"全列是否有非空值"全局选列,旧准则年份的列会被永久忽略——必须新旧两键都保留、逐年取非空者。
七、验证基准
药明康德 SH603259(2015–2025,含旧准则年份)全区间已跑通,可用作回归测试(主口径,剔商誉):
| 年 | ROIC | 年 | ROIC |
|---|---|---|---|
| 2015 | 7.97% | 2021 | 19.52% |
| 2016 | 23.51% | 2022 | 25.76% |
| 2017 | 32.34% | 2023 | 25.04% |
| 2018 | 29.10% | 2024 | 22.34% |
| 2019 | 22.24% | 2025 | 34.64% |
| 2020 | 21.99% |
注意:2018 因 AVAILABLE_SALE_FINASSET(可供出售金融资产)并入 ω 组,基准为 29.10%(旧基准 27.43% 作废);2015–2016 利息明细缺失、研发费用未单列,按 0 处理并有警告,属已知口径瑕疵。
八、已知未处理项(跨行业比较时需注明)
- 研发费用化:经济上是长期资本投入,账面直接进费用不形成资产 → 账面 IC 小于真实投入资本,ROIC 系统性高估。研发密集型公司(创新药、软件)之间比较问题不大,跨行业比较必须注明。
- 递延所得税资产/负债不重分类
- 资本化利息不在财务费用里(进了资产成本,通过折旧释放),结构化数据取不到;对 ROIC 而言它与分母是配对的,无需调整
- 历史成本计量:老资产账面价值远低于重置成本
九、变更记录
- 1.0.2(2026-09-21,双机合并):以家庭机版本为基底,并入办公室机的
sys.stdout.reconfigure(encoding="utf-8")编码修复(Windows 重定向中文乱码)。本机环境信息从 SKILL.md 剥离至ENV.local.md。回归验证:药明康德 SH603259 2015–2025 全区间主口径与下方「验证基准」表逐年一致。 - 1.0.1:办公室机版本号(含本机环境段落,已迁出至
ENV.local.md)。 - 1.0.0:首版。