逆向投资——完整实施规范

基于安东尼·波顿,《逆向投资》(2009年)


目录

  1. 概述
  2. 逆向投资哲学
  3. 选股流程
  4. 估值方法
  5. 管理层评估
  6. 催化剂识别
  7. 组合构建
  8. 风险管理
  9. 卖空
  10. 板块分析与宏观意识
  11. 行为纪律
  12. 常见错误与陷阱
  13. 投资生命周期示例
  14. 实施伪代码
  15. 关键语录

1. 概述

1.1 本书是什么

《逆向投资》是安东尼·波顿对1979-2007年管理富达特殊 situations基金的28年经验提炼,期间他实现了约19.5%的年化复合回报,而富时全股指数约13.5%。波顿通常被称为"英国的巴菲特",他在成立时投入的1000英镑到退休时变成了超过147,000英镑——这一记录使他成为英国历史上最伟大的基金经理之一。

本书不是公式化系统,而是实践者手册,揭示波顿如何实际发现、评估、买入、持有和卖出股票。涵盖了他的逆向投资哲学、对管理质量的执着、多重估值方法的使用,以及120-150个仓位的纪律组合构建方法。

1.2 为什么重要

波顿的方法独特,因为它桥接了多种投资风格:

他并不僵化地附属于任何单一学派。他称自己为"实用投资者",使用任何有效的工具。

1.3 业绩背景

时期 富达特殊situations 富时全股指数 超额表现
1979-2007(28年) ~19.5%年化 ~13.5%年化 ~6%每年
累计 ~147倍 ~36倍 ~4倍相对
最差回撤期 参与但更快恢复
一致性 大多数年份跑赢基准

1.4 基金特征


2. 逆向投资哲学

2.1 核心原则

波顿的核心论点是,共识意见错误时产生最佳投资机会。市场由人类情绪驱动——恐惧和贪婪——这创造了系统性的错误定价。逆向投资者通过识别群体在任一方向过度反应的状況来获利。

逆向不是为不同而不同。当你自己分析告诉你共识错误时,有信念与共识背道而驰才是逆向。

2.2 为什么逆向主义有效

波顿识别了与群体对抗产生超额回报的几个结构性原因:

  1. 机构从众:职业基金经理围绕基准权重和共识预测聚集,因为职业风险惩罚偏离甚于惩罚糟糕的绝对回报
  2. 外推偏见:投资者无限期地投射近期趋势——连续两个糟糕季度的公司被假定为永久衰落
  3. 忽视溢价:失宠的股票失去分析师覆盖,创造信息低效
  4. 不对称风险/回报:当预期已经处于最低点时,下行空间有限,但任何正面惊喜的上行空间是实质性的
  5. 均值回归:企业盈利能力和估值往往回归长期均值

2.3 逆向频谱

波顿区分了逆向主义的程度:

程度 描述 示例
温和 略微超配失宠板块 在轻微低迷期间增持银行
适度 买入大多数分析师评级"卖出"的股票 在盈利预警后购买零售商
强劲 在广泛被厌恶的名称上持有大仓位 在监管危机中买入面临困境的公司
极端 在每个人都在卖出的市场恐慌中买入 在2008年10月全面增持

波顿主要在适度至强劲水平操作。他不是深度价值的"雪茄屁股"投资者——他需要看到可信的恢复路径,而不仅仅是统计便宜。

2.4 逆向赌注的条件

波顿仅在以下情况下与群体对抗:

2.5 共识何时正确

波顿明确警告,逆向主义不是普遍策略。共识对的时候多于错的时候。关键技能是区分:


3. 选股流程

3.1 三大支柱

波顿的选股建立在三个类别上,每个都有独特特征:

支柱1:恢复 ситуации

经历了盈利或股价显著下跌的公司,波顿认为最坏情况已过,改善即将到来。

特征

波顿寻找

支柱2:低估成长

以比市场预期更快的速度增长的公司,但增长或其持续时间被低估。

特征

波顿寻找

