财报一看就懂——完整实施规范

基于薛兆丰 (Xue Zhaoheng),《财报一看就懂》(2019)


目录

  1. 概述
  2. 利润表分析
  3. 资产负债表分析
  4. 现金流量表分析
  5. 关键财务比率
  6. 杜邦分析
  7. 红旗与盈利操纵检测
  8. 行业特定指标
  9. 使用财务数据选股
  10. 财务分析常见错误
  11. 完整分析生命周期示例
  12. 实施伪代码
  13. 关键原则

1. 概述

1.1 本书目的

本书旨在为普通投资者——没有会计学位的人——提供一本实用指南,帮助他们充分理解企业财务报表,从而做出明智的股票投资决策。作者的核心论点是:财务素养是区分持续盈利投资者与依赖消息、传闻和市场情绪投资者的最重要技能。

这一方法本质上是自下而上的:首先了解公司的财务健康状况,然后判断股价是否代表合理的入场点。这与自上而下的宏观经济分析或纯粹的技术图表方法形成对比。

1.2 三张财务报表作为一个系统

财务分析不是孤立地阅读某一张报表。三张核心财务报表形成一个相互关联的系统:

利润表                  资产负债表               现金流量表
(盈利能力)             (财务状况)            (现金现实)
────────────────         ────────────────        ────────────────
营业收入                 资产                     经营活动现金流
- 成本                 = 负债 + 所有者权益      投资活动现金流
= 净利润 ─────────────→ 留存收益               筹资活动现金流
                        ↑                       ↓
                        └────────────────────────┘
                        资产负债表上的现金 = 现金流量表的期末现金

利润表告诉你公司赚了多少钱。资产负债表告诉你公司在特定时刻拥有什么和欠什么。现金流量表告诉你钱实际上去了哪里。三者必须讲述一致的故事——当它们出现分歧时,那就是最重要的分析洞察(和红旗)出现的地方。

1.3 核心分析哲学

本书倡导分层分析方法:

  1. 从现金流开始——现金是最难操纵的数字。首先检查公司是否从核心运营中实际产生现金。
  2. 用利润表验证——报告的利润是否有真实现金支持,还是只是会计构造(应计项目、一次性收益、激进的收入确认)?
  3. 用资产负债表压力测试——公司是用可持续的方式(留存收益、合理的债务)还是危险的方式(过度杠杆、表外负债)为增长融资?
  4. 跨时间和同行比较——单一年份的数字几乎毫无意义。你需要至少3-5年的数据和行业基准。

2. 利润表分析

2.1 营业收入

营业收入是起点,但并非所有营业收入都是平等的。本书强调:

营业收入质量检查清单:
────────────────────────
□ 营业收入是否连续3年以上同比增长?
□ 增长率是否稳定或加速(不是减速)?
□ 收入是否分散在多个客户中(没有单一客户 > 30%)?
□ 收入是否主要来自核心运营(不是资产出售、补贴或一次性项目)?
□ 收入增长是否匹配或超过行业平均水平?

2.2 毛利率

毛利率 =(营业收入 - 销售成本)/ 营业收入 × 100%

毛利率揭示了公司最基本层面的定价能力和成本结构——在运营费用、利息和税之前。关键解读框架:

毛利率范围 解读
> 60% 强定价能力,可能有品牌或知识产权优势(软件、奢侈品、制药)
40-60% 良好竞争地位,有一定差异化
20-40% 中等——典型于制造业、零售业
< 20% 类似大宗商品业务,主要靠价格或规模竞争

关键规则:连续多个季度毛利率下降是竞争恶化最可靠的早期警告信号之一。这意味着公司要么正在失去定价能力(被迫降价),要么面临无法转嫁给客户的投入成本上升。

2.3 营业利润率

营业利润率 = 营业利润 / 营业收入 × 100%
营业利润 = 营业收入 - 销售成本 - 运营费用(SG&A、研发、折旧摊销)

营业利润率剔除了金融工程(利息、税收),显示核心业务是否盈利。毛利率与营业利润率之间的差距揭示运营效率:

2.4 净利率

净利率 = 净利润 / 营业收入 × 100%

净利率是底线,但也是最容易失真的数字。可能膨胀或压低净利率但不代表运营实际的项目:

本书的关键规则:始终将净利润与经营活动现金流进行比较。如果净利润持续超过经营活动现金流,公司可能正在确认尚未收回的收入,或推迟已发生费用的确认。这是一个重要的红旗。

2.5 每股收益

