超级股 — 完整实施方案规范

基于肯尼斯·费雪,《超级股》(1984年)


目录

  1. 概述 — 超级股哲学
  2. 超级公司概念
  3. 市销率(PSR)— 费雪的_master_metric
  4. 产品生命周期与公司成长阶段
  5. 利润率及其预测能力
  6. 故障 — 创造机会的暂时性问题
  7. 资产负债表分析
  8. 管理层评估
  9. 三种类型的超级股
  10. 入场规则
  11. 出场规则
  12. 投资组合管理
  13. 常见错误与陷阱
  14. 完整投资生命周期示例
  15. 实施伪代码
  16. 关键语录

1. 概述 — 超级股哲学

肯尼斯·费雪(传奇成长型投资者菲利普·费雪之子)写《超级股》是为了解决一个具体问题:如何找到那些在三年到五年内股价能翻三到十倍的公司?他的答案不是追逐热门股票或跟随市场趋势,而是识别那些基本面优异但被华尔街暂时错误定价的公司。

费雪的核心论点建立在三个支柱之上:

费雪的方法从根本上不同于纯成长投资和纯价值投资。他想要成长 —— 但只为提供大的安全边际的价格。PSR是他量化安全边际的工具,这是P/E比率无法做到的。

目标范围:主要针对收入在1亿美元至50亿美元之间的科技、医疗保健和工业公司(1984年美元;经通胀调整,约合今天的3亿美元至150亿美元)。该方法最适合拥有可识别产品、可衡量市场且利润率可与行业规范基准比较的公司。

预期持有期:2-5年。费雪不是交易者。他在股票被PSR标准显著低估时买入,持有直到PSR达到高估区域。


2. 超级公司概念

2.1 定义

"超级公司"是费雪术语,指持续获得显著高于行业平均利润率的企业。这是所有事情的基础 —— 没有卓越的盈利能力,低PSR毫无意义(它可能只反映一个永久平庸的企业)。

超级公司的特征:

  1. 税前利润率 持续高于行业平均至少50%,跨多个商业周期。
  2. 收入增长一致 在滚动5年期间每年15-20%或更高。
  3. 强势竞争地位 — 在其市场细分中通常是第一或第二。
  4. 专有技术或产品 创造进入壁垒。
  5. 可扩展业务模型 — 可以高利润率添加增量收入。
  6. 管理层拥有重要所有权 和资本配置纪律的过往记录。

2.2 为什么利润率比增长更重要

费雪认为市场过度关注盈利增长,但对增长质量关注不足。两家公司都可能以每年20%的速度增长收入,但如果A公司有20%税前利润率,B公司有5%利润率:

高利润率公司天生更具弹性,每美元收入更有价值。这就是为什么PSR —— 将价格与收入进行比较 —— 只有在公司从该收入中获得的利润率背景下才有意义。

2.3 利润率可持续性测试

在将公司分类为超级公司之前,费雪要求有证据表明高利润率是结构性而非周期性的:


3. 市销率(PSR)— 费雪的 Master Metric

3.1 定义与计算

PSR = 市值 / 年总收入
    = 每股价格 / 每股收入

费雪普及了这个指标(他实际上为实际股票选择发明了它),因为它相对于P/E的优势:

特征 PSR P/E
无盈利时可用 是 — 收入总是存在 否 — 负盈利 = 无效
抗操纵性 高 — 收入比盈利更难 低 — 盈利容易通过
操纵 会计操纵
稳定性 高 — 收入比盈利更 低 — 盈利随周期
稳定 剧烈波动
可比性 调整后可跨行业 不同资本结构间
有意义 可比性较差

3.2 PSR估值区间

费雪的实证研究建立了明确的估值区间:

PSR估值区间
===================

  PSR < 0.75     买入区间 — 强烈买入。市场显著低估
                  公司收入流。这才是找到超级股的地方。

  PSR 0.75-1.0   吸引人 — 如果公司是真正的超级公司,
                  拥有强劲利润率和增长,值得买入。

  PSR 1.0-1.5   公允价值 — 如果已持有则持有。除非增长
                  前景格外优异,否则不启动新仓位。

  PSR 1.5-3.0   回避区间 — 相对于收入高估。不买。
                  如果持有,开始寻找出场机会。在此范围内
                  大多数新买入将产生糟糕的长期回报。

  PSR > 3.0      卖出区间 — 显著高估。卖出。几乎没有
                  PSR高于3的股票能提供足够的长期回报。
                  主要下跌风险非常高。

3.3 PSR调整

原始PSR必须在背景下解读:

3.4 为什么PSR有效