支柱3:特殊 ситуации

创造独立于市场方向的价值的公司事件或结构性变化。

类型

3.2 想法生成管道

波顿的想法生成是系统性的多来源:

  1. 量化筛选:定期运行,以表面统计上便宜的股票(低P/E、高收益率、低市净率、高自由现金流收益率)
  2. 券商研究:大量阅读但专注于事实而非结论——波顿形成自己的观点
  3. 公司会议:每周5-10家,全年约300-400家
  4. 行业联系人:建立行业专家和私企高管网络
  5. 52周低点清单:定期审查触及新低的股票以寻找恢复候选
  6. 内部人士交易申报:监控董事交易以寻找信念信号
  7. 同行推荐:与其他基金经理讨论想法,特别是利基领域的专家

3.3 过滤过程

从数百个潜在想法中,波顿应用连续过滤:

第1阶段:初步筛选(量化)
  → 每季度约200-300个候选

第2阶段:快速定性检查
  → 业务可理解吗?
  → 有可信的错误定价原因吗?
  → 约80-120个候选存活

第3阶段:深度定性研究
  → 公司会议、竞争对手分析、财务建模
  → 约30-50个候选存活

第4阶段:估值和催化剂检查
  → 上行空间是否足够(至公允价值30%+)?
  → 有可识别的催化剂在12-18个月内吗?
  → 每季度15-25个新仓位

第5阶段:组合适配
  → 它改善多元化吗?
  → 有能力添加而不超过板块限制吗?
  → 最终添加

4. 估值方法

4.1 多方法方法

波顿从不依赖单一估值指标。他使用多种方法,寻找收敛——当几种方法指向相同结论时,他的信心增加。

4.2 主要估值工具

4.2.1 市盈率(P/E)

4.2.2 企业价值/EBITDA(EV/EBITDA)

4.2.3 自由现金流收益率

4.2.4 市净率

4.2.5 分部总和(SOTP)

4.2.6 股息收益率

4.3 估值红旗

波顿同样专注于避免高估:

4.4 安全边际

波顿要求在买入前与他的公允价值估计有意义的折扣。他不严格量化这个,但操作这些一般准则:


5. 管理层评估

5.1 关键变量

波顿认为管理层质量是选股中最重要的单一因素。廉价股票加糟糕管理层是价值陷阱。合理价格加出色管理层可以是好投资。

我宁愿买平庸业务加出色管理层,也不愿买出色业务加平庸管理层。

5.2 波顿评估管理层的内容

5.2.1 记录

5.2.2 资本配置技能

5.2.3 利益对齐

5.2.4 诚实和沟通

5.2.5 运营专注

5.3 管理层会议技术

波顿的公司会议方法独特:

  1. 准备:在任何会议前阅读最新年报、券商笔记和竞争对手分析
  2. 开放式问题:在钻入具体细节前从广泛问题开始("你面临的三最大挑战是什么?")
  3. 肢体语言:密切关注非语言线索——犹豫、回避、过度自信
  4. 一致性检查:在不同会议点以不同方式问同样问题
  5. 竞争对手情报:问管理层关于竞争对手——往往比他们说自己更揭示
  6. 跟进:与中层管理、客户和供应商交谈以验证CEO声称的内容
  7. 频率:每年多次与同一家公司交谈以跟踪消息演变

5.4 管理层更迭作为催化剂

波顿最有利可图的模式之一是在新任强大CEO被任命用于挣扎公司时买入。顺序:

  1. 公司表现不佳 → 股价下跌 → 旧CEO离职
  2. 具有强劲记录的新CEO被任命
  3. 波顿在新战略宣布前的"不确定缺口"期间买入
  4. 新CEO交付战略审查,常涉及成本削减、处置和专注
  5. 盈利恢复 → 股价重估 → 波顿获利了结

6. 催化剂识别

6.1 为什么催化剂重要

股票可以便宜多年而不上涨。波顿坚持识别具体催化剂,将在合理时间范围(12-24个月)内缩小价格和价值之间的差距。