基本每股收益 = 净利润 / 加权平均流通股本
稀释每股收益 = 净利润 /(加权平均流通股本 + 稀释性证券)

每股收益是散户投资者最关注的指标,但本书警告不要进行简单的每股收益分析:


3. 资产负债表分析

3.1 资产

资产负债表按流动性顺序列报资产。本书按分析重要性分类:

流动资产——一年内可转换为现金:

项目 观察要点
现金及等价物 现金余额是否增长?是否足够6个月以上的运营?
应收账款 应收账款是否比收入增长更快?(如果是则为红旗)
存货 存货是否比收入/销售成本增长更快?(如果是则为红旗)
预付费用 异常增长可能表示渠道填充或激进会计

非流动资产——长期资源:

项目 观察要点
物业、厂房及设备 资本强度;折旧政策
无形资产 来自收购的商誉——是否有减值风险?
长期投资 投资收收益是否掩盖了运营表现疲软?

关键资产负债表规则:如果应收账款连续两个或多个季度比收入增长更快,公司可能正在过度放宽信用以膨胀收入。这是未来盈利令人失望最可靠的领先指标之一。

3.2 负债

流动负债——一年内到期:

非流动负债——一年后到期:

3.3 所有者权益

权益 = 资产 - 负债

权益代表股东的剩余索取权。关键组成部分:

关键权益规则:如果权益下降或比总资产增长更慢,公司越来越依赖债务融资。检查这种杠杆是故意的(战略投资)还是防御性的(弥补运营亏损)。

3.4 债务比率

资产负债率

资产负债率 = 总负债 / 总资产 × 100%
范围 解读
< 30% 保守,低财务风险
30-50% 中等杠杆,一般健康
50-70% 杠杆升高——在资本密集型行业(公用事业、房地产)可接受
> 70% 高风险——必须有非常稳定、可预测的现金流才能维持

产权比率

产权比率 = 总负债 / 总权益

比率高于2.0意味着公司债务是权益的两倍——显著杠杆。背景很重要:银行通常以10倍以上杠杆运营,而科技公司通常几乎没有债务。

3.5 流动比率和营运资本

流动比率

流动比率 = 流动资产 / 流动负债
范围 解读
> 2.0 强流动性——舒适的安全边际
1.5-2.0 对大多数行业足够
1.0-1.5 流动性紧张——如果现金转换快则可管理
< 1.0 潜在流动性危机——流动负债超过流动资产

速动比率——更保守的测试:

速动比率 =(流动资产 - 存货)/ 流动负债

速动比率排除存货,因为存货可能不容易以全额转换为现金(尤其是制造商、有季节性商品的零售商或产品快速贬值的科技公司)。

营运资本

营运资本 = 流动资产 - 流动负债

对大多数公司来说,负营运资本是一个警告信号,但有些企业(超市、订阅模式)由于在支付供应商之前就从客户那里收取现金,因此可以成功运营负营运资本。


4. 现金流量表分析

4.1 经营活动现金流

经营活动现金流(OCF)是财务分析中最重要的单一数字。它回答根本问题:核心业务是否产生现金?

OCF质量检查清单

□ 是否连续3年以上OCF为正?
□ OCF是否 > 净利润?(现金收益超过应计收益)
□ OCF是否以与收入增长相当的速率增长?
□ OCF是否足以覆盖资本支出(至少是维护性资本支出)?
□ OCF是否足以覆盖利息支付并有舒适余地?

OCF与净利润比率(现金含量)

现金转换质量 = 经营活动现金流 / 净利润
比率 解读
> 1.2 优秀——现金生成超过报告利润
1.0-1.2 良好——利润有现金支持
0.7-1.0 可接受但需监控——部分收益是基于应计的
< 0.7 警告——报告利润与现金之间存在显著差距
OCF为负但NI为正 重大红旗——利润仅存在于纸上

4.2 投资活动现金流

投资活动现金流揭示公司如何配置资本。对增长型公司来说,这通常为负数(用于资本支出、收购)。

关键区别

4.3 筹资活动现金流

筹资活动现金流显示公司如何为自己融资和向股东返还资本。

健康模式

不健康模式

4.4 自由现金流

自由现金流(FCF)= 经营活动现金流 - 资本支出

自由现金流是公司在维护和增长其资产基础后剩余的现金。它代表真正可供股东使用的现金——用于股息、回购、债务偿还或再投资。

FCF评估框架