费雪的实证发现(得到后续学术研究支持)是,低PSR股票 —— 特别是那些低于0.75的 —— 在3-5年期间显著跑赢市场。原因心理上:

  1. 华尔街主要根据盈利为股票定价。当盈利暂时下降时(由于故障),股票急剧下跌。
  2. 但收入在故障期间通常保持稳定或继续增长。PSR跌至白菜价。
  3. 当盈利恢复时(通常对超级公司如此),股票剧烈重新定价。你廉价买入收入,现在市场为其支付全价。

4. 产品生命周期与公司成长阶段

4.1 五个阶段

费雪直接将产品生命周期概念整合到他的股票选择中。每个公司都经历可识别的阶段,每个阶段有不同的风险/回报特征:

阶段1:开发/初创

阶段2:快速增长

阶段3:成熟增长

阶段4:成熟/停滞

阶段5:衰退

4.2 识别当前阶段

费雪使用这些诊断来确定公司处于其生命周期的哪个阶段:


5. 利润率及其预测能力

5.1 利润率框架

费雪认为,税前利润率是结合PSR时预测未来股票表现的最佳单一指标:

利润率分类
====================

  税前利润率 > 15%     卓越 — 公司有真正的定价能力
                          和/或成本优势。这是超级公司
                          领域。

  税前利润率 7-15%     平均 — 竞争行业,无特殊
                          优势。如果利润率从低谷快速
                          扩张,仍可能是超级股。

  税前利润率 < 7%      低于平均 — 要么行业竞争激烈
                          要么公司管理不善。仅作为转机
                          候选人有兴趣。

5.2 利润率回归原则

费雪关于利润率的关键洞察是,它们倾向于回归公司特定规范而非行业平均。一个超级公司暂时看到利润率从20%压缩至10%由于故障,一旦故障解决,利润率可能恢复到18-22%。这创造了一个强大的投资论点:

  1. 识别具有历史高利润率的超级公司。
  2. 等待暂时事件压缩利润率低于正常水平。
  3. 当PSR低时买入(因为市场正在推断低利润率)。
  4. 持有直到利润率回归和市场重新定价股票。

5.3 利润率趋势分析

费雪跟踪5年滚动期间的利润率,寻找:


6. 故障 — 创造机会的暂时性问题

6.1 什么是故障?

"故障"是费雪最具可操作性的概念。故障是一个暂时的、可修复的问题,导致华尔街放弃一只股票,将PSR推入买入区间。关键区别在于故障(暂时的)和根本性恶化(永久的)之间。

6.2 常见故障类型

产品相关故障:

管理相关故障:

市场相关故障:

自我造成的故障:

6.3 故障 vs. 根本性恶化

这是整个系统中最重要的分析判断:

信号 故障(买入) 恶化(避免)
收入趋势 稳定或仍在增长 连续2+季度下降
竞争地位 不变 — 仍是第一或第二 正在失去份额给竞争对手
产品相关性 产品仍有需求 产品正在变得过时
管理回应 承认,有修复计划 否认、责备或困惑
客户行为 客户仍在购买 客户正在离开
行业动态 行业仍在增长 行业处于结构性下降
资产负债表 有足够实力渡过难关 恶化,债务上升
内部人士行为 内部人士持有或买入 内部人士积极卖出

6.4 故障投资论点

故障股票的投资论点遵循可预测的模式:

  1. 故障前:PSR = 1.5-3.0。股票公平或完全定价。
  2. 故障来袭:坏消息。盈利未达预期。股票下跌30-60%。PSR跌破0.75。
  3. 华尔街放弃:分析师降级,机构卖出。股票是"有毒的"。
  4. 费雪买入:PSR < 0.75,公司仍是超级公司,问题暂时的。积极买入。
  5. 故障解决(6-24个月):利润率恢复,盈利意外上行。
  6. 华尔街重新发现:分析师升级,机构回购。
  7. PSR重新定价至1.5-3.0:股票从买入价翻了或三倍。

7. 资产负债表分析

7.1 费雪的资产负债表检查清单

费雪使用资产负债表作为安全检查 —— 不是作为主要选择工具,而是作为消除缺乏财务实力以度过故障的公司的一种方式:

  1. 债务权益比:对于大多数行业应低于0.40。高债务公司无法度过暂时性问题,可能被迫在恰恰错误的时机进行稀释性融资。

  2. 流动比率:应高于1.5。无法覆盖短期义务的公司面临流动性危机风险,将故障转化为灾难。

  3. 利息保障倍数:税前利润应至少覆盖利息费用5倍。较低的保障意味着公司在利率上升或利润率压缩时容易受到伤害。

  4. 现金头寸:费雪偏好拥有大量现金储备的公司。净现金(现金减去总债务)是理想的 —— 这意味着公司有度过低迷期的战争基金。

  5. 应收账款趋势:相对于收入上升的应收账款可能标志公司正在填充渠道或延长信用以维持销售 —— 未来收入减弱的警告。

  6. 库存趋势:相对于销售成本上升的库存可能标志需求减弱或过时风险。