便宜不够。你需要一个市场苏醒的理由。

6.2 催化剂分类

催化剂类型 描述 典型时间线
盈利拐点 下游后第一个盈利增长季度 1-3个季度
新管理层 具有turnaround记录的CEO任命 策略3-12个月,结果12-24个月
战略审查 宣布投资组合重组或专注 6-18个月
分拆/分拆上市 分离业务以解除企业集团折扣 从公告起6-12个月
并购活动 收购方法,无论是为公司还是由公司进行 变动
股票回购 公司以 depressed 价格回购股票 立即至12个月
监管解决方案 移除笼罩的调查或法律程序的结论 变动
行业整合 重新评级剩余独立玩家的部门并购浪潮 6-24个月
周期拐点 宏观或行业周期从低谷移动到恢复 6-18个月
内部人士买入 董事在公开市场价格大量买入 立即信号,6-12个月回报

6.3 催化剂信念分级

波顿隐含地将催化剂按概率和影响分级:

更高的信念催化剂允许波顿更积极地配置仓位。


7. 组合构建

7.1 多元化哲学

波顿运行高度多元化的组合120-150只股票,这将他与集中价值投资者区分开来。他的理由:

  1. 不确定性承认:即使最好的分析也有30-40%的时候错误
  2. 恢复投资固有风险:许多恢复候选失败;多元化确保赢家补偿输家
  3. 机会广度:大组合允许他同时参与多种类型的机会
  4. 流动性:较小仓位可以快速退出而无需市场影响
  5. 降低波动性:多元化平滑回报,这对客户保留重要

7.2 仓位配置

波顿使用分层仓位配置框架:

层级 仓位大小 持仓数量 标准
核心信念 基金的2-4% 10-15只 最高信念,多催化剂,强管理层
重要持仓 基金的1-2% 30-40只 好信念,清除催化剂,坚实估值
标准持仓 基金的0.5-1% 40-50只 中等信念,发展论点
起始/监控 基金的0.1-0.5% 30-50只 早期想法,建立理解

配置原则

7.3 换手率和持有期

波顿有相对较高的换手率对于基本面投资者:

高换手率的原因:

7.4 板块配置

波顿不做大板块赌注,但允许由自下而上选股驱动的有意义的超/欠配:

7.5 市值分布

波顿的优势最强在中小盘

中小盘超配是故意的——这些股票分析师覆盖较少、信息不对称更大、重估空间更大。


8. 风险管理

8.1 风险哲学

波顿将风险视为波动性而非永久资本损失的概率。他的风险管理是结构性的而非公式驱动的。

8.2 组合级风险控制

  1. 多元化:120-150个持仓确保没有单一失败能实质性损害基金
  2. 仓位大小限制:没有单一股票高于5%,前10持仓低于基金的25%
  3. 板块限制:没有板块高于基准权重的2倍
  4. 流动性管理:保持在一周内清算50%基金的能力
  5. 现金缓冲:很少持有超过5%现金;更喜欢全投资但在不确定时期持有较低风险仓位

8.3 股票级风险控制

  1. 资产负债表分析:避免相对于现金流稳定性过度杠杆化的公司
    • 净债务/EBITDA高于3倍是警告信号
    • 净债务/EBITDA高于4倍通常否定,除非有非常具体的催化剂存在
  2. 盈利质量检查:验证报告盈利是否转化为现金流
  3. 欺诈指标:关注关联交易、频繁审计师变更、激进会计
  4. 止损纪律:虽然波顿不使用机械止损,但他有心理框架:
    • 如果股票下跌20-30%且论点未变,他会增持
    • 如果股票下跌20-30%且论点受损,他会卖出
    • 如果股票下跌50%+,论点几乎肯定受损——卖出并从头重新评估

8.4 "如果我错了怎么办?"测试

在每个主要持仓前,波顿问:

8.5 回撤管理

波顿在1987年崩盘、1990年衰退、2000-2003年熊市和2007-2008年金融危机期间经历重大回撤。他的方法:


