资金来源与运用分析(T 型账户)
通用方法论,不绑定具体公司。 口径与行次已由用户逐项拍板,除触发提问条件的情形外不要擅自改动。
用大白话说它是干嘛的
给一家公司的钱做一次流水复盘。选一个起点和终点(如 2018 年末 → 2025 年末),
回答:这段时间公司一共经手了多少钱,钱是谁给的,又都花到哪去了。
核心是那张箱子图:
净利润 / 股东投入 / 借钱 / 占用上下游 ──► ┌──────┐ ──► 分红 + 回购(出门了)
│ 企业 │ ──► 资产增加(留下了)
进门多少钱,出门多少钱(分红+回购),剩下的变成资产。两边必须相等。
来源合计 = 分红 + 回购 + 资产增加
(药明康德 2018→2025:995 = 141 + 50 + 805,残差 0)
它基于资产负债表变动,不是现金流量表分析——capex 在这里不体现
(现金换固定资产,资产总额不变),这是刻意的,两者要配套看但别混为一谈。
> 想看更口语的完整说明见同目录 README.md。
何时使用
- 用户想搞懂「一段时间内资产增加了多少,这些钱是谁出的」
- 想分清外部融资(股权 + 债权)与自我造血(净利润)的比例
- 想看分红、回购这类「钱离开企业」的规模占比
- 做资金流向复盘、Sources & Uses 表、ΔBS 桥
> 与其他 skill 的分工:
> roic-calc 看「投入资本的回报率」,roic-decomp 看「回报率的驱动因子」,
> 本 skill 看「钱本身的来龙去脉」。三者口径必须一致(θ=5%、ω 组投资性资产定义相同)。
一、核心结构:T 型账户
用户的原始直觉:企业是个箱子,流进来的钱减去流出去的钱,剩下的变成资产。
这个直觉在财务上要修正一处——分红和回购不是「来源的减项」,而是「运用」。
它们讲的是「钱已经出了门」,不是「钱没挣到」。正确结构:
左侧 来源合计 S = 右侧 运用合计 U
右侧 = A 离开企业(分红 + 回购) + B 留在企业(资产增加 Δ总资产)
恒等式(必须闭合,残差 = 0)
记号:NI = 累计净利润(含少数股东损益)、DIV = 归母现金分红、BB = 真实回购额(含已注销)、
ΔTE = Δ权益合计、ΔTL = Δ负债合计、ΔTA = Δ总资产、ΔOCI = Δ其他综合收益、
ΔIB = Δ有息负债、ΔOL = Δ经营性负债(无息)
左侧
① 累计净利润(含少数股东损益,不扣分红) = NI
② 外部股东投入净额(倒轧) = ΔTE − NI + DIV + BB − ΔOCI
③ 有息负债净增 = ΔIB
④ 经营性负债净增(无息) = ΔOL
⑤ 其他综合收益 = ΔOCI
⑥ 其他负债(衍生金融负债等) = ΔTL − ΔIB − ΔOL
右侧
A1 现金分红 = DIV
A2 股份回购 = BB
B 资产增加 = ΔTA
结论: S = ΔTA + DIV + BB = U
② 为什么必须倒轧:股本 + 资本公积 的变动里混着增发、股权激励、可转债转股,
还混着已注销回购对资本公积的冲减。若不用 BB 加回,外部股东投入会被系统性低估
(药明康德低估 14 亿)。倒轧值 = 外部股权融资 + 少数股东增资 − 少数股东分红 + 其他权益变动,
不含少数股东损益(已在 ① 中,代数上正好抵消)。
交叉验证:倒轧出的 ② 应与现金流量表「吸收投资收到的现金」同量级。
药明康德 238 亿 vs 217 亿,差 21 亿 = 股权激励 + 资本公积其他变动,合理。
二、口径规则(用户拍板)
- 经营创造用累计净利润(含少数股东损益),不扣分红。
- 分红与回购并列在右侧「A 离开企业」,绝不能以负值出现在左侧。
- 少数股东相关内容不放在左侧,只在右侧「B 资产增加」下作备忘行
("其中:归属少数股东的权益增加"),提示这部分资产对应的权益归少数股东。 - 所有占比的分母统一为「来源合计」(不是 Δ总资产)。
- 亿元金额全部取整,不显示小数;百分比保留 1 位小数。
- 资产端明细(钱变成什么)的分母用 Δ总资产,因为它加总必须等于 100%。
沿用 ROIC 系列的既定参数
- θ = 5%(超额现金 = 货币资金 + 交易性金融资产 − 营收 × 5%)
- ω 组投资性资产(长期股权投资、其他非流动金融资产、其他权益工具投资、商誉)默认全额剔除
- 单项资产 ÷ 期末总资产 > 10% 时停下来问用户性质(经营 vs 金融),不要自行假定
三、取数方法
1. 真实回购金额(关键,易错)
东财接口 ak.stock_repurchase_em() —— 无入参(签名 () -> DataFrame),
返回全市场约 5500 行回购预案表,需拉全量后按 股票代码 过滤,耗时约 10 秒。
df = ak.stock_repurchase_em() # 不要传 symbol,会 TypeError
d = df[df["股票代码"].astype(str).str.contains(code)]
d["_y"] = pd.to_datetime(d["回购起始时间"]).dt.year
sel = d[(d["_y"] >= y0 + 1) & (d["_y"] <= y1)]
bb = pd.to_numeric(sel["已回购金额"]).sum() / 1e8
为什么必须用真实回购而不是库存股账面变动:库存股只记录未注销部分。
已注销的回购直接冲减股本和资本公积,账面上看不见。
药明康德 2019–2025 真实回购 50 亿,库存股账面只增加 36 亿,少算 14 亿。
三个局限必须在输出中写明:
① 仅 A 股回购预案口径,H 股回购不计入(A+H 公司要提示);
② 按预案起始年度归集,与实付现可能错期;
③ 与「支付其他与筹资活动有关的现金」做上限校验(回购额应显著小于该科目,
该科目还含租赁付款、收购少数股权)。
接口失败时降级为库存股变动,并在输出里标注"仅未注销部分,可能低估"。
脚本提供 --buyback <亿元> 手工覆盖。
注意差额方向不是固定的(康龙化成实测):库存股账面 3 亿 大于 本口径回购 2 亿,
因为库存股还含股权激励/限制性股票回购。所以:
- 真实回购 − 库存股变动 ≥ 1 亿 → 差额是已注销部分,说明账面低估了回购
- 否则 → 库存股含其他来源,本口径只覆盖集中竞价回购的预案部分
文案要跟着条件走,不能一律说"差额为已注销部分"。
2. 累计现金分红(权益反推)
累计分红 = 累计归母净利润 − Δ(盈余公积 + 未分配利润)
提取盈余公积是权益内部结转,取两者合计即可自动对冲。
与现金流量表「分配股利、利润或偿付利息支付的现金」交叉验证(后者还含利息与少数股东股利)。
3. 少数股东损益
利润表字段 MINORITY_INTEREST。累计少数股东损益 + 累计归母净利 = 累计净利润。
四、输出结构
- T 型账户(HTML 左右并排,两列等高;终端上下两块)
- 右侧 B 的展开:资产端分组(现金理财 / 厂房设备 / 欠条存货 / 对外投资 / 无形商誉 / 其他),分母 Δ总资产
- 外部拿了多少 vs 自己挣了多少(自我造血率、返还股东占比)
- 自己挣的钱里有多少是一次性的(剔投资收益、公允价值变动、资产处置、其他收益、营业外收支,按实际税率税后化)
- 现金视角:三张现金流量表净额 + 筹资进出毛额
- IC 口径:ΔIC 占 Δ总资产的比例
- 通俗解读 6 段(自动生成,非硬编码):先说结论 / 钱去哪了 / 钱从哪来 /
为什么分红和回购要单独放 / 两个容易被忽略的点 / 打个比方
五、用法
python scripts/t_account.py SH603259 2018 2025 # 代码需带 SH/SZ 前缀
python scripts/t_account.py SZ300759 2020 2025 --out <输出目录>
python scripts/t_account.py SH603259 2018 2025 --buyback 50 # 手工指定回购额
# 长区间(>15 年)必须再跑一次分期,否则不同阶段的模式会被首尾一减糊掉
python scripts/stage_breakdown.py SH600196 1997 2025 --cuts 2007,2017 \
--inject <输出目录>/t_account_SH600196_1997_2025.html
依赖:akshare(≥1.18.6)、pandas。
输出:t_account_{代码}_{起}_{止}.html + 终端文本。
> 本机运行环境(Python 解释器绝对路径、输出目录、本机特有的坑)见同目录 ENV.local.md。
> 该文件每台机器各有一份、不参与跨机同步;本文件(SKILL.md)与 scripts/ 为机器无关内容,两台机器保持一致。
六、易错点(全踩过)
- 分红不能从净利润里减掉 —— 它是运用不是来源。这是本 skill 存在的根本原因。
- 回购不能用库存股账面变动 —— 漏掉已注销部分,同时低估外部股东投入。
stock_repurchase_em()无入参 —— 传symbol=会 TypeError。- 少数股东作负值放左侧 —— 用户明确反对,必须移到右侧备忘行。
- 分母用 Δ总资产 —— 应统一用来源合计,否则各占比加总不等于 100%。
- 利润表取
PARENT_NETPROFIT—— 应用NETPROFIT(含少数股东损益)。 SECURITY_CODE/SECURITY_TYPE_CODE/ORG_CODE是代码不是金额,必须从金额字段中排除,否则资产负债表求和爆炸。- 交易性金融资产在
TRADE_FINASSET_NOTFVTPL,不是TRADE_FINASSET(后者常全空)。 - 负债易漏字段:
OTHER_CURRENT_LIAB(其他流动负债)、HOLDSALE_LIAB、DERIVE_FINLIAB。漏归类会让经营性负债算错。 - Δ现金及等价物 ≠ Δ货币资金(定期存款/受限资金 + 汇率影响),属正常,不要当错误去"修"。
- 终端中文表格对齐:
{x:<52}把中文按 1 宽算,实际显示占 2 格,必然错位。
必须用按显示宽度填充的函数(见脚本W())。 - HTML 缩进不要靠在字符串里塞空格(会被折叠),用 CSS class 控制层级。
- 资产端三个高频漏项:
DEVELOP_EXPENSE(开发支出)、FINANCE_RECE(应收款项融资)、
LONG_RECE(长期应收款)。漏掉会让资产分组残差冲到 5% 以上
——复星医药首次跑残差 −64 亿(94.6%),补上这三项后收敛到 +1 亿。
残差不为 0 就先查未归类科目:把期末所有字段按金额倒序列一遍,
挑出不在ASSET_GROUPS里的(注意TOTAL_*是合计项,不算漏项)。 ACCOUNTS_RECE与NOTE_ACCOUNTS_RECE是包含关系,不能相加。
后者 = 应收票据 + 应收账款,前者只是其中的应收账款子项。
同理NOTE_RECE(应收票据)也已含在NOTE_ACCOUNTS_RECE里。- 新建脚本必须在 import 后立刻
sys.stdout.reconfigure(encoding="utf-8", errors="replace")。
否则 Windows PowerShell 下第一次 print 中文就 UnicodeEncodeError,
进程静默死在中途,只留下 tqdm 进度条,看起来像"跑了一半卡住"。 - 区间超过 15 年必须配
stage_breakdown.py。首尾一减会把 1998 年的
IPO 扩张和 2020 年代的创新药投入混成一个数字,结论没有意义。 - 旧准则年份(≈2018 前)两组科目必须兜底:对外投资组加
AVAILABLE_SALE_FINASSET
(可供出售金融资产);现金组加FVTPL_FINASSET(旧版交易性金融资产,超额现金候选)。
pick()若按"全列是否有非空值"全局选列,旧准则年份的列会被永久忽略
—— 必须新旧两键都保留、逐年取非空者。
七、验证基准
药明康德 SH603259,2018年末 → 2025年末(来源合计 995 亿,残差 0)
| 左|来源 | 金额 | 占来源合计 |
|---|---|---|
| ① 累计净利润(归母 569 + 少数股东 6) | 575 | 57.8% |
| ② 外部股东投入净额(倒轧) | 238 | 23.9% |
| ③ 有息负债净增 | 81 | 8.1% |
| ④ 经营性负债净增 | 105 | 10.5% |
| ⑤ 其他综合收益 | −2 | −0.2% |
| ⑥ 其他负债 | −2 | −0.2% |
| 来源合计 | 995 | 100% |
| 右|运用 | 金额 | 占来源合计 |
|---|---|---|
| A1 现金分红 | 141 | 14.1% |
| A2 股份回购(5 笔各 10 亿) | 50 | 5.0% |
| A 小计 返还股东 | 191 | 19.2% |
| B 资产增加 | 805 | 80.8% |
| 运用合计 | 995 | 100% |
校验式:995 = 141 + 50 + 805
总资产 227 → 1,031 亿,增加 805 亿(4.55 倍,7 年 CAGR 24.2%)
剔非经营税后(118 亿)的经营性创造 457 亿,占来源合计 45.9%
ΔIC 316 亿,仅占 Δ总资产 39.3%
康龙化成 SZ300759,2020年末 → 2025年末(来源合计 170 亿,残差 0)
通用性验证:自我造血率仅 45.9%(vs 药明康德 57.8%),有息负债净增 60 亿占 35.1%
(药明康德仅 8.1%)——同样的方法能清楚照出两种截然不同的扩张模式。
少数股东损益为 −3 亿,说明该口径在少数股东亏损的公司上也成立。
回购 2 亿 / 库存股账面 3 亿,触发"库存股含股权激励"分支。
跑新公司后必须用「残差 = 0」自检;残差不为 0 说明有科目没归类或口径错配。
复星医药 SH600196,1997年末 → 2025年末(上市前夜起算,来源合计 1,358 亿,残差 0;
资产分组残差 +1 亿 / 0.08%)
| 左|来源 | 金额 | 占来源合计 |
|---|---|---|
| ① 累计净利润(归母 476 + 少数股东 66) | 542 | 39.9% |
| ② 外部股东投入净额(倒轧) | 253 | 18.7% |
| ③ 有息负债净增 | 381 | 28.0% |
| ④ 经营性负债净增 | 200 | 14.7% |
| ⑤ 其他综合收益 | −18 | −1.3% |
| 来源合计 | 1,358 | 100% |
右侧:分红 156 + 回购 5 + 资产增加 1,198 = 1,358。
总资产 2.9 → 1,201 亿(418 倍,28 年 CAGR 24.1%)。
这个案例暴露了两个通用教训:
- 投资控股型公司的「剔非经营」会失真 —— 区间累计投资收益 470 亿 = 累计净利润的 87%,
剔完只剩 129 亿。这 129 亿只能当最保守下限读,不能当主业盈利能力的正常值。
脚本已内置:cum_inv / cum_np > 50%时自动打印口径警示。 - 长期股权投资占比过大会让 IC 结论摇摆 —— 长股投增加 264 亿(占 Δ总资产 22%),
默认 ω 口径 ΔIC 占 40.4%,若认定长股投属经营性则 ΔIC′ 占 62.5%。
脚本已内置敏感性行,触发条件Δ长股投 > 10% × Δ总资产。
(按口径规则「单项资产 > 期末总资产 10% 需问用户」,此时应就参股性质确认。)
分期结果(同一口径):
| 阶段 | Δ总资产 | ①净利润占比 | ②+③外部融资 | 新增资产最大去向 |
|---|---|---|---|---|
| 1997→2007 | 71 亿 | 29.2% | 62.4% | 对外投资 41% |
| 2007→2017 | 545 亿 | 35.2% | 46.0% | 无形与商誉 31% |
| 2017→2025 | 581 亿 | 45.4% | 45.5% | 无形与商誉 30% / 厂房设备 27% |
自我造血率从 29% → 35% → 45%,逐阶改善;扩张性质从"买公司"转向"建产能 + 做研发"。
九、变更记录
- 1.0.1(2026-09-21,双机合并):以 Gitee 仓库版为基底(含
stage_breakdown.py分期脚本、
IC′ 敏感性、投资收益占比口径警示、易错点 13–16、复星医药基准),
并入本机版的旧准则逐年兜底:AVAILABLE_SALE_FINASSET(可供出售金融资产,对外投资组)
与FVTPL_FINASSET(旧版交易性金融资产,现金/超额现金组),
并据此补入易错点 17。本机环境信息剥离至ENV.local.md。 - 1.0.0:首版。