场景1:FCF为正,增长         → 最佳情况。公司产生盈余现金。
场景2:FCF为正,稳定          → 良好。成熟、可靠的现金生成器。
场景3:FCF为正,下降          → 谨慎。调查原因(资本支出上升?OCF下降?)。
场景4:FCF为负,改善          → 如果公司处于高增长阶段可能可接受。
场景5:FCF为负,恶化          → 警告。现金消耗正在加速。
场景6:FCF持续为负           → 危险,除非公司是处于明确FCF路径上的预盈利公司。

4.5 现金转换周期

现金转换周期(CCC)= 存货周转天数 + 应收账款周转天数 - 应付账款周转天数

其中:
  存货周转天数(DIO)=(存货 / 销售成本)× 365
  应收账款周转天数(DSO)=(应收账款 / 营业收入)× 365
  应付账款周转天数(DPO)=(应付账款 / 销售成本)× 365

CCC衡量将存货投资转换为销售现金所需的天数。较短的CCC通常更好——意味着公司更快收回现金。

CCC 解读
负数 exceptional——公司在支付供应商之前就收取现金(例如超市)
0-30天 高效现金转换
30-60天 对大多数行业正常
60-90天 缓慢——调查应收账款或存货是否是瓶颈
> 90天 令人担忧——资本被长期占用

关键趋势规则:连续多个季度CCC上升是一个警告信号,即使绝对水平看起来合理。它表明与客户的议价能力恶化(DSO上升)、库存积压(DSO上升)或供应商关系削弱(DPO下降)。


5. 关键财务比率

5.1 净资产收益率

ROE = 净利润 / 股东权益 × 100%

ROE是股权投资者最重要的盈利能力比率。它衡量管理层使用股东资本产生利润的效率。

ROE 解读
> 20% 优秀——强劲竞争优势(持续5年以上)
15-20% 良好——高于平均的业务质量
10-15% 平均——可接受但不突出
< 10% 低于平均——可能没有创造超过权益成本的价值

关键注意事项:由高杠杆驱动的高ROE与由高利润率或高资产周转驱动的高ROE不同。杜邦分析(第6节)分解ROE以揭示来源。

5.2 资产收益率

ROA = 净利润 / 总资产 × 100%

ROA衡量相对于所有使用资本(股权和债务)的盈利能力。它对于比较不同资本结构的公司特别有用。

ROA 解读
> 10% 对大多数行业优秀
5-10% 良好
2-5% 对资本密集型行业(公用事业、银行)可接受
< 2% 弱——资产基础没有产生足够回报

5.3 投入资本回报率

ROIC = 税后净营业利润 / 投入资本 × 100%

其中:
  税后净营业利润 = 营业利润 ×(1 - 税率)
  投入资本 = 总权益 + 带息债务 - 多余现金

ROIC是最全面的盈利能力衡量标准,因为它考虑了投入业务的总资本(股权和债务),并使用营业利润(消除了资本结构决策的扭曲)。

价值创造的基本规则:当ROIC > WACC(加权平均资本成本)时,公司创造价值。如果ROIC < WACC,即使公司报告正收益,也在破坏价值。

5.4 资产负债率

见上文第3.4节。

5.5 利息保障倍数

利息保障倍数 = 营业利润(EBIT)/ 利息费用
比率 解读
> 10x 非常安全——收益多次覆盖利息
5-10x 舒适
3-5x 足够但需监控,尤其是在周期性行业
1.5-3x 紧张——低迷可能威胁债务服务
< 1.5x 危险——收益勉强覆盖利息

6. 杜邦分析

6.1 三因素分解

杜邦分析是本书理解盈利来源的核心分析框架。它将ROE分解为三个相乘的驱动因素:

ROE = 净利率 × 资产周转率 × 权益乘数

其中:
  净利率       = 净利润 / 营业收入       (每美元销售额的盈利能力)
  资产周转率   = 营业收入 / 总资产        (资产利用效率)
  权益乘数     = 总资产 / 权益             (财务杠杆)

这种分解揭示了根本不同的业务模式:

┌─────────────────────────────────────────────────────────────────────┐
│                    杜邦分析:业务模式原型                              │
├───────────────────┬──────────────┬────────────────┬─────────────────┤
│ 公司类型          │ 净利率       │ 资产周转率     │ 权益乘数         │
├───────────────────┼──────────────┼────────────────┼─────────────────┤
│ 奢侈品牌          │ 高(25%+)   │ 低(0.3-0.6)  │ 低(1.2-1.5)   │
│ 软件/SaaS         │ 高(20%+)   │ 中(0.5-1.0)  │ 低(1.1-1.5)   │
│ 必需消费品        │ 中(8-15%)  │ 中(0.8-1.2)  │ 中(1.5-2.5)   │
│ 零售/超市         │ 低(2-5%)   │ 高(2.0-3.0)  │ 中(2.0-3.0)   │
│ 银行              │ 中(15-25%) │ 低(0.02-0.05)│ 高(8-15)      │
│ 房地产            │ 中(10-20%) │ 低(0.1-0.3)  │ 高(3-6)       │
└───────────────────┴──────────────┴────────────────┴─────────────────┘