7.2 资产负债表红旗

费雪识别了使股票不符合考虑资格的具体模式:


8. 管理层评估

8.1 费雪的管理标准

继承其父菲利普·费雪对定性分析的强调,肯尼斯·费雪通过可观察的具体行为评估管理层:

  1. 所有权股份:拥有重要股票的管理层(至少合计5%)与股东一致。内部所有权低于1%是警告。

  2. 资本配置历史:管理层如何部署自由现金流?

    • 在高回报资本上再投资 = 优秀。
    • 在低PSR水平回购 = 优秀。
    • 以合理价格进行整合良好的收购 = 好。
    • 以高价格进行帝国建设收购 = 破坏性。
    • 高管薪酬过高 = 警告。
  3. 沟通诚实:管理层是否坦率讨论问题,还是将每个负面转化为正面?费雪重视过度承诺和不足交付的管理层。

  4. 运营专注:专注于产品质量和客户满意度的管理层建立持久特许经营权。专注于财务工程和短期盈利管理的管理层摧毁价值。

  5. 逆境过往记录:管理层如何处理上一次低迷?他们是智能削减成本、保护核心业务并以更强姿态出现?还是恐慌、削减研发并失去人才?

8.2 "传言"方法

直接继承自菲利普·费雪,流言方法涉及从非传统来源收集信息:


9. 三种类型的超级股

9.1 类型1:超级公司

定义:具有卓越盈利能力、强劲增长和主导竞争地位的公司,由于暂时故障而被暂时低估。

特征:

预期回报:3-10倍于3-5年,因为故障解决、利润率恢复和PSR从0.75以下重新定价至1.5-3.0。

风险:"故障"原来是永久性恶化。

费雪最喜欢的类型:这是战略的核心。以白菜价收购超级公司是最高概率、最高回报的机会。

9.2 类型2:超级周期股

定义:在周期底部以最低PSR买入的周期行业(汽车、化工、钢铁、建筑)中有优越成本结构和资产负债表的公司。

特征:

预期回报:周期转向和PSR重新定价后1-3年内2-5倍。

风险:你买得太早(周期还有进一步下跌)或周期因结构性变化而未恢复。

与超级公司的关键区别:估值论点是周期恢复,而非故障解决。你必须对周期判断正确,而不只是对公司。

周期时机:

9.3 类型3:超级转机

定义:曾经是超级公司、迷失方向、现在在新管理层领导下正在恢复历史盈利能力。

特征:

预期回报:如果转机成功,2-5年内3-10倍。

风险:三种类型中最高。许多转机失败。费雪建议对转机投资使用更小仓位和更严格的分散化。

转机检查清单:

  1. 是否有具有成功转机过往记录的可信新CEO?
  2. 新团队是否确定了具体的、可衡量的成本节约和收入举措?
  3. 资产负债表是否足够强劲以度过另外2-3年的糟糕表现?
  4. 内部人士是否用自己的钱购买股票(不只是收取期权)?
  5. 在前2-3个季度内是否有进展的早期迹象 —— 即使是小的?

10. 入场规则

10.1 强制标准(全部必须通过)

入场过滤器检查清单
======================

  1. PSR < 0.75            股票必须在买入区间。无例外。
                            对于最快增长的超级公司,如果所有其他
                            标准都出色,PSR < 1.0可接受。

  2. 税前利润率       对于超级公司:必须有利润率比行业高
     高于行业平均      50%+ 的历史往绩记录。当前利润率
                            可能已受压(那是机会),
                            但必须显示恢复潜力的证据。

  3. 收入增长         对于超级公司,滚动5年收入CAGR应至少
     >= 15% CAGR            15%。对于周期股,收入应高于
                            先前周期谷底。对于转机,
                            收入基础必须可观。

  4. 债务权益比         对于超级公司和转机,低于0.40。
     < 0.40                对于周期股,低于0.60(通常
                            携带更多债务)。

  5. 流动比率 > 1.5   公司必须能够轻松覆盖短期义务。

  6. 可识别的故障   必须有具体的、可描述的原因为什么
                            股票便宜。如果你无法识别故障,
                            低PSR可能反映真正的永久性问题。

  7. 产品仍有 viability  公司的核心产品必须仍有需求。
                            客户仍需要公司销售的东西。

  8. 管理层质量    至少一项:重要内部所有权(>5%),
                            近期内部人士购买,或具有强劲
                            转机往绩记录的新CEO。