9. 卖空

9.1 波顿的卖空框架

波顿将空头仓位作为他有工具包的有限但有价值的部分,特别是在基金获得使用衍生品能力的后期年份。

9.2 空头持仓标准

波顿会在识别以下情况时卖空:

  1. 高估:股票以极端倍数交易且无正当理由
  2. 基本面恶化:盈利已达峰值,结构性下跌来临
  3. 会计担忧:激进的收入确认、不可持续的利润率、资产负债表外负债
  4. 商业模式崩溃:行业颠覆使公司产品/服务过时
  5. 管理层卖出:内部人士显著减少持股

9.3 卖空规则

9.4 卖空教训

波顿学到了几个艰难教训:


10. 板块分析与宏观意识

10.1 自下而上与宏观叠加

波顿主要是自下而上选股员但保持可能影响持仓的宏观条件意识。

10.2 监控的宏观因素

10.3 板块特定框架

金融(银行、保险)

消费可选(零售、媒体、休闲)

工业(工程、建筑、服务)

科技

10.4 板块轮动信号

虽然不是宏观交易者,波顿注意到经济周期中板块轮动往往遵循可预测模式:

  1. 早期复苏:金融、消费可选、小盘领先
  2. 中期周期:工业、科技、中盘领先
  3. 晚期周期:能源、材料、防守板块领先
  4. 衰退:现金、政府债券、公用事业领先

波顿使用这个意识来将他的恢复导向选股倾斜到最有可能从下一周期阶段受益的板块。


11. 行为纪律

11.1 情绪管理

波顿将情绪控制识别为区分好的分析师和伟大投资者的差异化因素。他的规则:

  1. 将分析与情绪分离:在你平静时完成分析;不要在市场波动火热时改变论点
  2. 保持决策日志:记录为什么买入和什么会让你卖出——当情绪高涨时参考
  3. 接受不确定性:没有投资是确定的;目标是比错误更频繁地正确,并按信念配置仓位
  4. 避免锚定:不要锚定你的购买价格——市场不关心你付了什么
  5. 接受不适:最好的逆向投资在购买时感觉不舒服——那是重点

11.2 波顿防范的认知偏见

偏见 描述 波顿对策
确认偏见 寻找支持你观点的信息 故意寻找每个持仓的空头情况
锚定 执着于购买价格或历史高点 基于当前基本面而非历史估值股票
损失厌恶 持有输家太久以避免实现损失 买入前设定明确的卖出标准
过度自信 基于虚假确定性配置过大仓位 广泛多元化;上限最大仓位大小
近因偏见 高估近期事件 研究长期周期;记住均值回归在年而非周内运作
从众 跟随其他基金经理进入热门名称 保持独立研究过程;对共识持怀疑态度
沉没成本谬误 仅因为价格更低而非论点加强而向下摊平 从头重新评估——你会今天以这个价格买这只股票吗?

11.3 重新评估纪律

波顿定期对每个持仓执行"干净纸"审查:

11.4 处理错误

波顿承认犯了很多错误并将它们视为不可避免。他的方法:


12. 常见错误与陷阱

12.1 波顿犯的错误

波顿对自己的错误异常坦诚:

  1. 爱上股票:因对成功想法的情感依恋而持有太久
  2. 接飞刀:太早买入恢复 situations,在基本面低谷之前
  3. 忽视资产负债表风险:偶尔低估信贷紧缩时过度杠杆化公司的风险
  4. 太信任管理层:被讲故事比执行更好的魅力CEO欺骗
  5. 不在公允价值时卖出:持有"最后10%"的上行,看着收益蒸发
  6. 没有新信息时向下摊平:纯粹因为价格更低而增持输家,而非因为论点加强