6.2 解读杜邦变化随时间的演变

杜邦分析最有价值的用法是跟踪每个组成部分随时间的变化:

6.3 五因素扩展杜邦

为了更深入的分析,本书呈现了五因素分解:

ROE =(净利润 / 税前利润)× 税前利润 / 利息和税前利润
    ×(利息和税前利润 / 营业收入)×(营业收入 / 总资产)
    ×(总资产 / 权益)
  = 税收负担 × 利息负担 × 营业利润率 × 资产周转率 × 杠杆

这进一步将税收效率和利息负担与运营表现分离,使你能够将管理层运营效率与税收策略和资本结构决策分开评估。


7. 红旗与盈利操纵检测

7.1 收入操纵信号

红旗 含义 如何检测
应收账款比收入增长更快 公司可能正在确认未付款的销售 比较4个季度以上应收账款增长%与收入增长%
季度末收入激增 渠道填充——将产品推向分销商 如果有数据,检查季度收入分布
来自关联方的收入 可能的人为交易 阅读关联方交易附注
收入确认政策突然变更 可能虚增当期收入 阅读会计政策附注、审计师报告
大额"其他收入"或营业外收入 掩盖疲软的核心业务 将营业收入与总收入分离

7.2 费用操纵信号

红旗 含义 如何检测
将运营费用资本化 低报当期费用,高报资产 检查资本支出增长 vs 收入;异常无形资产增长
折旧占固定资产比例下降 延长使用年限以减少费用 计算折旧率 = 折旧 / 固定资产原值
每年都有重组费用 "一次性"费用实际上是经常性的 跟踪5年以上的非经常性项目
突然降低税率无合理解释 可能激进的税务立场或一次性优惠 将实际税率与法定税率比较
R&D支出相对同行下降 削减投资以膨胀短期利润 将R&D/收入与行业同行进行基准比较

7.3 资产负债表红旗

红旗 含义 如何检测
商誉 > 总资产的30% 收购过度支付,减值风险 计算商誉/总资产比率
存货比销售成本增长更快 需求可能减弱;报废风险 比较存货增长%与销售成本增长%
"其他资产"或"其他应收款"增加 可能隐藏损失或关联方贷款 关注模糊类别中无法解释的增长
表外负债 真实义务隐藏在主要报表之外 阅读有关经营租赁、担保、或有事项的附注
频繁撇账或减值 前期收益被高估 跟踪累计减值费用

7.4 现金流量红旗

红旗 含义 如何检测
净利润 >> 经营活动现金流(持续) 收益质量差 OCF/NI比率 < 0.7超过3年
经营活动现金流被营运资本技巧膨胀 延长应付账款、应收账款保理 检查是否是应付账款增长推动OCF改善
资本支出远低于折旧 投资不足以膨胀FCF 比较资本支出/折旧比率(应约~1.0+)
尽管报告盈利,仍频繁发行股权 收益没有产生现金 跟踪股本和股权发行随时间变化
股息由借款资助 不可持续的派息 比较FCF与股息支付

7.5 Beneish M-Score(改编版)

本书参考了检测盈利操纵的Beneish M-Score框架简化版。关键输入变量:

DSRI =(AR_t / 收入_t)/(AR_t-1 / 收入_t-1)       应收账款天数指数
GMI  = 毛利率_t-1 / 毛利率_t                        毛利率指数
AQI  =(1 -(CA_t + PPE_t)/TA_t)/                 资产质量指数
       (1 -(CA_t-1 + PPE_t-1)/TA_t-1)
SGI  = 收入_t / 收入_t-1                              销售增长指数
DEPI =(折旧_t-1 /(折旧_t-1 + PPE_t-1))/          折旧指数
       (折旧_t /(折旧_t + PPE_t))
LVGI = 杠杆_t / 杠杆_t-1                              杠杆指数

解读:
  DSRI > 1.0  → 应收账款比收入增长更快(可疑)
  GMI  > 1.0  → 毛利率下降(操纵压力)
  AQI  > 1.0  → 资产质量恶化(可能的费用资本化)
  DEPI > 1.0  → 折旧放缓(延长资产年限)
  LVGI > 1.0  → 杠杆增加