10.2 入场时的仓位配置

费雪没有规定严格的仓位配置规则,但他的原则暗示:

10.3 入场时机

费雪不是市场时机者,但他提供实用指导:


11. 出场规则

11.1 强制卖出信号

出场触发器检查清单
======================

  1. PSR > 3.0             立即卖出。无论增长率如何,
                            PSR > 3.0的股票没有足够的风险/回报。

  2. PSR 1.5-3.0           开始卖出。股票不再便宜。至少卖出
                            50%仓位。只有在增长加速和利润率
                            扩张时才持有剩余部分。

  3. 利润率恶化  如果税前利润率连续3+个季度下降
                            没有明确暂时解释,卖出。超级公司
                            论点可能已打破。

  4. 收入下降        对于非周期公司,连续两个季度同比收入
                            下降 = 卖出。产品生命周期可能已
                            转移至阶段4-5。

  5. 资产负债表        债务权益比上升至0.75以上,或流动比率
     恶化          降至1.0以下 = 卖出。公司的财务
                            安全边际已蒸发。

  6. 管理离职  如果CEO和/或关键高管意外离职,
                            且离职不是有计划继任的一部分,
                            卖出至少50%仓位。

  7. 竞争        有清晰证据表明竞争对手开发了
      disruption        威胁公司核心特许经营权 superior 产品
                            或技术 = 卖出。

  8. 论点违反       如果你买入股票的具体原因不再成立
                            (例如,故障原来是永久的,
                            转机计划被放弃,周期未恢复),
                            无论当前PSR如何,卖出。

11.2 渐进出场

费雪建议逐步减仓而非倾倒整个仓位:

11.3 时间止损

如果股票持有3年以上且没有显著价格升值,且论点未实现,考虑卖出无论当前PSR。资本有机会成本,停滞的投资占用可部署到更高概率机会的资金。


12. 投资组合管理

12.1 分散化

费雪建议集中但不鲁莽的投资组合:

12.2 审查周期

12.3 加仓赢家vs. 输家

费雪在这一点上与许多价值投资者不同:

12.4 投资组合PSR概况

费雪建议监测整体投资组合的加权平均PSR:


13. 常见错误与陷阱

13.1 购买低PSR而不检查质量

最危险的错误。坏公司上的低PSR不是 bargain —— 是价值陷阱。利润率2%、收入下降和重债公司的PSR 0.30是正确定价的。PSR过滤器仅对超级公司(或转机中的前超级公司)有效。

13.2 将故障与永久性问题混淆

这需要最多的分析判断。警告"故障"实际上是永久性的关键迹象:

13.3 卖出太早

费雪强调超级股经常在几年内翻三或四倍。在一年后获得50%利润的诱惑是强烈的,但它意味着错过剩余的200-300%收益。根据PSR区间卖出,而非基于任意利润目标。

13.4 忽视资产负债表

拥有弱资产负债表的超级公司更容易受到故障影响,因为:

13.5 爱上一个故事

每个超级股都有引人入胜的叙述。危险是继续持有 —— 或更糟,在论点明显破裂后因为你对故事情感依恋而增加仓位。

13.6 过度分散化

拥有50+股票使得深入研究每个股票成为不可能。费雪的流言方法需要时间和努力。最好拥有15只你深入了解的股票,而非50只你肤浅了解的股票。

13.7 忽视宏观背景

虽然费雪是自下而上的股票选择者,他承认即使以牛市顶部最好的超级股票价格买入(当所有PSR都偏高时)也会降低回报。为熊市持有现金储备是有意义的优势。


14. 完整投资生命周期示例

阶段1:筛选

你对3,000只中盘股运行PSR筛选,识别45家PSR低于0.75的公司。你进一步过滤利润率质量,得到8个候选。其中一个突出:

MedTech Instruments — 筛选结果
-----------------------------------------
市值:             $8亿
年收入:          $14亿
PSR:                    0.57($8亿/$14亿)
5年收入CAGR:    18%
税前利润率(5年平均):16.2%(行业平均:9.8%)
当前税前利润率:8.1%(受压)
债务权益比:         0.28
流动比率:          2.1
内部人士所有权:      7.2%
近期内部人士购买:  CFO 6周前购买了$25万股票

PSR在买入区间深处(0.57 < 0.75)。公司历史上是超级公司(16.2%利润率vs.9.8%行业平均)。当前利润率受压(8.1%),暗示故障。所有资产负债表标准通过。