12.2 他看到别人犯的错误

  1. 指数拟合:构建密切跟踪基准的组合,保证平庸
  2. 配置近因偏见:堆积去年表现最好的板块
  3. 忽视估值而偏向质量:为"伟大"公司支付任何价格
  4. 过度交易:对每个新闻标题反应而非等待有意义的信息
  5. 忽视卖出纪律:90%的时间花在买入决策上,10%在卖出决策上(应该更平衡)
  6. 将牛市与技能混淆:将回报归因于选股而实际是 beta 敞口

12.3 价值陷阱检查清单

波顿开发了一个非正式检查清单以避免价值陷阱:

如果三个或更多框被勾选,无论股票看起来多便宜,都可能是价值陷阱。


13. 投资生命周期示例

13.1 综合波顿风格投资

以下示例综合了波顿描述的方法到一个单一说明性案例:

第1阶段:识别(第0月)

一只中型英国工业公司("IndustrialCo")出现在波顿的筛选中:

第2阶段:初步研究(第0-1月)

波顿阅读年报并注意到:

第3阶段:公司会议(第1-2月)

波顿会见新CEO并发现:

第4阶段:估值(第2月)

波顿构建估值范围:

第5阶段:初步购买(第2月)

波顿买入0.5%仓位(起始仓位)——足够小以在价格进一步下跌时增持。

第6阶段:催化剂发展(第4-8月)

波顿增持仓位,增加至1.5%。

第7阶段:重估开始(第8-16月)

第8阶段:获利了结(第16-20月)

第9阶段:退出(第20-24月)


14. 实施伪代码

14.1 逆向筛选器

class BoltonContrarianScreener:
    """
    使用安东尼·波顿的多因素方法筛选潜在逆向投资机会。
    """

    # 可配置阈值
    PRICE_DECLINE_MIN = -0.30          # 至少离高点30%
    PE_NORMALIZED_MAX = 12.0            # 低正常化P/E
    EV_EBITDA_MAX = 8.0                 # 低EV/EBITDA
    FCF_YIELD_MIN = 0.06               # 最低6%自由现金流收益率
    DIVIDEND_YIELD_MIN = 0.03          # 最低3%股息收益率
    NET_DEBT_EBITDA_MAX = 3.5          # 最大杠杆
    ANALYST_DOWNGRADE_MIN = 2          # 至少2次近期下调(逆向信号)
    INSIDER_BUY_LOOKBACK_DAYS = 90     # 检查过去90天内部人士买入

    def screen_universe(self, stocks):
        """
        第一轮定量筛选。
        返回按综合逆向分数排序的候选列表。
        """
        candidates = []

        for stock in stocks:
            score = 0
            flags = []

            # --- 价格下跌过滤器 ---
            price_decline = stock.price_change_from_52w_high()
            if price_decline < self.PRICE_DECLINE_MIN:
                score += 2
                flags.append("PRICE_DECLINE")

            # --- 估值过滤器 ---
            pe_norm = stock.normalized_pe()
            if pe_norm is not None and 0 < pe_norm < self.PE_NORMALIZED_MAX:
                score += 2
                flags.append("LOW_PE")

            ev_ebitda = stock.ev_to_ebitda()
            if ev_ebitda is not None and 0 < ev_ebitda < self.EV_EBITDA_MAX:
                score += 2
                flags.append("LOW_EV_EBITDA")

            fcf_yield = stock.free_cash_flow_yield()
            if fcf_yield is not None and fcf_yield > self.FCF_YIELD_MIN:
                score += 1
                flags.append("HIGH_FCF_YIELD")

            div_yield = stock.dividend_yield()
            if div_yield is not None and div_yield > self.DIVIDEND_YIELD_MIN:
                score += 1
                flags.append("HIGH_DIVIDEND")

            # --- 资产负债表安全检查 ---
            net_debt_ebitda = stock.net_debt_to_ebitda()
            if net_debt_ebitda is not None and net_debt_ebitda > self.NET_DEBT_EBITDA_MAX:
                score -= 3  # 惩罚过度杠杆
                flags.append("HIGH_LEVERAGE_WARNING")

            # --- 逆向情绪信号 ---
            recent_downgrades = stock.analyst_downgrades_last_90_days()
            if recent_downgrades >= self.ANALYST_DOWNGRADE_MIN:
                score += 2  # 逆向:更多下调 = 更有趣
                flags.append("ANALYST_CAPITULATION")

            insider_buys = stock.insider_purchases_last_n_days(
                self.INSIDER_BUY_LOOKBACK_DAYS
            )
            if insider_buys > 0:
                score += 3  # 强信号
                flags.append("INSIDER_BUYING")

            # --- 忽视溢价 ---
            analyst_coverage = stock.number_of_analysts()
            if analyst_coverage is not None and analyst_coverage <= 3:
                score += 1
                flags.append("LOW_COVERAGE")

            # 需要最低分数才能通过筛选
            if score >= 5:
                candidates.append({
                    "ticker": stock.ticker,
                    "name": stock.name,
                    "market_cap": stock.market_cap,
                    "score": score,
                    "flags": flags,
                    "price_decline": price_decline,
                    "pe_normalized": pe_norm,
                    "ev_ebitda": ev_ebitda,
                    "fcf_yield": fcf_yield,
                    "net_debt_ebitda": net_debt_ebitda,
                })

        # 按综合分数降序排序
        candidates.sort(key=lambda x: x["score"], reverse=True)
        return candidates

    def classify_opportunity(self, candidate):
        """
        分类到波顿的三大支柱。
        """
        flags = candidate["flags"]

        if "PRICE_DECLINE" in flags and candidate["price_decline"] < -0.40:
            return "RECOVERY_SITUATION"
        elif "LOW_PE" in flags and candidate.get("earnings_growth_3yr", 0) > 0.15:
            return "UNDERVALUED_GROWTH"
        elif self._has_special_situation_trigger(candidate):
            return "SPECIAL_SITUATION"
        else:
            return "GENERAL_VALUE"

    def _has_special_situation_trigger(self, candidate):
        """
        检查特殊情况催化剂。
        """
        triggers = [
            candidate.get("pending_demerger", False),
            candidate.get("new_ceo_last_6_months", False),
            candidate.get("strategic_review_announced", False),
            candidate.get("activist_involved", False),
            candidate.get("takeover_rumor", False),
        ]
        return any(triggers)