当多个指标同时超过1.0时,盈利操纵的可能性显著增加。


8. 行业特定指标

8.1 银行和金融机构

标准利润率分析不适用于银行。关键指标:

8.2 房地产

8.3 科技/软件

8.4 制造业

8.5 零售和消费品


9. 使用财务数据选股

9.1 财务质量筛选

本书倡导多步骤筛选流程以缩小投资范围:

步骤1:淘汰劣质股

立即排除具有以下任一条件的公司:

步骤2:筛选优质股

从剩余公司中,选择满足以下全部条件的:

步骤3:估值判断

质量本身不够——你还必须考虑价格:

9.2 财务趋势分析

本书强调,财务指标的方向比绝对水平更重要:

改善趋势(买入信号):
  收入增长加速
  + 毛利率扩张
  + 营业利润率扩张
  + OCF/NI比率改善
  + ROE上升(由利润率或周转率驱动,非杠杆)
  + 债务比率稳定或下降

恶化趋势(卖出信号):
  收入增长减速
  + 毛利率收缩
  + 应收账款比收入增长更快
  + OCF/NI比率下降
  + ROE仅通过上升杠杆维持
  + 自由现金流转为负

9.3 同行比较框架

永远不要孤立地分析公司。对于每个考虑中的公司:

  1. 识别同一行业细分中3-5个直接竞争对手。
  2. 计算所有同行的关键比率。
  3. 在每个指标上对目标公司进行同行排名。
  4. 在大多数指标上排名前四分之一的公司是强候选。
  5. 在现金流指标上排名低于中位数的公司——无论盈利能力排名如何——都应谨慎对待。

10. 财务分析常见错误

10.1 仅关注每股收益

每股收益是最常报告的指标,但单独几乎不说明任何问题。仅基于每股收益增长购买股票的投资者经常陷入陷阱:

纠正:始终将每股收益与收入增长、现金流和利润率趋势一起分析。

10.2 忽视资产负债表

许多投资者检查利润表就停止了。但资产负债表揭示了利润表隐藏的风险:

纠正:资产负债表是压力测试。始终检查它。

10.3 将会计利润与现金混淆

最危险的错误。权责发生制会计允许公司报告不存在的现金的利润。典型例子:

纠正:现金流量表是真相讲述者。如果现金流持续与利润表讲述不同故事,相信现金流。

10.4 比较不同公司

对不同行业的公司应用相同的比率阈值会导致错误结论:

纠正:始终在同一行业内比较。建立行业特定基准表。

10.5 锚定于历史倍数

过去的估值倍数反映过去的情况。公司或行业的结构性变化可能永久改变适当的倍数:

纠正:将历史倍数用作一个输入,而不是唯一决定因素。结合前瞻估计和定性分析。

10.6 忽视附注和审计师报告

财务报表中最重要的信息通常在附注中:

纠正:阅读附注。审计师的保留意见或持续经营警告优先于财务报表中的所有内容。


11. 完整分析生命周期示例

11.1 目标:假设的消费电子公司

假设我们正在评估"X公司"——一家在上海证券交易所上市的中型消费电子制造商。以下是完整分析过程。

步骤1:收集5年财务数据

                        第1年    第2年    第3年    第4年    第5年
营业收入(亿元)          80.0      92.0      105.8     116.4     119.9
收入增长率                —        15.0%     15.0%     10.0%      3.0%
毛利率                   38.0%     37.5%     36.8%     35.2%     33.5%
营业利润率               14.0%     13.5%     12.8%     11.0%      8.5%
净利率                  10.5%     10.2%      9.8%      8.5%      6.2%
净利润(亿元)            8.4       9.4      10.4       9.9       7.4

总资产(亿元)          60.0      68.0      80.0      95.0     105.0
总负债                  24.0      29.0      38.0      50.0      60.0
权益                    36.0      39.0      42.0      45.0      45.0
资产负债率              40.0%     42.6%     47.5%     52.6%     57.1%

经营活动现金流(亿元)      9.0       9.8      10.0       8.5       5.0
资本支出(亿元)          4.0       5.0       7.0       9.0      10.0
自由现金流                5.0       4.8       3.0      -0.5      -5.0

应收账款                10.0      12.5      16.0      21.0      26.0
应收账款增长率            —       25.0%     28.0%     31.3%     23.8%
存货                    8.0       9.5      12.0      15.0      18.0