阶段2:识别故障

你调查发现:

评估:这是教科书般的故障。问题是真实的但是暂时的。公司的竞争地位未变。利润率 depression是由于不会重复的一次性成本。

阶段3:入场

阶段4:不舒服的时期(月份1-4)

第1月:股票跌至$12.50。又一位分析师降级。PSR跌至0.51。基本面未变。持有。

第2月:季度盈利显示收入下降8%(工厂关闭影响)。利润率仍受压于7.5%。股票跌至$11.00。PSR = 0.45。你的持仓下跌21%。你重新检查论点:工厂现在已全力生产。客户订单正在完成。你增加剩余40%的计划仓位:1,818股在$11.00 = $20,000。总持仓:5,388股,平均成本$13.00。

第4月:工厂恢复在线后的第一个完整季度。收入同比增长3%。利润率改善至11.2%。股票涨至$13.50。PSR = 0.55。

阶段5:恢复(月份5-12)

第6月:收入同比增长15%。利润率在13.8%(接近历史规范)。积压正在清理。一位分析师升级至"买入"。股票涨至$19.00。PSR = 0.78。持仓价值$102,372(相对于投入资本$70,000上涨46%)。

第9月:收入同比增长22%。利润率在15.5%(恢复至超级公司水平)。两位更多分析师开始覆盖。一家中小盘成长基金买入4%股份。股票涨至$26.00。PSR = 1.06。

第12月:收入同比增长20%。利润率在16.8%。股票达到$32.00。PSR = 1.31。

阶段6:渐进出场(月份12-18)

第12月:PSR = 1.31(在1.0-1.5公允价值区间)。根据渐进出场规则,你卖出25%持仓:1,347股在$32.00 = $43,104。

第15月:股票达到$42.00。PSR = 1.71(进入回避区间)。你再卖出25%:1,347股在$42.00 = $56,574。

第18月:股票达到$48.00。PSR = 1.96。你卖出剩余50%:2,694股在$48.00 = $129,312。

结果摘要
==============
总投入:   $70,000(5,388股,平均$13.00)
总收入:   $228,990
净利润:   $158,990
回报:           227%,18个月
年化:           约120%

入场时PSR:     0.57(买入区间)
出场时PSR:      1.71-1.96(回避区间)
入场时利润率:  8.1%(受故障压低)
出场时利润率:   16.8%(恢复至超级公司水平)

阶段7:事后分析


15. 实施伪代码

15.1 PSR筛选器

# =============================================================================
# 超级股 — PSR筛选器
# 基于肯尼斯·费雪《超级股》(1984年)的标准
# =============================================================================

