第一章:经典滤波器设计——移动平均线(SMA/EMA)的数学原理与实战应用
各位同学,我是老张。在量化交易这个行当摸爬滚打了十几年,要说哪个工具最基础、最常用,我第一个想到的就是移动平均线。很多人觉得它简单,不就是算个平均值嘛。但说实话,真正理解它背后信号处理逻辑的人,并不多。
今天这一章,我们就来把 SMA 和 EMA 的底裤扒干净。从数学原理到实战坑点,我会把我在项目中踩过的雷、总结的经验,一股脑倒给你们。
1.1 移动平均线的本质:一个低通滤波器
先问大家一个问题:价格序列里有什么?有趋势,有噪声。我们做交易,想要的是趋势,而不是那些随机跳动的毛刺。移动平均线,说白了就是一个低通滤波器——它把高频的噪声滤掉,留下低频的趋势信号。
我刚开始做策略回测时,总喜欢用很短的均线,觉得反应快。结果呢?频繁被假突破打脸。后来才明白,均线越短,保留的噪声越多,信号越不靠谱。
核心观点:移动平均线 = 数字低通滤波器。它的截止频率由窗口长度决定。窗口越长,截止频率越低,平滑效果越强。
1.2 SMA(简单移动平均线)的数学原理
SMA 的公式很简单,小学生都会算:
SMA(n) = (P₁ + P₂ + ... + Pₙ) / n
其中 P 是价格,n 是窗口长度。但这里有个容易被忽略的点:SMA 对窗口内所有数据一视同仁,权重完全相等。这意味着什么呢?
- 优点:计算简单,容易理解
- 缺点:对最新价格不敏感,存在滞后性
我记得有一次做高频策略,用 SMA 做信号触发,结果发现每次信号出来,行情已经走了一半。这就是滞后性在作祟。你想想看,一个 20 日均线,它包含了 20 天前的价格信息,那些老数据还在拖后腿呢。
实战技巧:我个人习惯用 SMA 做长期趋势判断(比如 60 日、120 日),因为长期趋势不需要那么敏感,滞后一点反而能过滤掉更多噪声。
1.3 EMA(指数移动平均线)的数学原理
EMA 的出现,就是为了解决 SMA 滞后性的问题。它的核心思想是:给近期的价格更高的权重,给远期的价格更低的权重。公式如下:
EMA(t) = α × P(t) + (1 - α) × EMA(t-1)
其中 α = 2 / (n + 1),是平滑因子。这个公式其实是一个递归的指数加权过程。你仔细看,它本质上就是一个一阶 IIR(无限脉冲响应)低通滤波器。
为什么会这样?因为 EMA 的权重随着时间呈指数衰减。越新的数据,权重越大;越老的数据,权重趋近于零。这比 SMA 那种一刀切的权重分配,要合理得多。
| 特性 | SMA | EMA |
|---|---|---|
| 权重分配 | 等权 | 指数衰减 |
| 滞后性 | 较大 | 较小 |
| 对噪声敏感度 | 较低 | 较高 |
| 计算复杂度 | 低 | 低(递归) |
| 典型应用场景 | 长期趋势 | 短期信号 |
避坑指南:我曾经在回测中直接用 EMA 的默认参数,结果发现信号频繁到没法看。后来才意识到,EMA 对噪声太敏感了,需要配合其他滤波器一起使用。记住,EMA 不是万能的。
1.4 低通滤波与高通滤波在价格平滑中的应用
好了,现在我们知道了 SMA 和 EMA 都是低通滤波器。那高通滤波器呢?其实很简单:价格序列减去低通滤波后的结果,剩下的就是高频成分。
举个例子:
高通信号 = 原始价格 - 低通滤波后的价格
这个高通信号,其实就是价格相对于均线的偏离度。在交易中,我们经常用它来识别超买超卖状态。比如价格远离 20 日均线,说明短期情绪过热,可能面临回调。
我个人习惯用这种组合:
- 低通滤波:用 EMA(20) 提取趋势
- 高通滤波:用价格 - EMA(20) 提取波动
这样,趋势和波动就分开了。做趋势跟踪时看低通信号,做均值回归时看高通信号。各司其职,互不干扰。
核心逻辑:低通滤波 = 趋势,高通滤波 = 波动。两者结合,才能完整描述价格行为。
1.5 实战代码示例:用 Python 实现 SMA 和 EMA
光说不练假把式。下面我给出一段 Python 代码,你们可以直接跑起来看看效果。
import numpy as np
import pandas as pd
# 生成模拟价格数据
np.random.seed(42)
prices = 100 + np.cumsum(np.random.randn(200) * 0.5)
# SMA 实现
def sma(data, window):
return pd.Series(data).rolling(window=window).mean().values
# EMA 实现
def ema(data, window):
alpha = 2 / (window + 1)
result = np.zeros_like(data)
result[0] = data[0]
for i in range(1, len(data)):
result[i] = alpha * data[i] + (1 - alpha) * result[i-1]
return result
# 计算
sma_20 = sma(prices, 20)
ema_20 = ema(prices, 20)
# 输出前几个值看看
print("原始价格:", prices[:5])
print("SMA(20):", sma_20[:5])
print("EMA(20):", ema_20[:5])
这段代码里,SMA 用的是滑动窗口平均,EMA 用的是递归公式。你跑一下就会发现,EMA 对最新价格的变化反应更快,而 SMA 则更平滑。
小提示:实际交易中,我建议先用 SMA 做趋势判断,再用 EMA 做入场信号。这样既能保证趋势的可靠性,又能抓住入场时机。
1.6 本章知识体系图
下面这张 SVG 图,把本章的核心逻辑串起来了。你们可以保存下来,随时回顾。
1.7 本章小结
这一章我们讲了三个核心点:
- SMA 和 EMA 都是低通滤波器,区别在于权重分配方式
- 低通滤波提取趋势,高通滤波提取波动
- 实战中要根据场景选择合适的均线类型和参数
嗯,内容不算多,但都是干货。下一章我们会深入讲均线的交叉策略和参数优化,到时候再聊。