步骤2:识别趋势

令人担忧的信号:
  ✗ 收入增长急剧减速:15% → 15% → 10% → 3%
  ✗ 毛利率每年下降:38% → 33.5%(4年内下降4.5个百分点)
  ✗ 营业利润率比毛利率下降更快:14% → 8.5%
  ✗ 每年应收账款增长远快于收入(25%+ vs 15%或更低)
  ✗ 存货比销售成本增长更快
  ✗ 自由现金流在第4年转负并在第5年进一步恶化
  ✗ 资产负债率稳步上升:40% → 57%
  ✗ 收入增长停滞而资本支出增加

积极信号:
  ✓ 收入仍在增长(虽然很小)
  ✓ 公司仍在盈利(虽然利润率压缩)

步骤3:杜邦分解

                   第1年    第5年    变化
净利率             10.5%      6.2%     ↓ 下降
资产周转率         1.33       1.14     ↓ 下降
权益乘数           1.67       2.33     ↑ 上升(杠杆增加)
ROE               23.3%      16.4%    ↓ 下降,尽管杠杆增加

解读:ROE下降,即使公司承担更多杠杆。这意味着基础业务质量恶化速度快于杠杆可以补偿的程度。这是最危险的杜邦模式。

步骤4:现金流分析

OCF/NI比率:  第1年:1.07  第3年:0.96  第5年:0.68

现金转换质量正在恶化。到第5年,仅68%的报告收益有现金支持。结合应收账款积累,表明公司正在积极确认未收回的收入。

步骤5:结论

结论:避免/卖出

主要担忧:
1. 收入增长在公司在增加支出(资本支出)时实际上已停滞。
2. 各层面利润率都在压缩——竞争地位正在削弱。
3. 应收账款比收入增长快得多——潜在收款问题或激进收入确认。
4. 自由现金流已显著转为负。
5. 杠杆上升以补偿恶化回报——不可持续。
6. 杜邦分析证实基础业务恶化。

这家公司表现出典型的晚期衰退特征。财务数据强烈表明报告盈利能力将进一步下降,资产负债表风险正在增加。对新持仓避免;考虑卖出现有持仓。

12. 实施伪代码

12.1 财务健康筛选器

def financial_health_screen(companies: list) -> dict:
    """
    根据财务健康状况将公司筛选为三个层级。
    返回带有键的字典:'strong'、'acceptable'、'avoid'。
    """
    results = {'strong': [], 'acceptable': [], 'avoid': []}

    for company in companies:
        data = get_financial_data(company, years=5)  # 5年年度数据

        # ── 第1阶段:淘汰过滤器(任何失败 → 'avoid')──
        if any(ocf < 0 for ocf in data.operating_cash_flow[-2:]):
            results['avoid'].append((company, "最近2年OCF为负"))
            continue

        if data.debt_to_asset_ratio[-1] > 0.70 and not data.is_financial_company:
            results['avoid'].append((company, "资产负债率 > 70%"))
            continue

        if data.interest_coverage[-1] < 2.0:
            results['avoid'].append((company, "利息保障倍数 < 2倍"))
            continue

        if all(g < 0 for g in data.revenue_growth[-3:]):
            results['avoid'].append((company, "收入连续3年下降"))
            continue

        if data.auditor_opinion in ['qualified', 'adverse', 'disclaimer']:
            results['avoid'].append((company, "审计师意见保留"))
            continue

        # ── 第2阶段:质量过滤器(全部通过 → 'strong')──
        quality_checks = [
            all(roe > 0.15 for roe in data.roe[-3:]),
            all(ocf > ni for ocf, ni in zip(data.operating_cash_flow[-3:],
                                             data.net_income[-3:])),
            all(g > 0.10 for g in data.revenue_growth[-3:]),
            is_stable_or_improving(data.gross_margin[-3:]),
            sum(1 for fcf in data.free_cash_flow[-3:] if fcf > 0) >= 2,
        ]

        if all(quality_checks):
            results['strong'].append(company)
        else:
            results['acceptable'].append(company)

    return results

12.2 红旗检测器

