均线的物理课:EMA 的重心、速度与加速度
ewm(span=12, adjust=False) 一行就能算出 EMA,但两个问题多数人答不上来:α 为什么偏偏是 2/(N+1) 而不是 1/N?DIF 为什么被称为"速度"?这篇把递推式展开成权重表,用不超过高中的数学推出它的"重心",再用实测数字证明 MACD 那套速度/加速度类比是真家伙——DIF = 7 × 速度,柱 = 56 × 加速度。
起因是在 《确认越多越好吗?》 那篇回测手记里写了一句"口径对齐券商:EMA 递推初值 = 首日值,α = 2/(N+1)",被人追问这几个数字到底哪来的。查了一圈发现:这不是物理定律,是一连串设计选择。讲清楚它,同名指标在不同软件里对不上账的根源也就清楚了。
一、递推式展开:EMA 到底在平均什么
EMA 的递推式大家都熟:
关键在于 E_{t-1} 本身又是递推来的。把昨天、前天、大前天一层层展开,得到:
这就是"指数"二字的来源:距今第 \(k\) 根 K 线的权重是 \(\alpha(1-\alpha)^k\),按指数衰减。看一眼 N=2(\(\alpha=2/3\))的实际权重:
a = 2 / 3 # N=2 -> alpha = 2/(N+1)
w = [a * (1 - a) ** k for k in range(5)]
print([round(x, 4) for x in w])
# [0.6667, 0.2222, 0.0741, 0.0247, 0.0082]
| 距今 | 0 | 1 | 2 | 3 | 4 | … |
|---|---|---|---|---|---|---|
| 权重 | 0.6667 | 0.2222 | 0.0741 | 0.0247 | 0.0082 | 无限延伸 |
这些权重加起来正好是 1(等比级数求和 \(\alpha/(1-(1-\alpha)) = 1\)),所以它确实是个"平均",不会系统性放大或缩小价格。
第一个反直觉的结论
EMA 根本不是"最近 N 根的平均"。它理论上吃无穷根历史,只是老数据的权重指数衰减到接近 0。SMA 你可以干脆地说"它用了 N 根",EMA 说不出来——这正是后面必须引入"重心"的原因。
二、α = 2/(N+1) 是怎么定下来的
EMA 有两个常用的"记忆长度"度量,定义不同,数值也不同。
半衰期:往前多少根,权重衰减到今天的一半?列方程 \((1-\alpha)^k = 0.5\),两边取对数把 \(k\) 从指数上搬下来:
平均滞后(重心):整条权重分布的加权平均年龄,\(L = \sum k \cdot w_k\)。
展开:重心怎么算出 (1-α)/α(不用求导)
\(L = \alpha(r + 2r^2 + 3r^3 + \cdots)\),其中 \(r = 1-\alpha\)。用错位相减:
所以 \(S = r/(1-r)^2\),代回去(注意 \(1-r = \alpha\)):
现在反推 α:想让 EMA 的重心等于同周期 SMA 的重心 \((N-1)/2\),α 该取多少?
这就是 α = 2/(N+1) 的全部来历——为了让 EMA(12) 和 MA(12) 在时间轴上的重心对齐(都是 5.5 根),名字里的"12"才有可比性。
那用 \(\alpha = 1/N\) 会怎样?重心变成 \((1-\alpha)/\alpha = N-1\),整整慢一倍。这不是没人用——它就是 Wilder 平滑,ADX / ATR / RSI 用的口径:
所以通达信的 SMA(X,N,1) 和 EMA(X,N) 都叫"N 日",实际速度差一倍。同名不同速,这才是各软件指标对不上账的真正根源。
实测一下(numpy 直接对权重求和):
| EMA(12) | EMA(26) | EMA(9) | |
|---|---|---|---|
| α | 0.1538 | 0.0741 | 0.2000 |
| 半衰期 | 4.15 | 9.01 | 3.11 |
| 重心(平均滞后) | 5.50 | 12.50 | 4.00 |
| 有效样本量 \(1/\sum w^2\) | 12.000 | 26.000 | 9.000 |
最后一行是个惊喜:EMA(N) 的等效独立样本数精确等于 N,和 SMA(N) 用 N 根完全等价。"12 日 EMA"这个名字因此有三重支撑——重心与 MA(12) 对齐、有效样本量精确等于 12、半衰期同量级。
三、重心:一条能拿尺子量的记忆长度
重心不是文学比喻。造一个匀速上涨的序列(每根涨 \(v\) 元),把权重代进去:
这条式子就是硬证据:匀速上涨时,均线永远落后价格恰好 \(L\) 根 K 线。\(L=5.5\) 意味着"EMA(12) 落后价格 5.5 根"——拿尺子量 \((x_t - E_t)/v\) 就能读出来。
它和物理重心是同一个公式:
| 物理质心 | EMA 重心 | |
|---|---|---|
| 公式 | \(\sum m_i x_i / \sum m_i\) | \(\sum w_k \cdot k / \sum w_k\) |
| "质量" | 砝码质量 | K 线权重 |
| "坐标" | 空间位置 | 时间轴上的根数 |
想象数轴原点 = 今天,往左每根 K 线按权重挂一个砝码,这条均线在时间轴上的平衡点就是重心。
为什么重心(5.5)比半衰期(4.15)大
权重尾巴是"一头粗、一头无限长的细棒"。半衰期看的是粗细减半处(中位数思维),重心看的是整根棒子的平衡点(均值思维)。细尾巴每一处都很细但无限长,累积的质量把平衡点往后拉。描述"滞后多少根",正确答案只能是重心——因为它有上面那条可测量的恒等式。
四、DIF 是速度,柱是加速度
快慢两条 EMA 都套用 \(E_t = x_t - vL\),相减:
DIF = 速度 × 7 根。物理直觉很直白:DIF = 3.5 意味着当前涨速 0.5 元/根,按这个速度 7 根后价格走 3.5 元。它衡量的是移动的快慢,不是价格的高低。
再套一层。DEA 是 DIF 的 9 日 EMA,同样的滞后公式:\(DIF - DEA = 4 \times\)(DIF 每根的变化量)\(= 4 \times 7a\),于是:
实测(匀速与匀加速各造一条序列):
N=12 alpha=0.1538 半衰期= 4.15 重心= 5.50 有效样本量=12.000
N=26 alpha=0.0741 半衰期= 9.01 重心=12.50 有效样本量=26.000
N= 9 alpha=0.2000 半衰期= 3.11 重心= 4.00 有效样本量= 9.000
匀速 v=1.0 -> DIF=7.000000 (预测 7.000) 柱=0.000000 (预测 0)
匀加速 a=0.01 -> 柱=0.560000 (预测 0.560)
匀速时柱严格为 0(速度不变,加速度为零),匀加速时柱严格等于 \(56a\)。分毫不差。
为什么不直接算 今天 − 昨天? 一阶差分当然是速度,但它是裸微分器,对高频噪音的增益随频率线性放大——K 线的随机跳动会被放大成巨大毛刺。而两条 EMA 相减在控制理论里叫实用微分器,频率响应是 \(s/[(1+\tau_{12}s)(1+\tau_{26}s)]\):低频段它就是微分器(得到速度),高频段增益反而衰减(噪音被滤掉)。该微分的地方微分,该滤波的地方滤波。
所以背离必须用 DIF 而不是价格:价格是位置,DIF 是速度。价格创新高但 DIF 没创新高 = 位置还在往上、速度却比上次慢了 = 减速爬升。这和"竖直上抛到最高点前,速度先归零、位置后到顶"是同一件事,用位置看不出来,用速度一眼看穿。
注意事项
- ⚠️ 类比不是定律。市场不是质点,没有惯性定律,价格不会因为涨速快就继续涨。而且层级不严格精确:价格真在加速时,实测 DIF = 19.635,而预测 \(7v = 20.93\),差的 1.295 是二阶项 \(\frac{1}{2}a\Delta E[k^2]\)——加速段 DIF 会略微低估速度。
- ⚠️ 乘 2 只是券商约定。它不改变零点和正负号(因此不改变任何信号),只放大视觉尺度。真正决定"加速度"性质的是 \(DIF - DEA\) 这个差分结构。
- ⚠️ EMA(12) 名义值有尾巴。距今 12 根之外的权重合计约 11%,它并非只看 12 根。命名不精确,但重心对齐,可用。
- ✅ 想自定义一条滞后 T 根的线,直接用 \(\alpha = 1/(T+1)\)(由 \(T = (1-\alpha)/\alpha\) 反解),别拿 N 去猜。
小结
一句话概括:EMA 展开后是权重 \(\alpha(1-\alpha)^k\) 的加权平均,重心 \((1-\alpha)/\alpha\) 就是它落后价格的根数(可测量),而 \(\alpha = 2/(N+1)\) 是人为挑来让 EMA 与同周期 SMA 重心对齐的设计选择;MACD 则是把这套低通滤波器叠了两层,得到速度(DIF)与加速度(柱)。 理解到这里,"为什么各软件同名的线对不上"就不再是玄学,而是初值、α 定义、乘 2 三个开关的排列组合。
附:30 行脚本复现上面所有数字
import numpy as np
import pandas as pd
def ema(s, n):
return s.ewm(span=n, adjust=False).mean()
# 1) 权重的三个度量
for N in (12, 26, 9):
a = 2 / (N + 1)
k = np.arange(5000)
w = a * (1 - a) ** k
print(f"N={N:2d} alpha={a:.4f} 半衰期={np.log(0.5)/np.log(1-a):5.2f}"
f" 重心={(w*k).sum():5.2f} 有效样本量={1/(w**2).sum():6.3f}")
# 2) 匀速上涨:DIF = 7 x 速度
t = np.arange(300)
close = pd.Series(100.0 + 1.0 * t)
dif = ema(close, 12) - ema(close, 26)
dea = ema(dif, 9)
print(f"匀速 v=1.0 -> DIF={dif.iloc[-1]:.6f} (预测 7.000)"
f" 柱={2*(dif-dea).iloc[-1]:.6f} (预测 0)")
# 3) 匀加速:柱 = 56 x 加速度
close2 = pd.Series(100.0 + 0.5 * 0.01 * t**2)
dif2 = ema(close2, 12) - ema(close2, 26)
dea2 = ema(dif2, 9)
print(f"匀加速 a=0.01 -> 柱={2*(dif2-dea2).iloc[-1]:.6f} (预测 0.560)")
最后更新:2026-10-24