14.2 催化剂跟踪器

class CatalystTracker:
    """
    跟踪和监控持仓催化剂。
    在催化剂实现或论点恶化时警报。
    """

    CATALYST_TYPES = [
        "EARNINGS_INFLECTION",
        "NEW_MANAGEMENT",
        "STRATEGIC_REVIEW",
        "DEMERGER_SPINOFF",
        "MA_ACTIVITY",
        "SHARE_BUYBACK",
        "REGULATORY_RESOLUTION",
        "INDUSTRY_CONSOLIDATION",
        "CYCLE_TURN",
        "INSIDER_BUYING",
    ]

    def __init__(self):
        self.holdings = {}  # ticker -> HoldingRecord

    def add_holding(self, ticker, entry_price, position_size_pct,
                    thesis, catalysts, fair_value_bear, fair_value_base,
                    fair_value_bull, max_loss_tolerance):
        """
        记录新持仓及其投资论点和催化剂。
        """
        self.holdings[ticker] = {
            "entry_price": entry_price,
            "entry_date": today(),
            "position_size_pct": position_size_pct,
            "thesis": thesis,
            "catalysts": catalysts,       # {type, description, expected_date, status}列表
            "fair_value_bear": fair_value_bear,
            "fair_value_base": fair_value_base,
            "fair_value_bull": fair_value_bull,
            "max_loss_tolerance": max_loss_tolerance,
            "status": "ACTIVE",
            "notes": [],
        }

    def daily_review(self, market_data):
        """
        每日检查所有持仓的催化剂触发和风险警报。
        """
        alerts = []

        for ticker, holding in self.holdings.items():
            current_price = market_data.get_price(ticker)
            pnl_pct = (current_price - holding["entry_price"]) / holding["entry_price"]

            # --- 检查是否达到公允价值(卖出信号) ---
            if current_price >= holding["fair_value_base"]:
                alerts.append({
                    "ticker": ticker,
                    "type": "FAIR_VALUE_REACHED",
                    "message": f"{ticker}处于基准情况公允价值。考虑削减。",
                    "priority": "HIGH",
                })

            # --- 检查是否超出容忍的损失 ---
            if pnl_pct < -holding["max_loss_tolerance"]:
                alerts.append({
                    "ticker": ticker,
                    "type": "LOSS_LIMIT_BREACH",
                    "message": f"{ticker}下跌{pnl_pct:.1%}。需要审查论点。",
                    "priority": "CRITICAL",
                })

            # --- 检查催化剂时间线 ---
            for catalyst in holding["catalysts"]:
                if catalyst["status"] == "PENDING":
                    if catalyst["expected_date"] < today():
                        alerts.append({
                            "ticker": ticker,
                            "type": "CATALYST_OVERDUE",
                            "message": f"{ticker}:'{catalyst['description']}'逾期。",
                            "priority": "MEDIUM",
                        })

            # --- 干净纸测试(每季度) ---
            days_held = (today() - holding["entry_date"]).days
            if days_held > 0 and days_held % 90 == 0:
                alerts.append({
                    "ticker": ticker,
                    "type": "CLEAN_SHEET_REVIEW",
                    "message": f"{ticker}:季度审查——你今天会买吗?",
                    "priority": "MEDIUM",
                })

        return sorted(alerts, key=lambda a: {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2}[a["priority"]])

    def update_catalyst_status(self, ticker, catalyst_index, new_status, note=""):
        """
        更新催化剂状态:PENDING, MATERIALIZED, FAILED, DELAYED。
        """
        holding = self.holdings[ticker]
        holding["catalysts"][catalyst_index]["status"] = new_status
        if note:
            holding["notes"].append({
                "date": today(),
                "note": note,
            })

        # 如果所有催化剂失败,标记审查
        active_catalysts = [c for c in holding["catalysts"] if c["status"] == "PENDING"]
        materialized = [c for c in holding["catalysts"] if c["status"] == "MATERIALIZED"]

        if len(active_catalysts) == 0 and len(materialized) == 0:
            holding["status"] = "REVIEW_FOR_EXIT"

    def position_sizer(self, conviction_score, opportunity_type):
        """
        基于信念和机会类型确定仓位大小。

        conviction_score: 1-10等级
        opportunity_type: RECOVERY | UNDERVALUED_GROWTH | SPECIAL_SITUATION
        """
        # 基于信念的基本大小
        if conviction_score >= 8:
            base_pct = 2.5   # 核心信念:2-4%
        elif conviction_score >= 6:
            base_pct = 1.25  # 重要:1-2%
        elif conviction_score >= 4:
            base_pct = 0.75  # 标准:0.5-1%
        else:
            base_pct = 0.3   # 起始:0.1-0.5%

        # 按机会类型调整
        type_multiplier = {
            "RECOVERY_SITUATION": 0.85,     # 稍小(更高风险)
            "UNDERVALUED_GROWTH": 1.0,      # 标准
            "SPECIAL_SITUATION": 1.1,       # 稍大(催化剂驱动)
        }
        multiplier = type_multiplier.get(opportunity_type, 1.0)

        final_pct = base_pct * multiplier

        # 硬性上限
        final_pct = min(final_pct, 4.0)  # 永不超过4%
        final_pct = max(final_pct, 0.1)  # 最低有意义仓位

        return round(final_pct, 2)