def detect_red_flags(company) -> list:
    """
    分析公司财务中的操纵和质量红旗。
    返回(红旗名称、严重程度、描述)元组列表。
    """
    flags = []
    data = get_financial_data(company, years=5)

    # ── 收入质量红旗 ──
    for year in range(-3, 0):
        ar_growth = pct_change(data.accounts_receivable[year-1], data.accounts_receivable[year])
        rev_growth = pct_change(data.revenue[year-1], data.revenue[year])

        if ar_growth > rev_growth + 0.10:  # 应收账款比收入增长快10个百分点+
            flags.append((
                "AR_GROWTH_EXCEEDS_REVENUE",
                "高",
                f"第{year}年:应收账款增长{ar_growth:.1%} vs 收入{rev_growth:.1%}"
            ))

    # ── 存货质量红旗 ──
    for year in range(-3, 0):
        inv_growth = pct_change(data.inventory[year-1], data.inventory[year])
        cogs_growth = pct_change(data.cogs[year-1], data.cogs[year])

        if inv_growth > cogs_growth + 0.10:
            flags.append((
                "INVENTORY_GROWTH_EXCEEDS_COGS",
                "中",
                f"第{year}年:存货增长{inv_growth:.1%} vs 销售成本{cogs_growth:.1%}"
            ))

    # ── 现金流质量红旗 ──
    ocf_ni_ratios = [ocf / ni if ni > 0 else 0
                     for ocf, ni in zip(data.operating_cash_flow[-3:],
                                        data.net_income[-3:])]
    if all(r < 0.7 for r in ocf_ni_ratios):
        flags.append((
            "PERSISTENT_LOW_CASH_CONVERSION",
            "高",
            f"连续3年OCF/NI低于0.7:{ocf_ni_ratios}"
        ))

    # ── 毛利率恶化 ──
    if all(data.gross_margin[i] < data.gross_margin[i-1] for i in range(-3, 0)):
        flags.append((
            "PERSISTENT_MARGIN_DECLINE",
            "中",
            f"毛利率连续3年下降:{data.gross_margin[-4:]}"
        ))

    # ── 杠杆驱动的ROE ──
    recent_dupont = dupont_decomposition(data, year=-1)
    prior_dupont = dupont_decomposition(data, year=-3)

    if (recent_dupont.equity_multiplier > prior_dupont.equity_multiplier * 1.15
            and recent_dupont.net_margin < prior_dupont.net_margin * 0.95):
        flags.append((
            "LEVERAGE_MASKING_DECLINE",
            "高",
            "权益乘数上升而净利润下降——ROE质量下降"
        ))

    # ── 资本支出 vs 折旧 ──
    capex_depr_ratio = data.capex[-1] / data.depreciation[-1] if data.depreciation[-1] > 0 else 0
    if capex_depr_ratio < 0.5:
        flags.append((
            "UNDERINVESTMENT",
            "中",
            f"资本支出/折旧 = {capex_depr_ratio:.2f}——可能投资不足"
        ))

    # ── 商誉风险 ──
    goodwill_ratio = data.goodwill[-1] / data.total_assets[-1]
    if goodwill_ratio > 0.30:
        flags.append((
            "HIGH_GOODWILL",
            "中",
            f"商誉 = 总资产的{goodwill_ratio:.1%}——减值风险"
        ))

    # ── Beneish风格DSRI ──
    dsri = ((data.accounts_receivable[-1] / data.revenue[-1]) /
            (data.accounts_receivable[-2] / data.revenue[-2]))
    if dsri > 1.2:
        flags.append((
            "HIGH_DSRI",
            "高",
            f"DSRI = {dsri:.2f}——应收账款增长不成比例"
        ))

    return flags

12.3 比率计算器和杜邦分析器