class SuperStockScreener:
    """
    根据费雪的基于PSR的标准筛选股票宇宙。
    返回分类为超级公司、超级周期股或超级转机的候选,
    按PSR排序(升序)。
    """

    # --- PSR阈值 ---
    PSR_BUY_MAX = 0.75              # 买入区间最大PSR
    PSR_ATTRACTIVE_MAX = 1.00       # 吸引人区间最大PSR
    PSR_AVOID_MIN = 1.50            # 回避区间最小PSR
    PSR_SELL_MIN = 3.00             # 立即卖出最小PSR

    # --- 基本标准 ---
    MIN_REVENUE_CAGR_5Y = 15.0      # 最小5年收入CAGR(%)
    MIN_PRETAX_MARGIN_HIST = 12.0    # 最小历史税前利润率(%)
    MARGIN_SUPERIORITY_FACTOR = 1.5  # 利润率必须比行业平均高50%
    MAX_DEBT_TO_EQUITY = 0.40        # 超级公司最大D/E
    MAX_DEBT_TO_EQUITY_CYCL = 0.60   # 周期股最大D/E
    MIN_CURRENT_RATIO = 1.50         # 最小流动比率
    MIN_INTEREST_COVERAGE = 5.0      # 最小利息保障倍数
    MIN_INSIDER_OWNERSHIP = 5.0      # 最小内部人士所有权(%)

    def __init__(self, data_provider):
        self.data = data_provider

    def screen(self, universe):
        """
        对股票宇宙运行PSR和基本过滤器。
        返回包含三个列表的字典:super_companies、super_cyclicals、
        super_turnarounds — 每个按PSR升序排序。
        """
        results = {
            'super_companies': [],
            'super_cyclicals': [],
            'super_turnarounds': [],
            'rejected': [],
        }

        for ticker in universe:
            evaluation = self.evaluate(ticker)

            if evaluation['category'] == 'SUPER_COMPANY':
                results['super_companies'].append((ticker, evaluation))
            elif evaluation['category'] == 'SUPER_CYCLICAL':
                results['super_cyclicals'].append((ticker, evaluation))
            elif evaluation['category'] == 'SUPER_TURNAROUND':
                results['super_turnarounds'].append((ticker, evaluation))
            else:
                results['rejected'].append((ticker, evaluation))

        # 按PSR升序排序每个列表(最便宜在前)
        for key in ['super_companies', 'super_cyclicals', 'super_turnarounds']:
            results[key].sort(key=lambda x: x[1]['psr'])

        return results

    def evaluate(self, ticker):
        """评估单个股票并分类。"""
        stock = self.data.get_fundamentals(ticker)
        industry = self.data.get_industry_data(stock.industry)

        result = {
            'ticker': ticker,
            'company_name': stock.name,
            'industry': stock.industry,
            'market_cap': stock.market_cap,
            'annual_revenue': stock.annual_revenue,
        }

        # --- 核心指标:市销率 ---
        psr = stock.market_cap / stock.annual_revenue if stock.annual_revenue > 0 else float('inf')
        result['psr'] = round(psr, 3)
        result['psr_zone'] = self._classify_psr(psr)

        # --- 利润率分析 ---
        result['pretax_margin_current'] = stock.pretax_margin
        result['pretax_margin_5y_avg'] = stock.pretax_margin_5y_avg
        result['industry_avg_margin'] = industry.avg_pretax_margin

        margin_superiority = (
            stock.pretax_margin_5y_avg / industry.avg_pretax_margin
            if industry.avg_pretax_margin > 0 else 0
        )
        result['margin_superiority_ratio'] = round(margin_superiority, 2)
        result['is_super_margin'] = margin_superiority >= self.MARGIN_SUPERIORITY_FACTOR

        # --- 收入增长 ---
        result['revenue_cagr_5y'] = stock.revenue_cagr_5y
        result['revenue_growing'] = stock.revenue_cagr_5y >= self.MIN_REVENUE_CAGR_5Y
        result['revenue_trend'] = self._revenue_trend(stock.annual_revenue_history)

        # --- 资产负债表 ---
        result['debt_to_equity'] = stock.debt_to_equity
        result['current_ratio'] = stock.current_ratio
        result['interest_coverage'] = stock.interest_coverage
        result['net_cash'] = stock.cash - stock.total_debt

        balance_sheet_pass = (
            stock.current_ratio >= self.MIN_CURRENT_RATIO
            and stock.interest_coverage >= self.MIN_INTEREST_COVERAGE
        )
        result['balance_sheet_pass'] = balance_sheet_pass

        # --- 内部人士活动 ---
        result['insider_ownership_pct'] = stock.insider_ownership_pct
        result['recent_insider_buying'] = stock.recent_insider_net_purchases > 0

        # --- 分类 ---
        result['category'] = self._categorise(result, stock, industry)
        result['glitch_identified'] = 'REQUIRES_MANUAL_REVIEW'

        return result

    def _classify_psr(self, psr):
        """将PSR分类到费雪的估值区间。"""
        if psr < self.PSR_BUY_MAX:
            return 'BUY'
        elif psr < self.PSR_ATTRACTIVE_MAX:
            return 'ATTRACTIVE'
        elif psr < self.PSR_AVOID_MIN:
            return 'FAIR_VALUE'
        elif psr < self.PSR_SELL_MIN:
            return 'AVOID'
        else:
            return 'SELL'

    def _categorise(self, result, stock, industry):
        """
        确定公司是哪种超级股(如果有的话)。
        返回:SUPER_COMPANY、 SUPER_CYCLICAL、 SUPER_TURNAROUND或REJECTED。
        """

        # 必须在买入或吸引人PSR区间
        if result['psr_zone'] not in ('BUY', 'ATTRACTIVE'):
            return 'REJECTED'

        # 必须通过资产负债表检查
        if not result['balance_sheet_pass']:
            return 'REJECTED'

        # --- 测试超级公司 ---
        if (result['is_super_margin']
                and result['revenue_growing']
                and stock.debt_to_equity <= self.MAX_DEBT_TO_EQUITY
                and result['pretax_margin_5y_avg'] >= self.MIN_PRETAX_MARGIN_HIST):
            return 'SUPER_COMPANY'

        # --- 测试超级周期股 ---
        if (industry.is_cyclical
                and stock.debt_to_equity <= self.MAX_DEBT_TO_EQUITY_CYCL
                and result['margin_superiority_ratio'] >= 1.2  # 至少高于平均20%
                and self._at_cycle_trough(stock, industry)):
            return 'SUPER_CYCLICAL'

        # --- 测试超级转机 ---
        if (stock.pretax_margin_peak_5y >= self.MIN_PRETAX_MARGIN_HIST
                and stock.pretax_margin < stock.pretax_margin_peak_5y * 0.50
                and stock.debt_to_equity <= self.MAX_DEBT_TO_EQUITY
                and stock.annual_revenue > 200_000_000  # 可观收入基础
                and (stock.new_ceo_within_2y or result['recent_insider_buying'])):
            return 'SUPER_TURNAROUND'

        return 'REJECTED'

    def _at_cycle_trough(self, stock, industry):
        """确定行业是否接近周期谷底。"""
        return (
            industry.capacity_utilisation < 75
            or industry.revenue_yoy_change < -10
            or stock.pretax_margin < stock.pretax_margin_5y_avg * 0.50
        )

    def _revenue_trend(self, revenue_history):
        """分析5年期间的收入趋势。"""
        if len(revenue_history) < 3:
            return 'INSUFFICIENT_DATA'

        increases = sum(
            1 for i in range(1, len(revenue_history))
                if revenue_history[i] > revenue_history[i - 1]
        )
        ratio = increases / (len(revenue_history) - 1)

        if ratio >= 0.8:
            return 'CONSISTENTLY_GROWING'
        elif ratio >= 0.6:
            return 'MOSTLY_GROWING'
        elif ratio >= 0.4:
            return 'MIXED'
        else:
            return 'DECLINING'