14.3 组合监控器

class BoltonPortfolioMonitor:
    """
    监控符合波顿方法的组合级约束。
    """

    MAX_POSITIONS = 150
    MIN_POSITIONS = 100
    MAX_SINGLE_POSITION = 0.05       # 5%
    MAX_TOP_10_WEIGHT = 0.35         # 35%
    MAX_SECTOR_OVERWEIGHT = 2.0      # 基准的2倍
    MAX_NET_DEBT_EBITDA_AVG = 2.5    # 组合平均杠杆
    MIN_SECTORS = 8

    def check_constraints(self, portfolio, benchmark):
        """
        验证符合波顿风格约束的组合。
        返回违规列表。
        """
        violations = []

        # 持仓数量
        n_positions = len(portfolio.positions)
        if n_positions > self.MAX_POSITIONS:
            violations.append(f"持仓过多:{n_positions} > {self.MAX_POSITIONS}")
        if n_positions < self.MIN_POSITIONS:
            violations.append(f"持仓过少:{n_positions} < {self.MIN_POSITIONS}")

        # 单一持仓限制
        for pos in portfolio.positions:
            if pos.weight > self.MAX_SINGLE_POSITION:
                violations.append(
                    f"{pos.ticker}权重{pos.weight:.1%}超过{self.MAX_SINGLE_POSITION:.0%}"
                )

        # 前10集中度
        top_10_weight = sum(
            p.weight for p in sorted(portfolio.positions,
                                     key=lambda x: x.weight, reverse=True)[:10]
        )
        if top_10_weight > self.MAX_TOP_10_WEIGHT:
            violations.append(
                f"前10集中度{top_10_weight:.1%}超过{self.MAX_TOP_10_WEIGHT:.0%}"
            )

        # 板块超配
        for sector in portfolio.sector_weights():
            bm_weight = benchmark.sector_weight(sector)
            if bm_weight > 0:
                ratio = portfolio.sector_weight(sector) / bm_weight
                if ratio > self.MAX_SECTOR_OVERWEIGHT:
                    violations.append(
                        f"板块{sector}:{ratio:.1f}倍基准(最大{self.MAX_SECTOR_OVERWEIGHT}倍)"
                    )

        # 板块多元化
        active_sectors = len([s for s in portfolio.sector_weights() if portfolio.sector_weight(s) > 0.01])
        if active_sectors < self.MIN_SECTORS:
            violations.append(f"仅{active_sectors}个板块(最少{self.MIN_SECTORS})")

        return violations