def calculate_ratios(data) -> dict:
    """
    从原始财务数据计算所有关键财务比率。
    返回比率名称到值的字典。
    """
    ratios = {}

    # ── 盈利能力 ──
    ratios['gross_margin'] = (data.revenue - data.cogs) / data.revenue
    ratios['operating_margin'] = data.operating_profit / data.revenue
    ratios['net_margin'] = data.net_income / data.revenue
    ratios['roe'] = data.net_income / data.equity
    ratios['roa'] = data.net_income / data.total_assets

    nopat = data.operating_profit * (1 - data.effective_tax_rate)
    invested_capital = data.equity + data.interest_bearing_debt - data.excess_cash
    ratios['roic'] = nopat / invested_capital if invested_capital > 0 else 0

    # ── 流动性 ──
    ratios['current_ratio'] = data.current_assets / data.current_liabilities
    ratios['quick_ratio'] = (data.current_assets - data.inventory) / data.current_liabilities
    ratios['working_capital'] = data.current_assets - data.current_liabilities

    # ── 杠杆 ──
    ratios['debt_to_asset'] = data.total_liabilities / data.total_assets
    ratios['debt_to_equity'] = data.total_liabilities / data.equity
    ratios['interest_coverage'] = data.operating_profit / data.interest_expense \
        if data.interest_expense > 0 else float('inf')

    # ── 效率 ──
    ratios['asset_turnover'] = data.revenue / data.total_assets
    ratios['inventory_turnover'] = data.cogs / data.avg_inventory
    ratios['receivable_turnover'] = data.revenue / data.avg_accounts_receivable

    # ── 现金流 ──
    ratios['ocf_to_net_income'] = data.operating_cash_flow / data.net_income \
        if data.net_income > 0 else 0
    ratios['fcf'] = data.operating_cash_flow - data.capex
    ratios['fcf_margin'] = ratios['fcf'] / data.revenue

    # ── 现金转换周期 ──
    ratios['dio'] = (data.avg_inventory / data.cogs) * 365
    ratios['dso'] = (data.avg_accounts_receivable / data.revenue) * 365
    ratios['dpo'] = (data.avg_accounts_payable / data.cogs) * 365
    ratios['ccc'] = ratios['dio'] + ratios['dso'] - ratios['dpo']

    # ── 估值(需要市场数据)──
    if hasattr(data, 'market_cap'):
        ratios['pe_ratio'] = data.market_cap / data.net_income
        ratios['pb_ratio'] = data.market_cap / data.equity
        ratios['price_to_fcf'] = data.market_cap / ratios['fcf'] if ratios['fcf'] > 0 else float('inf')
        ratios['peg'] = ratios['pe_ratio'] / (data.eps_growth * 100) \
            if data.eps_growth > 0 else float('inf')

    return ratios


def dupont_analysis(data, years=5) -> list:
    """
    对过去N年每年进行杜邦分解。
    返回年度分解列表。
    """
    results = []

    for year_offset in range(-years, 0):
        yr = {
            'net_margin': data.net_income[year_offset] / data.revenue[year_offset],
            'asset_turnover': data.revenue[year_offset] / data.total_assets[year_offset],
            'equity_multiplier': data.total_assets[year_offset] / data.equity[year_offset],
        }
        yr['roe'] = yr['net_margin'] * yr['asset_turnover'] * yr['equity_multiplier']

        # 五因素扩展
        yr['tax_burden'] = data.net_income[year_offset] / data.pretax_income[year_offset] \
            if data.pretax_income[year_offset] > 0 else 0
        yr['interest_burden'] = data.pretax_income[year_offset] / data.ebit[year_offset] \
            if data.ebit[year_offset] > 0 else 0
        yr['operating_margin'] = data.ebit[year_offset] / data.revenue[year_offset]

        results.append(yr)

    return results


def generate_analysis_report(company) -> str:
    """
    为公司生成完整财务分析报告。
    """
    data = get_financial_data(company, years=5)
    ratios = calculate_ratios(data)
    red_flags = detect_red_flags(company)
    dupont = dupont_analysis(data)

    report_lines = []
    report_lines.append(f"=== 财务分析报告:{company.name} ===\n")

    # 第1节:盈利能力摘要
    report_lines.append("盈利能力:")
    report_lines.append(f"  毛利率:           {ratios['gross_margin']:.1%}")
    report_lines.append(f"  营业利润率:        {ratios['operating_margin']:.1%}")
    report_lines.append(f"  净利率:           {ratios['net_margin']:.1%}")
    report_lines.append(f"  ROE:              {ratios['roe']:.1%}")
    report_lines.append(f"  ROA:              {ratios['roa']:.1%}")
    report_lines.append(f"  ROIC:             {ratios['roic']:.1%}\n")

    # 第2节:流动性和杠杆
    report_lines.append("财务健康:")
    report_lines.append(f"  流动比率:          {ratios['current_ratio']:.2f}")
    report_lines.append(f"  速动比率:          {ratios['quick_ratio']:.2f}")
    report_lines.append(f"  资产负债率:        {ratios['debt_to_asset']:.1%}")
    report_lines.append(f"  利息保障倍数:       {ratios['interest_coverage']:.1f}x\n")

    # 第3节:现金流质量
    report_lines.append("现金流质量:")
    report_lines.append(f"  OCF/净利润:         {ratios['ocf_to_net_income']:.2f}")
    report_lines.append(f"  自由现金流:         {ratios['fcf']:.1f}")
    report_lines.append(f"  FCF利润率:         {ratios['fcf_margin']:.1%}")
    report_lines.append(f"  现金转换周期:       {ratios['ccc']:.0f}天\n")

    # 第4节:杜邦趋势