15.2 超级股分类器和投资组合监控器

# =============================================================================
# 投资组合管理 — 超级股实施
# =============================================================================

class SuperStockPortfolio:
    """
    通过费雪的PSR方法管理超级股投资组合。
    按类别处理仓位配置、基于PSR的出场信号,
    和仓位的渐进减仓。
    """

    # 按类别的仓位配置(占投资组合%)
    POSITION_SIZE = {
        'SUPER_COMPANY':   5.0,   # 更高信念
        'SUPER_CYCLICAL':  4.0,   # 中等信念
        'SUPER_TURNAROUND': 2.5,  # 更低信念 — 更高风险
    }

    MAX_POSITIONS = 25
    MIN_POSITIONS = 12
    MAX_SINGLE_POSITION_PCT = 8.0
    MAX_INDUSTRY_PCT = 30.0
    MIN_CASH_PCT = 5.0
    MAX_CASH_PCT = 15.0

    # 类别混合目标
    TARGET_MIX = {
        'SUPER_COMPANY':    (0.50, 0.60),   # 投资组合的50-60%
        'SUPER_CYCLICAL':   (0.20, 0.30),   # 20-30%
        'SUPER_TURNAROUND': (0.10, 0.20),   # 10-20%
    }

    def __init__(self, screener, initial_capital):
        self.screener = screener
        self.capital = initial_capital
        self.cash = initial_capital
        self.positions = {}
        self.trade_log = []

    def add_position(self, ticker, price, evaluation):
        """基于类别特定配置开设新仓位。"""
        category = evaluation['category']
        if category not in self.POSITION_SIZE:
            print(f"阻止:{ticker}不是公认的超级股类别")
            return False

        portfolio_value = self.get_portfolio_value()

        # 基于类别的仓位大小
        target_pct = self.POSITION_SIZE[category]
        position_value = portfolio_value * (target_pct / 100)

        # 检查投资组合约束
        if len(self.positions) >= self.MAX_POSITIONS:
            print(f"阻止:投资组合已满({self.MAX_POSITIONS}个持仓)")
            return False

        if (self.cash - position_value) < portfolio_value * (self.MIN_CASH_PCT / 100):
            print("阻止:将会 breach 最小现金储备")
            return False

        industry = evaluation['industry']
        industry_exposure = self.get_industry_exposure(industry)
        if (industry_exposure + position_value) / portfolio_value > (self.MAX_INDUSTRY_PCT / 100):
            print(f"阻止:行业{industry}将超过{self.MAX_INDUSTRY_PCT}%")
            return False

        # 执行 — 初始 tranche 是目标的60%
        initial_tranche = position_value * 0.60
        shares = int(initial_tranche / price)
        cost = shares * price

        self.positions[ticker] = {
            'shares': shares,
            'avg_cost': price,
            'entry_date': today(),
            'entry_psr': evaluation['psr'],
            'category': category,
            'industry': industry,
            'target_total_shares': int(position_value / price),
            'tranches_completed': 1,
            'entry_evaluation': evaluation,
        }
        self.cash -= cost

        self.trade_log.append({
            'action': 'BUY',
            'tranche': '1 of 2',
            'ticker': ticker,
            'shares': shares,
            'price': price,
            'psr_at_trade': evaluation['psr'],
            'category': category,
            'date': today(),
        })

        return True

    def add_second_tranche(self, ticker, price):
        """
        在论点确认后(如下一份盈利报告支持故障论点)
        添加剩余40%的计划仓位。
        """
        if ticker not in self.positions:
            print(f"阻止:{ticker}不在投资组合中")
            return False

        pos = self.positions[ticker]
        if pos['tranches_completed'] >= 2:
            print(f"阻止:{ticker}已完全配置")
            return False

        remaining_shares = pos['target_total_shares'] - pos['shares']
        cost = remaining_shares * price

        if cost > self.cash:
            print(f"阻止:现金不足(需要${cost},有${self.cash})")
            return False

        self.positions[ticker]['shares'] += remaining_shares
        self.cash -= cost

        self.trade_log.append({
            'action': 'BUY',
            'tranche': '2 of 2',
            'ticker': ticker,
            'shares': remaining_shares,
            'price': price,
            'date': today(),
        })

        return True

    def check_exit_signals(self, ticker, current_psr, fundamentals):
        """
        根据费雪的PSR区间规则检查出场信号。
        返回建议的动作。
        """
        if ticker not in self.positions:
            return None

        pos = self.positions[ticker]
        entry_psr = pos['entry_psr']
        category = pos['category']

        # 强制卖出:PSR > 3.0
        if current_psr > 3.0:
            return {
                'action': 'SELL_ALL',
                'reason': f'PSR {current_psr:.2f} > 3.0 — 显著高估'
            }

        # 开始卖出:PSR 1.5-3.0
        if current_psr >= 1.5:
            return {
                'action': 'SELL_50%',
                'reason': f'PSR {current_psr:.2f} 进入回避区间'
            }

        # 检查利润率侵蚀
        if fundamentals.get('margin_quarters_declining', 0) >= 3:
            return {
                'action': 'REVIEW',
                'reason': '利润率连续3+季度下降'
            }

        return None

    def gradual_exit(self, ticker, current_price):
        """
        按费雪的渐进出场协议减仓。
        """
        pos = self.positions[ticker]
        shares = pos['shares']
        current_psr = self.get_current_psr(ticker, current_price)

        if current_psr >= 2.0:
            # 卖出50%
            sell_shares = shares // 2
            self.execute_sell(ticker, sell_shares, current_price)
            return f"PSR {current_psr:.2f} — 卖出50% ({sell_shares}股)"

        if current_psr >= 1.5:
            # 卖出25%
            sell_shares = shares // 4
            self.execute_sell(ticker, sell_shares, current_price)
            return f"PSR {current_psr:.2f} — 卖出25% ({sell_shares}股)"

        return "PSR仍在持有区间"

    def get_portfolio_value(self):
        """计算当前投资组合总价值。"""
        positions_value = sum(
            pos['shares'] * self.get_current_price(ticker)
            for ticker, pos in self.positions.items()
        )
        return positions_value + self.cash

    def get_industry_exposure(self, industry):
        """计算给定行业的总敞口。"""
        return sum(
            pos['shares'] * self.get_current_price(ticker)
            for ticker, pos in self.positions.items()
            if pos['industry'] == industry
        )