15. 关键语录

关于逆向主义

"最佳投资机会出现在共识错误时。但逆向不是为不同而不同——它是有做工作以知道共识何时错误的信念。"

"如果买一只股票感觉舒服,你可能已经太晚了。最好的买入是让你稍微紧张的。"

关于管理层

"我始终相信,公司管理层是决定投资是否成功的最重要因素。"

"会见管理层,但不要只听他们说的。看他们做的——特别是他们自己的钱。"

关于估值

"没有单一正确的方法来估值公司。我使用多种方法,寻找重复出现的答案。当几种不同方法指向相同结论时,我有更多信心。"

"便宜不等于好价值。股票仅在有理由被重估时才成为好价值。"

关于风险和错误

"投资的长期成功关键不是避免错误——而是快速识别它们并采取行动。"

"多元化是投资者的好朋友。我始终更喜欢在大量股票上分散赌注而非集中于少数。"

"每个投资者都会经历表现不佳的时期。重要的是你是否坚持你的过程还是在最坏时机放弃它。"

关于卖出

"卖出决策至少与买入决策一样重要,但大多数投资者在上面花费太少时间。"

"当股票达到我估计的公允价值时,我卖出。我不会试图挤出最后几个百分比的回报。"

关于心理学

"投资者最大的敌人不是市场——而是他自己。恐惧和贪婪比任何基本面因素驱动更多糟糕决策。"

"我记录我做出的每一个投资决策。回顾我的错误是痛苦的,但至关重要。"

关于过程

"投资是一门随着实践提高的手艺。28年后,我仍在学习。"

"我认识的最好的投资者好奇、谦逊、愿意在事实改变时改变主意。"


附录:博尔顿投资检查清单摘要

用于评估任何潜在博尔顿风格投资的可综合检查清单:

机会识别

基本面质量

管理层

催化剂

估值

风险


实施规范结束