跳转至

⚠️ 免责声明:本章仅为教育与研究方法展示,不构成任何投资建议。 所有回测结果来自历史数据,不代表未来表现。投资有风险,决策需独立判断。

第三课:均值-标准差策略——离正常有多远

本章代码:code/lesson3_mean_std.py 运行方式:python lesson3_mean_std.py

3.0 策略概述

这是什么策略

PE 分位数(第二课)问的是"排第几"。均值-标准差问的是"偏多远"。

举个例子。一个班的考试成绩,你的分数是 85 分。分位数告诉你"你排在班级前 30%"。标准差告诉你"你比班级平均分高 1.5 个标准差"。两个答案都有用,但含义不同——分位数只看排名,标准差看偏离幅度。

在投资中:PE 分位数说"当前 PE 排在历史的 80% 分位"。均值-标准差说"当前 PE 比历史均值高 2 个标准差"。

它回答什么问题

问题 白话
PE 偏离它的正常范围多远? 用标准差衡量偏离幅度
什么叫"极端"? 超过 ±2 个标准差 = 统计学上的极端
为什么分位数还不够? 分位数在趋势性市场中会失效——标准差捕捉偏离幅度

核心算法

每周末做一次判断:
  1. 取最近 5 周的 PE 均值(平滑)
  2. 计算历史 PE 的滚动均值 avg 和标准差 std
  3. 创建 5 个区间:
     当前 PE <= avg - 2*std        → 满仓(极度低估)
     avg - 2*std < PE <= avg - 1.5*std → 加仓(低估)
     avg - 1.5*std < PE < avg + 1.5*std → 不动(正常)
     avg + 1.5*std <= PE < avg + 2*std → 减仓(高估)
     当前 PE >= avg + 2*std        → 空仓(极度高估)

参数 m=2.0、n=1.5 来自原始 notebook,但在不同指数上需要重新调整。

死穴

这个策略假设 PE 围绕一个固定的均值波动。 如果 PE 长期单边上涨(像深证红利 2008—2017:PE 从 9 到 42),滚动均值永远追不上当前 PE,策略永远不触发——变成"永远空仓,吃利息"。


3.1 核心代码

# 参数
m = 2.0   # 上轨:avg + 2*std = 极度高估
n = 1.0   # 下轨:avg - 1*std = 低估(从 1.5 调下来后效果更好)

position = [0]  # 初始空仓

for i in range(WARMUP, n_weeks):
    current_pe = pe_data[i-5:i].mean()       # 5 周平滑

    # 关键:均值 and 标准差只用 PAST 数据(没有未来信息泄露)
    avg = pe_data[0:(i-1)].mean()            # 到今天为止的历史均值
    std = pe_data[0:(i-1)].std()             # 到今天为止的历史标准差

    if current_pe <= avg - m*std:
        position.append(1)                    # 比均值低 2 个标准差 → 极度低估 → 满仓
    elif current_pe <= avg - n*std:
        if position[-1] >= 0.5: position.append(1)
        else: position.append(0.5)            # 低估 → 建仓
    elif current_pe < avg + n*std:
        position.append(position[-1])         # 正常 → 不动
    elif current_pe < avg + m*std:
        if position[-1] == 1: position.append(0.5)
        else: position.append(position[-1])   # 高估 → 减仓
    else:
        position.append(0)                    # 极度高估 → 空仓

和 PE 分位数的关键区别

PE 分位数(第二课) 均值-标准差(本课)
问什么 排第几 偏多远
阈值来源 排序(20%/30%/60%/80%) 统计量(均值 ±n*σ)
优势 不假设正态分布 对"极端"有明确定义
死穴 趋势市场中分位数无意义 PE 不均值回归时永远空仓
深证红利 +44.5%(旧数据) 任何参数都失效

3.2 参数实验:从失效到有效

原始 notebook 用 m=2.0, n=1.5。在深证红利上完全失效——298 周中 0 周满仓、0 周半仓、298 周空仓。策略变成了银行存款。

我们换了四个指数来试四组参数:

m, n CSI300 年化 说明
2.5, 1.5 3.6% 区间太宽 → 永远不触发 → 等于存银行
2.0, 1.5 3.6% 同上
2.0, 1.0 11.5% 最佳——比买入持有(7.7%)高 49%
1.5, 1.0 10.3% 也不错
1.0, 0.5 7.9% 区间太窄 → 频繁交易 → 交易成本吃掉收益