16. 关键语录

"超级公司是在行业内持续赚取超额利润的公司。当这些公司由于暂时性'故障'而被市场忽视时,智慧投资者有机会以折扣价买入它们。"

"购买低PSR股票的关键不是找到便宜的股票,而是找到因暂时性问题而便宜的优质公司。便宜的低质量公司是价值陷阱。"

"故障是朋友。寻找那些因暂时性问题而暂时不受欢迎的优质公司。这些问题越严重,华尔街的反应越过度,你的安全边际就越大。"

"投资超级股需要耐心。你必须在其他人恐惧时买入,并持有直到市场认识到公司的真实价值。这通常需要两到五年的时间。"

"永远不要给亏损仓位加仓。如果你买入时论点正确,但股票下跌了,那是因为市场在短期内是无效的。增加亏损仓位是加倍赌注于你的错误。"

"卖出超级股需要纪律。不要仅仅因为股票上涨就卖出。根据估值卖出。当PSR告诉你卖出时,服从。"

"费雪的PSRmakes简单的事情变简单:找到赚钱的公司,以低PS荣的价格买入。剩下的就是纪律和耐心。"


实施方案规范编译自肯尼斯·费雪,《超级股》(1984年)。 本文件是实践应用的系统提炼,不替代阅读原作。

(文件结束 — 共1187行)