笑傲股市——完整实施规范

基于威廉·奥尼尔 (William J. O'Neil),《笑傲股市》(第四版,2009年)


目录

  1. 概述
  2. CAN SLIM系统——完整细节
  3. 图表基底形态——完整目录
  4. 基底计数与阶段概念
  5. 正确买入点与买入区
  6. 成交量要求
  7. 卖出规则——防御
  8. 卖出规则——进攻
  9. 市场方向:M因素
  10. 行业组强度
  11. 机构持仓分析
  12. 模型手册方法
  13. 常见错误
  14. 完整交易生命周期示例
  15. 实施伪代码
  16. 关键语录

1. 概述

1.1 权威CAN SLIM参考

《笑傲股市》是威廉·奥尼尔CAN SLIM系统的综合参考。现在第四版(2009年),该书结合了超过125年的市场研究——每一只在上涨前录得翻倍或以上涨幅的股票都被编目和分析。第四版新增:

1.2 研究基础

奥尼尔的方法论完全基于实证。他不是从应该有效的假设开始。他从结果开始——真正产生最大收益的股票——然后逆向工作,识别它们在上涨之前有什么共同特征。样本涵盖了1880年代到2008年的每个市场周期:

研究方法:
1. 识别每个周期中翻倍或更多的股票。
2. 编目基本面:盈利增长、销售增长、利润率、ROE、新产品。
3. 编目技术面:突破前的价格形态、成交量、相对强度。
4. 编目市场条件:突破时的 general market 趋势。
5. 编目机构活动:买入的基金数量、 sponsor 质量。
6. 综合成一个可重复的、基于规则的系统。

结果是CAN SLIM——获胜股票在重大价格上涨前共有的七个特征。每个字母代表一个可衡量的标准。

1.3 核心原则

1. 正确买入,坚定持有   —— 入场点决定一切。在错误时间或价格买入好股票会亏钱。

2. 历史重演            —— 人性不变。1910年代主要上涨之前的相同形态今天依然重演。

3. 所有损失在7-8%处切断 —— 不可协商。无例外。无希望。不向下摊平。

4. 市场方向第一        —— 四分之三的股票跟随 general market 方向。
                         你必须与市场的主要趋势同步。

5. 两者结合使用        —— CAN SLIM结合基本面强度(C、A、N、S)与
   基本面和技术面        技术时机(L、I、M)。单独使用任何一个都不够。

2. CAN SLIM系统——完整细节

CAN SLIM的每个字母代表一个标准。所有七个应在理想买入候选中同时存在。奥尼尔在整本书中明确给出具体数值阈值。

2.1 C——当前季度每股收益

最重要的单一基本面标准。 奥尼尔的研究表明,在样本中最佳表现股票中,有75%在重大价格上涨之前的最近一个季度显示每股收益增长至少70%。

要求:
- 当前季度每股收益同比增长 >= 25%(绝对最小值)。
- 首选40-50%或更高。最佳股票显示100-500%+增长。
- 增长必须来自持续运营,不是一次性事件(资产出售、税收优惠)。
- 盈利质量重要:确认销售也在增长(至少25%)。
- 如果最近一个季度比前几个季度减速,要谨慎。
  示例:Q1 +100%、Q2 +80%、Q3 +50% = 减速,即使仍然强劲。
- 与上年同期(同比)比较,而非环比。
- 关注"共识击败"——股票应击败分析师预期,理想情况下大幅超越。

红旗:
- 盈利增长仅由成本削减驱动,而非收入增长。
- 一次性收益膨胀每股收益。
- 盈利增长但收入持平或下降。
- 公司持续降低指引然后"击败"降低的预期。

2.2 A——年度盈利增长

最佳股票显示过去3-5年年度盈利增长模式。

要求:
- 过去3年每年每股收益增长25%或以上。
- 首选加速模式:例如 +25%、+30%、+40%。
- 年化股本回报率(ROE)>= 17%。最佳显示25-50%+。
- 寻找年度和季度数字之间的"共识":
  强劲年度趋势 + 强劲当前季度 = 最佳候选。
- 如果公司在过去5年中有一年"下降",下一年的盈利应该
  恢复到新高,显示韧性。

IBD指标——EPS评分:
- IBD的EPS评分(1-99)将当前和年度盈利增长合并为单一分数。
- 目标EPS评分 >= 80,最好 >= 85。
- EPS评分80意味着公司的盈利记录优于所有上市公司的80%。

2.3 N——新产品、新管理、新高

"N"因素是催化剂。 奥尼尔发现95%的最大赢家股票有真正的新事物推动其上涨。

"新"的类型:
1. 新产品或服务——创造新市场或主导现有市场的突破性产品。
   书中的例子:苹果的iPod/iPhone、谷歌的搜索广告、思科的路由器、微软的Windows。

2. 新管理——由有新愿景的新领导层带领的扭转。新团队下基本面已显示改善。

3. 新行业条件——监管变化、消费行为转变、创造全组机会的新技术平台。

4. 新价格高点——这是反直觉但关键的。创52周新高的股票往往走高。
   创52周新低的股票往往走低。奥尼尔的研究强调:
   "看起来太高的往往走高,看起来太低的往往走低。"

关键原则:
- 不要买"便宜"或"跌透"的股票。正确买入时机是股票从适当基底形态
  突破到新高时,而不是在下跌中看起来像便宜货时。

2.4 S——供给与需求

供求定律支配股价。 流通股越少意味着供给越少,这意味着需求增加时价格变动更大。

寻找:
- 流通股数合理的公司。奥尼尔历史上偏好少于5亿股的公司。
- 突破日大成交量:股票从基底突破当天,成交量应比其50日平均成交量
  高出至少40-50%。这确认机构需求。
- 成交量在基底形成期间应"枯竭"(安静积累),然后在突破日"飙升"
  (机构承诺资本)。
- 股票回购计划是积极的——减少供给。
- 避免巨大流通股(数十亿股)的股票,除非显示异常重的机构积累。

成交量解读:
- 价格涨,成交量大 = 需求(看涨)。
- 价格跌,成交量大 = 供给/派发(看跌)。
- 价格涨,成交量小 = 无信心(中性至谨慎)。
- 价格跌,成交量小 = 正常回调,不令人担忧。

2.5 L——领导者或落后者

买入行业组中第一或第二的公司。永远不买落后者。

要求:
- IBD相对强度(RS)评分 >= 80,最好 >= 85或90。
- RS评分将股票过去12个月的价格表现与所有其他股票排名。
  评分90意味着股票跑赢了90%的所有股票。
- 奥尼尔的研究:最佳表现股票在突破时的平均RS评分为87。

规则:
- 永远不买RS评分低于70的股票。句号。
- 在行业内,买第一的股票——盈利最好、RS评分最高、图表形态最佳的。
  不要因为同一组中某只"更便宜"就买它,指望随涨。
- 如果你持有一只股票而其RS评分下降,而同组竞争对手RS评分上升,
  考虑换到领导者。
- 相对强度线(不仅是评分)应在股票价格突破时处于或接近新高。
  如果RS线滞后,突破质量较低。

2.6 I——机构持仓

你想要被最佳机构投资者买入的股票——不仅是任何基金。

要求:
- 至少一些机构 sponsor(共同基金、养老基金等)。
- 关注持仓质量:在长期记录中表现优异的顶级基金。
- 机构持有人的数量应在最近几个季度增加。
  上季度400个持有人,本季度420个,比500个持有人缩小至480个更好。
- 趋势:机构兴趣增加 = 积累。
  机构兴趣减少 = 派发/卖出。

IBD指标:
- 积累/派发评分:A或B = 机构积累(买入)。
  C = 中性。D或E = 机构派发(卖出)。
- 持仓评分:衡量机构持仓的质量和趋势。
- 目标:A/D评分A或B。持仓人数环比增加。

警告信号:
- 股票"过度持有"——当每个大型基金都已经持有它时,没有新买家剩余。
  这通常发生在长期上涨后的第三或第四阶段基底。
- 关注顶级基金卖出。如果最佳表现基金经理正在减仓,密切关注。

2.7 M——市场方向

这是最重要的因素。 四分之三的股票跟随一般市场方向。即使是最好的CAN SLIM股票在熊市中也会失败。详见第9节。

摘要:
- 你必须确定市场是处于确认上升趋势、压力下的上升趋势,还是市场调整。
- 仅在确认上升趋势时买入股票。
- 当上升趋势受到压力时减少敞口,停止买入。
- 当市场处于调整时转向现金和保护收益。
- 确定市场方向的工具:跟进日(确认新上升趋势)和分配日计数(识别顶部市场)。

3. 图表基底形态——完整目录

"基底"是整合形态——在先前上涨之后发生的修正和横向交易期间。基底代表股票消化收益、弱持有者卖出、强劲机构吸纳的时期。当股票在大量成交下从基底向上突破时,上涨恢复。

奥尼尔识别了七种主要基底形态。每种都有具体的识别规则。

3.1 杯柄形态

最常见和最可靠的形态。 因其从侧面看像咖啡杯而命名。

结构:
- 持续时间:最短7周(可持续6-65周;大多3-6个月)。
- 深度:从峰值到谷底修正12-33%。熊市中可达40-50%。
  深于50%的为有缺陷——股票已损坏太严重。
- 左侧:价格从先前高点在成交量增加时下跌。这是"卖出"阶段。
- 底部:成交量枯竭。价格找到支撑并开始圆形向上。底部应相对平滑
  和"U形",不是尖锐的V底(V底容易失败)。
- 右侧:价格向先前高点回升。成交量通常减少
  形成右侧,显示安静积累。
- 柄:从右侧峰值小幅回调1-4周。柄应:
  * 向下倾斜(不是向上——向上柄是楔形形态,看跌)。
  * 从柄高到低修正不超过10-15%。
  * 在整体基底的上半部分形成(柄位太低意味着股票
    无法充分恢复——疲软)。
  * 显示成交量减少至低于平均水平(最后弱持有者被震出)。
- 买入点:柄的高点 + $0.10。这被称为"支点"。

理想特征:
- 基底开始前至少30%的先前上升趋势。
- 柄中价格走势紧密(日范围小)。
- 当股票接近买入点时相对强度线处于或接近新高。
- 突破日成交量比平均高50%+。

3.2 无柄杯形态

与杯柄形态相同,但股票直接突破,不形成柄。

结构:
- 深度、持续时间和形状与杯柄形态相同。
- 没有柄形成——价格直接越过左侧高点。
- 买入点:杯的左侧高点(先前高点)+ $0.10。

注意:
- 通常被认为比杯柄形态略不可靠,因为柄有助于震出最后弱持有者。
  没有它,可能有更多上方供给。
- 在强劲趋势市场中仍然是有效形态。

3.3 双底形态

"W"形形态,股票在上涨前测试其低点两次。

结构:
- 持续时间:最短7周。
- 深度:与杯相似12-33%,熊市中可达40-50%。
- 第一腿向下:价格从先前高点下跌到低点。
- 反弹:价格部分反弹(不需要到达先前高点)。
- 第二腿向下:价格再次下跌。第二低点应低于第一低点——
  这是关键。第二低点的下穿震出在先前低点设置止损的弱持有者。
  这种"震出"使形态有效。
- 恢复:价格从第二低点反弹。
- 买入点:W中间峰值(两低点之间反弹的高点)+ $0.10。

关键规则:
- 第二底部必须下穿第一底部,即使只有几分钱。
  如果没有,这不是正确的双底——可能是平底或不同形态。
- 右侧也可能形成柄,创建修改形态。柄规则与杯柄形态相同。

3.4 平底形态

显示非常小修正的紧密横向整合。

结构:
- 持续时间:最短5周。
- 深度:从高到低修正不超过10-15%。
- 股票在窄范围内横向移动。这通常发生在从先前基底
  (杯、双底)突破后——它是现有趋势中的"连续"形态。
- 买入点:平底区间的高点 + $0.10。

意义:
- 平底显示极大强度——即使市场可能回落,股票拒绝大幅修正。
- 它们通常作为较长上涨中的第二或第三阶段基底。
- 因为修正如此之小,买入点接近当前价格,意味着
  7-8%止损很紧,风险定义明确。

3.5 高紧旗形

最稀有和最强大的形态。 奥尼尔称其为可在最短时间内产生最大收益的形态。

结构:
- 先前上涨:股票必须在非常短的时期内上涨100-120%或更多
  (通常4-8周)。爆炸性移动是"旗杆"。
- 整合:股票然后在紧密、横向至略向下模式中修正10-25%,
  持续3-5周。这是"旗"。
- 买入点:旗部分的高点 + $0.10。

关键特征:
- 这种形态非常罕见——仅在最 exceptional 股票和最强劲市场上涨中发生。
- 数周内100%+的涨幅显示非凡需求。
- 尽管如此大的涨幅,浅修正(10-25%)表明持有者不卖出——
  他们相信股票的未来,拒绝获利。
- 奥尼尔的例子:1999年的高通、2004年的谷歌。

警告:
- 因为股票已经翻倍,许多投资者觉得它"太高了。"
  这正是奥尼尔警告的那种思维方式。好股票经常翻倍然后再翻倍。

3.6 上升基底

三个回调系列,每个都有更高低点,阶梯式向上。

结构:
- 持续时间:通常9-16周。
- 股票进行三次大约10-20%的回调。
- 每个回调低点高于先前回调低点。
- 形态"上升"——从左到右向上倾斜。
- 买入点:第三回调恢复的高点 + $0.10。

背景:
- 上升基底通常在 general market 处于修正或压力下形成。
  股票足够强劲,即使市场回落也保持创造更高低点——
  特殊机构支持的信号。
- 如果股票能在其他都在下跌时保持和上升,当市场确认新上升趋势时,
  它往往会是首批强劲突破的股票之一。

3.7 碟形带柄

杯柄形态的更长、更 gradual 版本。

结构:
- 持续时间:通常比杯长——经常3-6个月或更长,有时更长。
- 深度:可以是浅(12-20%)到中等(20-33%)。
- "碟"是宽、慢、圆形的底部——曲线比杯更 gradual。
- 右侧形成柄,遵循与杯柄形态相同的规则。
- 买入点:柄的高点 + $0.10。

特征:
- 碟形基底往往在较大市值、更多机构的股票中形成,需要更长时间积累。
- 缓慢、gentle 的圆形显示大型基金在延长时期内的耐心、持续积累。
- 不如杯形态波动,但突破可能同样强劲。

3.8 基底叠基底

不是独立的基底类型,而是一个重要的结构性概念。

描述:
- 当股票形成基底、突破、上涨10-20%但无法在回落到新基底前实现完整25%+涨幅时。
- 第二个基底部分或完全形成于先前基底上方。
- 这经常发生在 general market 疲软时——股票试图上涨但市场拖累它。
  股票强度由其拒绝完全回落至或低于先前基底来显示。
- 从第二个(上部)基底突破是买入点。
- 基底计数不推进——基底叠基底与下方基底计为同一阶段。

4. 基底计数与阶段概念

4.1 为什么基底计数重要

奥尼尔的研究表明,成功突破的概率随每个连续基底下降。 第一和第二基底概率最高。第三基底可接受但需要更大谨慎。第四基底及以上经常失败。

基底计数规则:

第一基底:从长期下跌或长期不活跃后形成。这是股票从"第一阶段"底部阶段出现。最高概率。

第二基底:在第一基底成功突破和上涨后形成。股票修正、建立新基底、再次突破。高概率。

第三基底:股票现在已有两次成功突破和上涨。它再次修正。第三基底可接受但要更苛刻——要求更好的基本面、更紧密形态、更重成交量。

第四基底:显著更高失败率。到此阶段,股票上涨已"成熟"并被广泛认知。晚期基底是机构开始向散户派发(卖出)的地方。避免或极其谨慎。

第五+基底:非常高失败率。股票几乎肯定处于晚期顶部形态。不要买入。

4.2 如何重置基底计数

基底计数在以下条件下重置为1:

1. 股票下跌足以低于先前基底低点。这是一种"基底失败"——
   股票必须从头重建。下一个适当基底成为新的第一基底。

2. 股票经历熊市下跌(通常从峰值下跌50%+)然后最终形成新基底。
   基底计数重置。

3. 非常长期的整合(多年)基本上"重置"股票的形态。

基底计数在以下情况下不重置:
- 股票形成基底叠基底(与下方基底相同计数)。
- 股票只是有未低于任何先前基底低点的浅回调。

4.3 阶段分析连接

奥尼尔的基底计数与斯坦·温斯坦的阶段分析概念一致:

第一阶段:筑底/积累——股票在下跌后横盘。聪明钱积累。
第二阶段:上涨——股票趋势向上,形成和突破基底。
第三阶段:筑顶/派发——晚期基底。机构向散户卖出。
第四阶段:下跌——下降趋势。不要买入。

5. 正确买入点与买入区

5.1 支点

支点(也称为买入点)是股票从适当形成的基底形态突破的确切价格。计算公式为:

支点 = 基底形态柄的高点(或无柄时的基底顶部)
        + $0.10

每种形态:
- 杯柄形态:     柄的高点 + $0.10
- 无柄杯:        杯左侧高点 + $0.10
- 双底:          W中间峰值 + $0.10
- 平底:          平底区间高点 + $0.10
- 高紧旗:        旗部分高点 + $0.10
- 上升基底:       第三回调恢复高点 + $0.10
- 碟形带柄:      柄的高点 + $0.10

5.2 5%买入区

买入区规则:
- 你可以从支点起最多买入股票至支点上方5%。
- 永远不要在支点超过5%以上追涨。如果错过突破,等待下一个适当基底
  或回调至10周均线。

示例:
  支点 = $50.10
  最大买入价 = $50.10 × 1.05 = $52.61
  如果股票在$53.00,你错过了。不要追。

为什么5%?
- 如果在支点买入且股票失败,最大损失与7-8%止损约为7-8%。
  如果在支点上方5%买入且失败,损失可能为12-13%——太多。
  5%限制保持风险可管理。

5.3 替代买入点

回调至10周均线:
- 在成功突破后,股票可能回调至其10周(50日)均线,
  在低于平均成交量下然后反弹。
- 这是加仓或如果你错过突破则开仓的次级买入点。
- 回调日成交量应枯竭,反弹日成交量增加。
- 第一和第二回调至10周线最可靠。第三次及以后的回调成功率较低。

三周紧缩:
- 如果股票连续三周收盘价与前一周收盘价相差约1-1.5%以内,
  它形成"三周紧缩"形态。
- 这显示非凡持有信心——没人卖出。
- 买入点:三周紧缩区的高点 + $0.10。
- 这是连续形态,用于加仓现有持仓。

6. 成交量要求

成交量是市场的X光。它揭示是否机构——实际推动股价的实体——在买入还是卖出。

6.1 突破日

最小值:突破日成交量应至少比股票50日平均日成交量高40-50%。

理想:比平均高100%或更多——机构需求 decisive、 unambiguous 的展示。

计算:
  50日平均成交量 = 1,000,000股
  最小突破成交量 = 1,400,000 - 1,500,000股
  理想突破成交量 = 2,000,000+股

如果成交量低于平均40%以上:
- 突破可疑。可能缺乏机构支持。
- 如果买入,使用更严格止损。
- 如果成交量在突破后几天内没有增加,考虑卖出。

6.2 基底形成期间

健康基底成交量形态:
- 成交量应在基底形成期间通常减少。这被称为"成交量枯竭"。
- 成交量减少意味着卖出压力正在耗尽——弱持有者已卖出完毕,
  股票正在被quietly 积累。
- 基底内下跌日成交量大是负面的——显示激进派发。
- 基底内下跌日成交量小而上涨日成交量略大 = 理想。

6.3 突破后

- 成交量应在突破后数天至数周保持高于平均。这确认持续机构买入,
  而非仅仅一日事件。
- 高位的"成交量翻腾"(成交量非常大但价格无进展)是机构派发的警告信号——
  大玩家正在卖出。

7. 卖出规则——防御

7-8%损失削减规则是奥尼尔最重要的规则。 他在卖出纪律上花的篇幅比任何其他主题都多,因为这是大多数投资者失败的地方。

7.1 7-8%止损

规则:如果股票从你的买入价下跌7-8%,立即卖出。无例外。

示例:
  买入价 = $50.00
  7%止损 = $50.00 × 0.93 = $46.50
  8%止损 = $50.00 × 0.92 = $46.00
  如果股票达到$46.00-$46.50,当天卖出。

为什么7-8%?
- 奥尼尔的研究表明,在正确买入点从正确基底形态买入的股票,
  几乎从不在下跌7-8%后成为大赢家。从适当支点如此大跌幅
  几乎总是意味着形态失败。
- 如果你在适当支点以适当成交量买入,股票应几乎立即朝你有
  利移动。如果反转并达到-7-8%,形态已失败。

关键规则:
- 止损从你的买入价衡量,而非从支点。
- 永远不要向下摊平。不要在股票跌至买点以下时买入更多。
- 永远不要在设定后降低止损。只有在股票上涨后将止损升高
  (或在股票上涨后将止损转为保护利润)。
- 不要将止损恰好设在-7%或-8%然后告诉自己"再等一天。"
  线是绝对的。

7.2 按特征变化卖出

卖出如果:
- 股票在大量成交下跌破其50日(10周)均线且在1-2天内无法收复。
- 股票在数月最大成交量下突然、急剧价格下跌。
- 股票在盈利或其他新闻下跳空低开。在开盘或第一次反弹卖出。
  不要持有和希望。
- 股票下穿先前基底低点(基底失败)。

7.3 "往返"规则

规则:如果股票给你10-15%或以上收益然后完全回转至你的买入价,卖出。
不要让可观收益变成亏损。

这是与7-8%止损分开的规则。它解决看着利润蒸发的心理困难。
奥尼尔说这是最痛苦和常见的错误之一:股票上涨15%,
投资者不卖,然后它回落至持平,投资者持有因为他们"不想承受损失"——
然后它进一步下跌。

8. 卖出规则——进攻

8.1 20-25%利润目标

规则:一旦股票从适当买入点上涨20-25%,至少取部分利润——
除非股票在突破后1-3周内达到该收益。

理由:
- 大多数股票在20-25%上涨后修正。如果你锁定收益,你有现金为下次机会做准备。
- 长期来看,一系列20-25%收益与7-8%损失的组合产生出色结果。
  数学:三次20%收益 vs 一次7%损失 = 赢家周期净+53%收益。

8周持有规则(20-25%规则的例外):
- 如果股票在突破后前1-3周内从买入点上涨20%+,不要卖。
  至少持有8周从突破日期起。
- 在不到3周内上涨20%的股票具有巨大动量。这些可能是"大领袖"——
  可能翻倍或三倍的股票。在这些股票上快速获取20%利润
  是把改变人生的收益留在桌面上。
- 8周持有期后,重新评估。如果股票表现仍然良好
  (保持在10周线上方、强劲RS、强劲基本面),继续持有。

8.2 高潮顶部信号(耗尽卖出)

当你持有的股票开始显示高潮顶部信号时,是卖出全部仓位的时候了。这些信号标记上涨的最后、 euphoric 冲刺阶段。

高潮顶部信号:
1. 最大单日涨幅:在上涨数周或数月後,股票突然有自突破以来最大单日价格上涨。
   这是"耗尽缺口"或 blow-off 走势。股票看起来要直冲云霄——
   正是聪明钱正在卸货的时刻。

2. 耗尽缺口:股票在非常大量成交下在开盘跳空高开,通常在新闻或盈利报告上。
   它可能当天收盘接近高点。这种在长期上涨后的"高潮缺口"是卖出信号。

3. 宽幅震荡:在数月紧密、受控上涨后,股票开始有宽得多的周价格范围。
   "价差"在周高和周低之间变得大得多。这显示顶部波动性增加。

4. 铁路轨道/翻腾:成交量非常大但数天或数周内价格无进展。
   这是"派发"——机构正在卖出大量股票,但新买家(暂时)正在吸收,
   保持价格持平。最终买家筋疲力尽,股票崩盘。

5. 通道线加速:如果你围绕股票的上涨画一个趋势通道,
   而股票在大量成交下突然突破上方通道线,这往往是blow-off。
   反直觉地,突破通道上方是卖出信号。

6. 200日均线距离:如果股票在200日均线上方70-100%+交易,
   它 extremely extended 并容易急剧修正。

8.3 渐进仓位管理

大赢家持有规则:
1. 8周持有期后,使用10周均线作为你的指导。
   - 只要股票收盘在10周线上方(或回调至线并反弹
     在成交量上),继续持有。
   - 如果它在大量成交下收盘在线下方并保持2+周,
     卖出至少部分仓位。

2. 随着收益累积(50%、100%、200%+),逐步收紧卖出信号:
   - 寻找高潮顶部信号。
   - 关注晚期基底失败(第三、第四基底突破失败)。
   - 监控盈利减速(季度每股收益增长放缓)。

3. 当你有大收益时锁定。当100%收益是罕见和宝贵的。200%收益是 extraordinary。
   不要回吐大收益。

9. 市场方向:M因素

9.1 为什么市场方向最重要

三个事实:
1. 四分之三的股票跟随一般市场方向。
2. 你不能忽视市场并孤立交易个股。
3. 每个熊市开始时基本面看起来仍然很好。你必须使用价格和成交量
   行为在实际下跌明显之前检测派发。

9.2 跟进日(确认新上升趋势)

跟进日是市场调整可能结束和新上升趋势正在开始的信号。没有跟进日,你不开始买入股票。

跟进日规则:
1. 先决条件:市场必须首先尝试反弹。这由主要指数
   (标准普尔500、纳斯达克综合指数)在一天收盘更高来识别。
   这一天是尝试反弹的"第一天"。第一天低点(或调整低点,
   以较低者为准)在后续日子里不能被下穿。如果被下穿,
   尝试反弹失败,你用下一次尝试反弹重新计数。

2. 时机:跟进日可能发生在尝试反弹的第4天或之后。
   跟进日在第4-7天最常见。第1-3天太早,不算数。
   第10天+后的跟进日仍可能工作,但成功率较低。

3. 信号:在第4天或之后,主要指数必须在成交量高于前一天
   的情况下以显著涨幅上涨(通常1.5%或以上,
   奥尼尔不给 rigid 数字——他说涨幅应"明显强劲")。

4. 确认:一个跟进日足以将状态从"市场调整"转为"确认上升趋势"——
   但你应逐渐开始买入,不要一次全部。
   从一两笔仓位开始,仅在它们有效时才增加。

重要注意事项:
- 不是每个跟进日都导致持续的上升趋势。大约25%失败。
  这可以接受,因为假信号成本小(你买入1-2只股票并以-7-8%止损),
  而错过真正的上升趋势成本巨大。
- 从未有没有跟进日就开始的显著牛市。它是必要条件,
  即使不是充分条件。

9.3 分配日计数(识别市场顶部)

分配日是检测市场上升趋势何时结束的主要工具。

分配日定义:
- 主要指数(标准普尔500或纳斯达克)在成交量高于前一天的情况下
  下跌0.2%或以上。
- 这表示机构卖出(派发)——大型基金正在清算头寸,
  更重的成交量揭示了它。

计数规则:
- 从确认上升趋势的跟进日开始计数分配日。
- 分配日在25个交易日后过期(约5周)。26个或更多交易日前
  发生的分配日从计数中移除。
- 如果指数在分配日收盘上方足够远处上涨(通常5%+),
  该日的卖出变得无关,也被移除。

警告阈值:
- 在标准普尔500或纳斯达克的25天窗口内有4-5个分配日 =
  市场上升趋势"承压"。谨慎。停止买入,收紧止损。
- 6+个分配日 = 市场很可能正在筑顶的高概率。转向"市场调整"状态。
  卖出弱持仓。提高现金。
- 分配日 clustering(在1-2周内多个)是特别危险的——
  表明紧急、激进的机构卖出。

停滞日:
- 停滞日是一种分配形式,指数收盘上涨但在成交量更大的情况下
  处于日内范围的较低部分。指数试图上涨但卖家出现并压制涨幅。
- 停滞日计入分配日计数。

9.4 强势趋势

强势趋势是第四版中完善的 concept,用于识别 exceptional 强劲牛市,投资者应重仓持有且较慢卖出。

强势趋势条件:
1. 21日指数均线高于50日简单均线。
2. 50日简单均线高于200日简单均线。
3. 200日简单均线正在上升。
4. 指数已收盘高于21日EMA至少10+个连续日,
   或在上升趋势期间未收盘低于50日均线。

处于强势趋势时:
- 在仓位规模上更激进。
- 给赢家更多空间——考虑持有通过10周均线测试而非卖出。
- 不要过早获取20-25%利润对于表现 exceptional 的股票。
- 允许你最好的股票发展为100%+收益。
- 强势趋势保持有效直到21日EMA收盘低于50日均线
  或指数收盘低于50日均线。

10. 行业组强度

10.1 组领导力

奥尼尔的研究揭示大约37%的股票价格变动直接与其行业组表现相关,另有**12%**可归因于其整体板块。这意味着股票涨跌的大约一半取决于它所在的 company。

规则:
- 关注前40-50个行业组(IBD的197个组中)按6个月相对价格表现排名的股票。
- 避免排名在后四分之一的组中的股票——即使是好公司也会在弱组中挣扎。
- 当新牛市开始时,识别哪些组正在领导。
  首先突破并显示大量成交的组通常领导数周或数月。
- 最佳股票通常是领导组的#1或#2表现者。

组轮换:
- 一个组领导数月后,最终会轮换到落后者名单。
  不要无限期持有组领导者——当组开始表现不佳时卖出。
- 在市场调整中,观察哪些组保持最好。这些"相对强度"
  领导者往往在市场转回向上时首先突破。

10.2 随涨行情和组突破

- 当组中#1股票突破时,#2和#3股票通常在数天或数周内跟随。
  寻找组突破——同一组中多只股票同时形成基底并接近支点。
- 但是,总是首先买领导者。不要因为#3"更便宜"就买它。
  领导者通常会产生最大收益。

11. 机构持仓分析

11.1 定量措施

检查什么:
1. 机构持有人数量:环比增加?
2. 持有人质量:顶级基金(富达、普信等)在买入?
3. 过去1-3年表现最佳的基金是否在积累该股票?
4. IBD积累/派发评分:A或B是必需的。C是中性。D或E是取消资格——机构在卖出。
5. 作为浮动百分比持有的基金数量:如果太多基金已经持有(过度持有),
   没有边际买家剩余。

11.2 阅读盘口

机构足迹:
- 在没有新闻的情况下在异常大量(比平均高50%+)上涨的股票很可能
  正在被机构积累。他们quietly 大量买入。
- 在大量成交下下跌,尤其是在长期上涨后,正在被派发。
  机构在卖出。
- "口袋 pivot"——股票在成交量大于前10个交易日中任何下跌日成交量的日子上涨——
  表示机构积累。

12. 模型手册方法

12.1 什么是模型手册?

模型手册是奥尼尔研究过去赢家股票以训练你的形态识别的方法。这是CAN SLIM方法论中最重要的教育工具。

如何建立模型手册:

1. 识别过去赢家:找到每个市场周期中翻倍或更多的股票。
   来源:IBD的档案、奥尼尔自己发表的例子、历史图表服务。

2. 打印图表:获取显示重大上涨之前和期间价格和成交量的周线图。

3. 标记买入点:在确切支点画一条线。用以下内容注释图表:
   - 基底类型(杯柄形态、双底等)。
   - 基底编号(第一、第二、第三基底)。
   - 基底的深度和持续时间。
   - 突破日成交量与平均比较。
   - 当时的RS评分和EPS评分。

4. 标记卖出点:注释最佳卖出点在哪里。注明:
   - 触发了哪个卖出信号(高潮顶部、跌破10周线等)。
   - 从买入到卖出的可用收益。

5. 研究基本面:对于每只股票,记录:
   - 突破前2-3个季度的季度每股收益增长。
   - 过去3-5年的年化每股收益增长率。
   - 销售增长。
   - ROE。
   - "N"因素——公司有什么新东西。
   - 当时的行业组排名。
   - 机构持仓人数和趋势。

6. 跨周期重复:从1950年代、1960年代、1970年代、1980年代、1990年代、2000年代建立模型。
   形态在所有时代都是一致的。

12.2 模型手册教什么

来自历史模型的教训:

1. 形态是通用的:1963年思科上涨之前的相同杯柄形态先于
   2004年苹果和2004年谷歌的上涨。

2. 基本面是一致的:几乎所有都有突破前25%+(大多50%+)的季度每股收益增长,
   过去3-5年25%+年化每股收益增长、高ROE和强劲销售增长。

3. 新产品推动上涨:几乎每个大赢家都有改变其行业的新产品、服务或商业模式。

4. 市场时机重要:大多数大赢家在,新市场周期早期突破,
   在跟进日后几个月内。

5. 早期基底赢:大多数最大收益来自第一和第二基底突破,
   而非第三或第四。

6. 卖出信号可靠:高潮顶部、派发和跌破10周线一致标记主要上涨的结束。

奥尼尔建议在用真钱交易前研究至少500个历史例子。
这不是建议——他认为是必要的训练。目的是将形态烙印到你的潜意识中,
以便在实时中能够立即识别它们。

13. 常见错误

奥尼尔在导致大多数投资者表现不佳的错误上花了大量篇幅。

错误1:在下跌途中买入
"看起来便宜的股票持续变得更便宜。"投资者因为看起来像便宜货而买入下跌的股票。
奥尼尔说这是一号错误。买入从适当基底突破新高的股票,不买创新低的股票。

错误2:未能在7-8%处切割损失
"在股市获胜的全部秘密是在不正确时损失最少。"大多数投资者持有亏损希望恢复。
小损失变大损失。大损失变成灾难性损失。

错误3:向下摊平
买入更多亏损股票以降低平均成本保证你最大仓位在你表现最差的股票上。

错误4:买便宜股票(低股价)
交易在$10-15/股以下的股票便宜是有原因的。机构投资者——
推动主要上涨的买家——通常避免低价格股票。关注交易在$20-$100+的股票。

错误5:想要基于消息和传言买入
基于"听到"的而非数据显示的买入。CAN SLIM标准是具体和可衡量的。使用它们,不用传言。

错误6:因为股息或低市盈率而买入
股息和低市盈率对成长股无关。最快增长的公司通常有高市盈率——
市场在定价未来增长。奥尼尔发现最佳表现股票在突破时的平均市盈率
高于市场平均,而非更低。

错误7:不关注市场方向
在未检查M因素的情况下买入个股。四分之三的股票跟随一般市场方向。
如果市场处于调整,即使最好的股票也会失败。

错误8:不愿在新高处买入
对在52周或历史新高买入股票的心理抵触。奥尼尔的数据显示
这恰恰是你应该买入的时候——当股票从适当基底进入新高时。

错误9:过早卖出赢家,过久持有输家
处置效应。投资者卖出最好的股票以"锁定"小额利润,
持有最差的股票以"避免"损失。这与有效操作完全相反。
快速切割损失。让赢家跑。

错误10:过度多元化
持有20-30只股票使你不可能深入了解任何一只。奥尼尔建议
大多数投资者最多集中于4-8只股票。如果你有信念,相应调整仓位。

错误11:不用图表
"图表记录股票的实际供求。"拒绝看图表就像医生拒绝看X光。
图表显示机构在做什么——积累还是派发——没有其他工具提供这些信息。

错误12:在市场调整期间买入
在确认下降趋势中 rationalizing "便宜"购买。在确认下降趋势中
正确行动是坐在现金中等待跟进日。

14. 完整交易生命周期示例

场景:寻找和管理从发现到退出的CAN SLIM股票。

步骤1:市场方向检查
- 日期:假设。市场经历了调整(纳斯达克在8周内下跌15%)。
- 反弹尝试第1天:纳斯达克在 undercut 调整低点后收盘上涨1.2%。
- 第4天:纳斯达克在成交量高于第3天的情况下上涨2.3%。
  成交量也高于50日平均。这是跟进日。
- 状态:"确认上升趋势。"开始寻找买入候选。

步骤2:CAN SLIM筛选
- 筛选具有以下条件的股票:
  C:当前季度每股收益增长 >= 25%(最好40%+)
  A:年化每股收益增长 >= 25%超过3年;ROE >= 17%
  N:推动增长的新产品或服务
  S:IBD积累/派发评分为A或B
  L:RS评分 >= 80(最好 >= 85)
  I:机构持仓人数增加;优质持仓人存在
  M:确认上升趋势(已检查)
- XYZ股票通过所有标准:
  * 当前季度每股收益:同比+85%
  * 年化每股收益增长:3年+30%、+45%、+55%
  * ROE:28%
  * 新产品:获得企业采用率的革命性云平台
  * A/D评分:A
  * RS评分:92
  * 机构持仓人:上季度40个,本季度58个
  * 行业组:197个中排名第8

步骤3:图表形态识别
- XYZ形成了14周杯柄形态。
- 杯深度:从峰值到谷底28%。在可接受范围内(12-33%)。
- 柄:3周长,向下倾斜,从柄高到低修正9%。
- 柄在基底的上半部分。
- 成交量在柄期间减少至比平均低40%。
- 这是第一阶段基底(股票从长期不活跃中出现)。
- 支点:柄高点$74.90 + $0.10 = $75.00。

步骤4:执行
- XYZ在周二上午10:15交易超过$75.00。
- 截至中午成交量已达全日平均的80%。预计收盘成交量
  约为50日平均的200%。强劲。
- 在$75.25买入500股(在5%买入区内;最大买入 = $78.75)。
- 设置止损:$75.25 × 0.92 = $69.23。如果达到此水平则卖出。
- 仓位规模:约 portfolio 的15%。

步骤5:仓位管理
- 第1周:XYZ上涨至$79.50。收益 = +5.6%。成交量保持高于平均。持有。
- 第2周:XYZ回调至$77.00。回调成交量低于平均。正常。持有。
- 第3周:XYZ上涨至$84.00。收益 = +11.6%。仍高于10周线。持有。
- 第5周:XYZ达到$91.00。收益 = +20.9%,5周内。这是20-25%目标范围。
  但收益在最初3周内达到20%。调用8周持有规则。不要卖。
  从突破日起至少持有8周。
- 第8周:XYZ为$98.50。收益 = +30.9%。8周持有期完成。
  股票仍在10周均线上方。RS评分为95。继续持有。

步骤6:继续持有/大赢家管理
- 第12周:XYZ已上涨至$112.00。收益 = +48.8%。
  股票形成平底(5周,8%深)并突破至新高。这是第二阶段基底。
  可以用较小加仓在这里加仓。
- 第20周:XYZ达到$135.00。收益 = +79.4%。
  10周均线在$118.00。股票表现良好。继续持有。

步骤7:卖出信号出现
- 第26周:XYZ在盈利击败下跳空高开$12——这是自突破以来最大单日上涨。
  成交量为6个月最高。第一号高潮顶部信号。
- 第27周:XYZ有史以来最宽的周价格范围:高$158,低$141。
  第二号高潮顶部信号(宽幅震荡)。
- 第27周:成交量非常大但价格当周大致持平。
  第三号高潮顶部信号(翻腾/铁路轨道)。
- 决定:在$152.00卖出全部仓位。
- 最终收益:($152.00 - $75.25) / $75.25 = +102%。
- 持续时间:27周(约6.5个月)。

结果摘要:
  买入:   $75.25
  卖出:   $152.00
  收益:   +102%
  风险:   限制在-8%($69.23止损)= 12.8:1的收益风险比。

15. 实施伪代码

15.1 CAN SLIM筛选器

def can_slim_screen(universe, market_status):
    """
    筛选CAN SLIM候选。
    返回通过所有标准的股票列表。
    """
    if market_status != "CONFIRMED_UPTREND":
        return []  # 在调整或不确定市场中不买入

    candidates = []

    for stock in universe:
        # C - 当前季度盈利
        q_eps_growth = stock.quarterly_eps_growth_yoy(most_recent=True)
        if q_eps_growth < 25:
            continue
        # 首选40%+;加速有加成
        q_eps_prior = stock.quarterly_eps_growth_yoy(quarters_ago=1)
        c_quality = "高" if q_eps_growth >= 40 else "最小"
        c_accelerating = q_eps_growth > q_eps_prior

        # 确认销售增长支持盈利
        q_sales_growth = stock.quarterly_sales_growth_yoy(most_recent=True)
        if q_sales_growth < 25:
            continue

        # A - 年度盈利增长
        annual_eps_rates = stock.annual_eps_growth(years=3)  # 例如 [28, 35, 42]
        if any(rate < 25 for rate in annual_eps_rates):
            continue
        roe = stock.return_on_equity()
        if roe < 17:
            continue
        eps_rating = stock.ibd_eps_rating()
        if eps_rating < 80:
            continue

        # N - 新产品 / 新高
        near_52w_high = stock.price >= stock.high_52week * 0.90
        has_catalyst = stock.has_new_product_or_management()  # 定性标志

        # S - 供需关系
        ad_rating = stock.ibd_accumulation_distribution()
        if ad_rating in ['D', 'E']:
            continue

        # L - 领导者还是落后者
        rs_rating = stock.ibd_rs_rating()
        if rs_rating < 80:
            continue
        rs_line_new_high = stock.rs_line_near_high()

        # I - 机构持仓
        inst_current = stock.institutional_holders(quarter="current")
        inst_prior = stock.institutional_holders(quarter="prior")
        if inst_current <= inst_prior:
            continue  # 需要增加的持仓
        sponsorship_quality = stock.top_fund_holders_count()

        # 组装候选
        candidates.append({
            "symbol": stock.symbol,
            "q_eps_growth": q_eps_growth,
            "c_accelerating": c_accelerating,
            "annual_eps_rates": annual_eps_rates,
            "roe": roe,
            "eps_rating": eps_rating,
            "rs_rating": rs_rating,
            "rs_line_new_high": rs_line_new_high,
            "ad_rating": ad_rating,
            "inst_holders_increasing": True,
            "industry_group_rank": stock.industry_group_rank(),
            "near_52w_high": near_52w_high,
        })

    # 按综合强度排序:RS评级 + EPS评级 + 行业组排名
    candidates.sort(key=lambda c: (
        c["rs_rating"] + c["eps_rating"] - c["industry_group_rank"]
    ), reverse=True)

    return candidates


### 15.2 基底形态检测器


```python
def detect_base_pattern(stock, weekly_bars):
    """
    分析周价格/成交量数据以识别基底形态。
    返回基底类型、买入点和质量指标。
    """
    patterns = []

    # --- 杯柄形态检测 ---
    cup = detect_cup_with_handle(weekly_bars)
    if cup:
        patterns.append(cup)

    # --- 双底形态检测 ---
    db = detect_double_bottom(weekly_bars)
    if db:
        patterns.append(db)

    # --- 平底形态检测 ---
    fb = detect_flat_base(weekly_bars)
    if fb:
        patterns.append(fb)

    # --- 高紧密旗形 ---
    htf = detect_high_tight_flag(weekly_bars)
    if htf:
        patterns.append(htf)

    # --- 上升基底 ---
    ab = detect_ascending_base(weekly_bars)
    if ab:
        patterns.append(ab)

    return patterns


def detect_cup_with_handle(bars):
    """
    检测杯柄形态。
    """
    MIN_WEEKS = 7
    MAX_DEPTH = 0.33        # 33%最大回撤(正常市场)
    BEAR_MAX_DEPTH = 0.50   # 熊市最大50%
    HANDLE_MAX_WEEKS = 4
    HANDLE_MAX_DEPTH = 0.15  # 15%

    # 步骤1:找到左侧高点(前峰值)
    left_high = find_prior_peak(bars)
    if not left_high:
        return None

    # 步骤2:找到杯底(谷底)
    cup_low = find_trough_after(bars, left_high.index)
    if not cup_low:
        return None

    # 步骤3:检查深度
    depth = (left_high.high - cup_low.low) / left_high.high
    if depth > MAX_DEPTH:
        return None  # 太深(根据熊市背景调整)
    if depth < 0.12:
        return None  # 太浅 — 可能是平底

    # 步骤4:找到右侧高点(向左侧高点恢复)
    right_high = find_peak_after(bars, cup_low.index)
    if not right_high:
        return None

    # 步骤5:检查U形(不是V形)
    weeks_down = cup_low.index - left_high.index
    weeks_up = right_high.index - cup_low.index
    if weeks_up < 2 or weeks_down < 2:
        return None  # V形,不是U形

    # 步骤6:总持续时间检查
    total_weeks = right_high.index - left_high.index
    if total_weeks < MIN_WEEKS:
        return None

    # 步骤7:检测柄部
    handle = detect_handle(bars, right_high.index)
    if handle:
        # 柄部验证
        handle_depth = (handle.high - handle.low) / handle.high
        if handle_depth > HANDLE_MAX_DEPTH:
            return None
        if handle.weeks > HANDLE_MAX_WEEKS:
            return None
        # 柄部必须在基底的上半部
        base_midpoint = cup_low.low + (left_high.high - cup_low.low) / 2
        if handle.low < base_midpoint:
            return None  # 柄部太低
        # 柄部必须向下倾斜(不是楔形向上)
        if handle.slope > 0:
            return None
        buy_point = handle.high + 0.10
    else:
        # 无柄杯形
        buy_point = left_high.high + 0.10

    # 步骤8:成交量分析
    avg_vol_base = average_volume(bars, left_high.index, right_high.index)
    vol_dry_up = volume_declining(bars, right_high.index - 3, right_high.index)

    return {
        "pattern": "cup_with_handle" if handle else "cup_without_handle",
        "buy_point": buy_point,
        "depth_pct": depth * 100,
        "duration_weeks": total_weeks,
        "handle_present": handle is not None,
        "volume_dry_up": vol_dry_up,
        "base_number": count_prior_bases(bars, left_high.index),
    }


def detect_double_bottom(bars):
    """
    检测双底(W)形态。
    关键:第二个低点必须跌破第一个低点。
    """
    MIN_WEEKS = 7

    # 找到第一个低点
    first_low = find_first_significant_low(bars)
    if not first_low:
        return None

    # 找到中间峰值(两次低点之间的反弹)
    middle_peak = find_peak_after(bars, first_low.index)
    if not middle_peak:
        return None

    # 找到第二个低点
    second_low = find_low_after(bars, middle_peak.index)
    if not second_low:
        return None

    # 关键:第二个低点必须跌破第一个低点
    if second_low.low >= first_low.low:
        return None  # 不是有效的双底

    # 持续时间检查
    total_weeks = second_low.index - find_start_of_base(bars)
    if total_weeks < MIN_WEEKS:
        return None

    # 买入点是中间峰值 + $0.10
    buy_point = middle_peak.high + 0.10

    return {
        "pattern": "double_bottom",
        "buy_point": buy_point,
        "first_low": first_low.low,
        "second_low": second_low.low,
        "undercut_amount": first_low.low - second_low.low,
        "duration_weeks": total_weeks,
        "base_number": count_prior_bases(bars, first_low.index),
    }


def detect_flat_base(bars):
    """
    检测平底:紧凑的横向调整,最大10-15%深,最少5周。
    """
    MIN_WEEKS = 5
    MAX_DEPTH = 0.15

    recent_range = bars[-MIN_WEEKS:]
    high = max(b.high for b in recent_range)
    low = min(b.low for b in recent_range)
    depth = (high - low) / high

    if depth > MAX_DEPTH:
        return None

    buy_point = high + 0.10

    return {
        "pattern": "flat_base",
        "buy_point": buy_point,
        "depth_pct": depth * 100,
        "duration_weeks": len(recent_range),
    }


def detect_high_tight_flag(bars):
    """
    检测高紧密旗形:4-8周内上涨100%+,然后3-5周内调整10-25%。
    """
    # 找到旗杆:短期内100%+的涨幅
    for i in range(len(bars) - 12, len(bars) - 5):
        start_price = bars[i].low
        peak_idx = None
        for j in range(i + 4, min(i + 9, len(bars))):
            if bars[j].high >= start_price * 2.0:
                peak_idx = j
                break
        if not peak_idx:
            continue

        # 找到旗形:10-25%的回调,持续3-5周
        peak_price = bars[peak_idx].high
        flag_low = min(b.low for b in bars[peak_idx:peak_idx + 6])
        flag_depth = (peak_price - flag_low) / peak_price

        if 0.10 <= flag_depth <= 0.25:
            flag_high = max(b.high for b in bars[peak_idx:peak_idx + 6])
            return {
                "pattern": "high_tight_flag",
                "buy_point": flag_high + 0.10,
                "flagpole_gain_pct": ((peak_price - start_price) / start_price) * 100,
                "flag_depth_pct": flag_depth * 100,
            }

    return None

15.3 市场方向模型

class MarketDirectionModel:
    """
    实现M因素:跟进日检测和分配日计数。
    """

    def __init__(self):
        self.status = "CORRECTION"  # CONFIRMED_UPTREND, UPTREND_UNDER_PRESSURE, CORRECTION
        self.distribution_days = []  # {date, index_close, index_name}列表
        self.rally_day_count = 0
        self.rally_low = None
        self.power_trend_active = False

    def update(self, index_data_today, index_data_yesterday):
        """
        每日调用指数数据。更新市场状态。
        """
        today = index_data_today
        yesterday = index_data_yesterday

        if self.status == "CORRECTION":
            self._check_for_rally_attempt(today, yesterday)
            self._check_for_follow_through(today, yesterday)

        elif self.status in ["CONFIRMED_UPTREND", "UPTREND_UNDER_PRESSURE"]:
            self._check_for_distribution(today, yesterday)
            self._expire_old_distribution_days(today.date)
            self._evaluate_distribution_count()
            self._check_power_trend(today)

    def _check_for_rally_attempt(self, today, yesterday):
        """反弹尝试第一天:指数收涨。"""
        if today.close > yesterday.close:
            if self.rally_day_count == 0:
                self.rally_day_count = 1
                self.rally_low = min(today.low, yesterday.low)
            else:
                self.rally_day_count += 1
        # 如果指数跌破反弹低点,重置
        if today.low < self.rally_low:
            self.rally_day_count = 0
            self.rally_low = None

    def _check_for_follow_through(self, today, yesterday):
        """
        跟进日:反弹尝试的第4天,指数涨幅约1.5%+,成交量高于前日。
        """
        if self.rally_day_count < 4:
            return

        gain_pct = (today.close - yesterday.close) / yesterday.close * 100

        if gain_pct >= 1.5 and today.volume > yesterday.volume:
            self.status = "CONFIRMED_UPTREND"
            self.distribution_days = []
            self.rally_day_count = 0

    def _check_for_distribution(self, today, yesterday):
        """
        分配日:指数跌幅>=0.2%,成交量高于前日。
        同时检查停滞日。
        """
        change_pct = (today.close - yesterday.close) / yesterday.close * 100

        # 标准分配日
        if change_pct <= -0.2 and today.volume > yesterday.volume:
            self.distribution_days.append({
                "date": today.date,
                "close": today.close,
                "type": "distribution",
            })

        # 停滞日:在成交量较高的情况下,收盘价处于当日区间的底部25%
        if change_pct > 0 and today.volume > yesterday.volume:
            daily_range = today.high - today.low
            if daily_range > 0:
                close_position = (today.close - today.low) / daily_range
                if close_position < 0.25:
                    self.distribution_days.append({
                        "date": today.date,
                        "close": today.close,
                        "type": "stalling",
                    })

    def _expire_old_distribution_days(self, current_date):
        """删除25个交易日之前的分配日。"""
        cutoff = trading_days_ago(current_date, 25)
        self.distribution_days = [
            d for d in self.distribution_days
            if d["date"] >= cutoff
        ]

    def _evaluate_distribution_count(self):
        """根据分配日数量更新状态。"""
        count = len(self.distribution_days)

        if count >= 6:
            self.status = "CORRECTION"
            self.power_trend_active = False
        elif count >= 4:
            self.status = "UPTREND_UNDER_PRESSURE"
        else:
            self.status = "CONFIRMED_UPTREND"

    def _check_power_trend(self, today):
        """
        强势趋势:21日EMA > 50日SMA > 200日SMA,均向上。
        """
        ema_21 = today.ema_21
        sma_50 = today.sma_50
        sma_200 = today.sma_200

        if (ema_21 > sma_50 > sma_200
                and sma_200 > today.sma_200_prior
                and today.close > ema_21):
            self.power_trend_active = True
        elif ema_21 < sma_50 or today.close < sma_50:
            self.power_trend_active = False


### 15.4 完整交易管理器


```python
class TradeManager:
    """
    管理仓位生命周期:入场、监控、出场。
    """

    def __init__(self, portfolio_value, max_positions=8):
        self.portfolio_value = portfolio_value
        self.max_positions = max_positions
        self.positions = []

    def evaluate_entry(self, stock, base_pattern, market_model):
        """判断今天是否应该买入股票。"""

        if market_model.status != "CONFIRMED_UPTREND":
            return None

        if not base_pattern:
            return None

        if base_pattern["base_number"] >= 4:
            return None  # 晚期,跳过

        current_price = stock.current_price
        buy_point = base_pattern["buy_point"]
        max_buy = buy_point * 1.05  # 5%买入区

        if current_price < buy_point or current_price > max_buy:
            return None  # 不在买入区

        # 检查成交量
        volume_ratio = stock.todays_volume / stock.avg_volume_50day
        if volume_ratio < 1.40:
            return None  # 成交量不足

        # 计算仓位大小(等权,根据信心调整)
        position_pct = 1.0 / self.max_positions  # 例如8个仓位时为12.5%
        if base_pattern["base_number"] == 1 and stock.rs_rating >= 90:
            position_pct *= 1.25  # 最高信心时增加
        if base_pattern["base_number"] == 3:
            position_pct *= 0.75  # 后期基底减少

        position_value = self.portfolio_value * position_pct
        shares = int(position_value / current_price)
        stop_loss = current_price * 0.92  # 8%止损

        return {
            "action": "BUY",
            "symbol": stock.symbol,
            "shares": shares,
            "price": current_price,
            "stop_loss": stop_loss,
            "buy_point": buy_point,
            "base_type": base_pattern["pattern"],
            "base_number": base_pattern["base_number"],
        }

    def monitor_position(self, position, stock, week_number):
        """对现有仓位进行每日检查。"""

        current_price = stock.current_price
        gain_pct = (current_price - position["price"]) / position["price"] * 100

        # --- 防御:检查止损 ---
        if current_price <= position["stop_loss"]:
            return {"action": "SELL", "reason": "stop_loss_hit",
                    "gain_pct": gain_pct}

        # --- 防御:往返规则 ---
        if position.get("max_gain_pct", 0) >= 10 and gain_pct <= 0:
            return {"action": "SELL", "reason": "round_trip",
                    "gain_pct": gain_pct}

        # 更新最大收益跟踪
        if gain_pct > position.get("max_gain_pct", 0):
            position["max_gain_pct"] = gain_pct

        # --- 进攻:20-25%盈利规则 ---
        if gain_pct >= 20:
            # 检查是否在前3周内达到20%
            if week_number <= 3:
                position["eight_week_hold"] = True
                # 不要卖出 — 至少持有8周
            elif not position.get("eight_week_hold"):
                return {"action": "SELL", "reason": "profit_target_20_25",
                        "gain_pct": gain_pct}

        # --- 8周持有规则 ---
        if position.get("eight_week_hold") and week_number < 8:
            return {"action": "HOLD", "reason": "eight_week_hold_active",
                    "gain_pct": gain_pct}

        # --- 高潮顶部检测 ---
        if self._detect_climax_top(stock, position):
            return {"action": "SELL", "reason": "climax_top",
                    "gain_pct": gain_pct}

        # --- 10周均线突破 ---
        if (current_price < stock.sma_50
                and stock.todays_volume > stock.avg_volume_50day * 1.2):
            return {"action": "SELL", "reason": "broke_10_week_heavy_vol",
                    "gain_pct": gain_pct}

        return {"action": "HOLD", "gain_pct": gain_pct}

    def _detect_climax_top(self, stock, position):
        """检查高潮顶部衰竭信号。"""
        signals = 0

        # 自突破以来最大单日涨幅
        if stock.todays_gain_pct >= stock.max_daily_gain_since(position["entry_date"]):
            signals += 1

        # 衰竭性向上跳空
        if stock.gapped_up and stock.todays_volume > stock.avg_volume_50day * 2:
            signals += 1

        # 距离200日均线较远
        distance_200 = (stock.current_price - stock.sma_200) / stock.sma_200 * 100
        if distance_200 > 70:
            signals += 1

        # 宽幅震荡(最宽的周区间)
        if stock.weekly_range_pct >= stock.max_weekly_range_since(position["entry_date"]):
            signals += 1

        return signals >= 2  # 两个或更多信号 = 卖出

16. 关键语录

"对大多数人来说看似过高和风险的东西往往会涨得更高,而对大多数人来说看似低和便宜的东西往往会跌得更低。"

"在股市中获胜的全部秘密是,当你不正确的时候,尽可能少亏损。"

"卖出的第一条也是最重要的规则是:削减每一笔亏损。这是你能学到的最重要的投资教训。"

"在大成交量配合下,当股票从可靠的图表形态中创出新高时买入,是在股市赚钱最有效的方式。"

"个人投资者陷入困境是因为他们要么不知道大盘方向,要么与大盘对抗。四分之三的股票跟随大盘趋势。"

"我宁愿在上涨途中以每股60美元买入,也不愿在下跌途中以30美元买入。"

"市场不知道也不关心你买入股票的价格是多少。它不会仅仅因为你亏损就反弹。"

"向下摊平是一种业余策略,可能造成严重损失。"

"你必须研究过去的市场领导者,学会如何发现和识别有潜力成为未来大赢家的股票。这对投资成功至关重要。"

"你应该像买食品杂货一样买股票,而不是像买香水一样买股票。"
  [含义:基于实质和价值投资,而不是魅力和兴奋。]

"图表只是供求关系的画面。你为什么会不想看那张图?"

"重要的不是你是否正确或错误,而是当你正确时赚了多少,当你错误时亏损了多少。"

"你的目标不是在最低点买入或在最高点卖出。是在正确的价格买入和卖出。"

"最好的股票从来不便宜。你必须克服股票高价就是贵、低价就是便宜的观念。"

"如果你想成功,研究成功——而不是失败。"
  [指的是模型手册方法,即研究历史赢家。]

附录:快速参考卡

========================================================================
                      CAN SLIM 快速参考
========================================================================

C  当前季度EPS增长         >= 25% 同比增长(首选40-100%+)
A  年度EPS增长            过去3年每年>= 25%;ROE >= 17%
N  新产品/管理层          + 股价接近或达到52周新高
S  供需关系               A/D评级A或B;突破时成交量高于均值50%+以上
L  领导者                 RS评级>= 80(首选85+);行业组第一
I  机构持仓               持仓数量增加;优质基金买入
M  市场方向               确认的上升趋势(跟进日已确认)

基底形态:
  杯柄           7+周     12-33%深    柄部1-4周,<15%深
  无柄杯形       7+周     12-33%深    无柄;在左高+$0.10买入
  双底           7+周     12-33%深    第二个低点必须跌破第一个低点
  平底           5+周     <15%深      延续形态
  高紧密旗形     100%+运行 10-25%旗形  最稀有、最强势
  上升基底       9-16周   3次回调     每个低点高于前一个
  带柄碟形       数月+     12-33%深    缓慢、逐渐的圆底

买入规则:
  在支点买入(基底高点 + $0.10)
  买入区:支点至支点+5%。绝不追涨超过5%。
  突破时成交量 >= 40-50%高于50日均值

卖出规则(防御):
  在买入价下方7-8%处止损。无例外。
  如果往返(10%+收益回到盈亏平衡点)则卖出。
  在大成交量跌破50日均线时卖出。

卖出规则(进攻):
  在20-25%时获利了结(除非3周内达到20%——则持有8周)。
  在高潮顶部信号时卖出(衰竭跳空、最宽区间、翻腾、通道突破)。
  使用10周均线作为大赢家的移动止损指南。

市场方向:
  跟进日:反弹第4天+起,指数涨幅约1.5%+,成交量高于前日。
  分配日:指数跌幅>=0.2%,成交量高于前日。
  25天窗口内4-5个分配日 = 上升趋势承压。
  6+个分配日 = 调整。持有现金。
  强势趋势:21日EMA > 50日SMA > 200日SMA,均上升。积极操作。

基底计数:
  第1个基底 = 最高概率。第2个 = 高。第3个 = 可接受。
  第4个+ = 高失败率。避免。
  如果股票跌破先前基底低点或经历熊市下跌,计数重置。
========================================================================