教训:参数不是复制过来的。 m=2.0, n=1.5 是原始 notebook 在深证价值(399348.SZ)上调出来的。换个指数就要重新调。这就是为什么第二章开始说——"回测好看不等于策略有效"。

图 3-1:沪深300 PE 与滚动均值(新数据 2005-2026)。 PE 长期在均值带内波动时,均值-标准差策略才有意义;趋势性上涨/下跌时它永远不触发。

图 3-1

3.3 为什么深证红利上完全失效

深证红利的 PE 从 2008 年的 9 涨到 2017 年的 42。它从来没有均值回归——它一直在涨。

想象一个人在长身体:12 岁 150cm,18 岁 180cm。你用"历史平均身高"(165cm)来判断他"是不是太高了"——你会永远觉得他"高于平均",永远建议他"少吃饭"。但他只是正常成长。

深证红利的 PE 就是这个人。它的"正常 PE"不是一个数字,是一条向上的曲线。

3.4 分位数 vs 标准差——终极对比

场景 用分位数 用标准差
PE 在稳定区间震荡(如 15-25)
PE 长期单边上涨 ✅ 仍有效 ❌ 永远空仓
PE 有极端值(暴涨暴跌) ✅ 只看排名 ❌ 极端值撑大标准差
PE 近似正态分布

均值-标准差只在 PE 真正围绕一个稳定均值波动时才有效。 在 A 股,这样的指数极少。这就是为什么这个策略在 11 课里出场最晚——不是因为它厉害,是因为它的适用条件最苛刻。

3.5 这一课教了你什么

  1. 均值-标准差问的不是"排第几",是"偏多远"。
  2. 参数 m 和 n 是指数特定的——m=2.0, n=1.0 在 CSI300 上有效,在深证红利上完全无用。
  3. 失效的根本原因:策略假设 PE 均值回归。深证红利的 PE 从不均值回归——它在 10 年里涨了 4 倍。
  4. 一个残酷的事实:A 股市场上,满足"均值回归"条件的指数极少。 这个策略的适用面比 PE 分位数窄得多。
  5. 你学会了第二个防止被骗的工具:当别人说"这个策略有效"时,问他"在哪个指数上?用什么参数?数据到哪一年?"

3.6 课堂问答

问:你在书中说深证红利的 PE 一直在涨,像一个人在长身体。那是不是意味着 PE 策略永远失效了?

不是永远。是\"在那个时间段失效了\"。2008—2017 年深证红利 PE 单边上涨——PE 分位数策略失效,因为\"排第几\"失去了意义。但如果某一天深证红利 PE 开始在一个区间内震荡(比如 15—25 之间反复),PE 分位数策略会重新有效。策略的有效性不是永恒属性——是特定市场条件下的属性。

问:你一直在说\"参数不能复制\"。那怎么找到正确的参数?

滚动窗口测试。用 2005—2010 的数据调参数 → 在 2011—2013 上验证 → 用 2005—2013 重新调 → 在 2014—2017 上验证。让参数选择和收益验证完全分离。如果某组参数在所有滚动窗口上都稳定——这才是真正有效的参数。m=2.0, n=1.0 在 CSI300 上就是我这样找到的。


动手练习(第 3 课)

  1. 入门:扩大参数扫描。把 m, n 的范围扩大到 (3.0, 0.5) 和 (0.5, 0.3), 补全第 3.2 节的表格。你会看到参数"最优区"有多窄。
  2. 进阶:半程验证(walk-forward 雏形)。用 2008-2012 的数据找最优参数, 然后在 2013-2017 上验证——"最优参数"在验证期还灵吗? 如果失效,恭喜你,你刚刚亲眼看到了过拟合。
  3. 挑战:迁移到采购决策。把你行业的原材料价格序列,套用"偏离均值 N 个标准差 就是采购信号"的逻辑:过去 10 年,这个信号每次都对吗?错了几次?

下节预告: 前两课都用的是历史数据——\"过去发生了什么\"。第四课换一个角度:\"未来可能发生什么\"——100,000 种可能的未来,蒙特卡洛模拟。