本文是《量化指标解码》系列的第6篇,我们将深入解码最基础也最重要的技术指标——移动平均线。从SMA和EMA的本质区别到多均线系统,从葛兰碧八大法则到均线发散收敛,带你真正掌握这个最简单却最实用的趋势利器。

均线深度解码

均线深度解码

写在前面

前面五篇文章,我们讲了RSI、布林带、MACD、DMI这些看起来很"高级"的指标。每个都有复杂的公式,每个都有独特的含义。

但实际交易中我发现一个很有意思的现象:真正赚钱的交易者,往往最依赖的是最简单的均线

举个例子:

  • MACD告诉你趋势方向,但不告诉你支撑阻力在哪

  • 布林带告诉你波动率,但不告诉你趋势是否持续

  • RSI告诉你超买超卖,但在强趋势中经常钝化

而均线,能给你最直观的趋势判断和最可靠的支撑阻力参考

说实话,我现在的交易系统中,均线是第一参考。价格站上均线,做多;跌破均线,做空。听起来很简单,但这个简单的逻辑,配合多周期确认,胜率能稳定在70%以上。

不过话说回来,均线虽然简单,但里面的门道不少。SMA和EMA到底有什么区别?什么时候用SMA,什么时候用EMA?多头排列是不是就能无脑做多?均线粘合预示着什么?

在这篇文章中,我会把均线的方方面面都讲清楚。从原理到代码,从单均线到多均线系统,从经典法则到实战技巧。

一、均线的原理:SMA与EMA的本质区别

1.1 什么是移动平均线?

移动平均线(Moving Average,简称MA)是最古老也是最基础的技术指标之一。

核心思想非常简单:把一段时间内的价格取平均值,用平滑后的曲线来观察趋势

举个例子:

  • 过去5天的收盘价是:100, 102, 104, 103, 105

  • 5日均线 = (100+102+104+103+105) / 5 = 102.8

就这么简单。但就是这么简单的逻辑,却能过滤掉价格的短期波动,显示出真正的趋势方向。

均线主要有两种:

  • SMA(Simple Moving Average) - 简单移动平均线

  • EMA(Exponential Moving Average) - 指数移动平均线

1.2 SMA:简单但稳定

SMA是最原始的均线,计算方式就是简单的算术平均:

SMA(N) = (P1 + P2 + ... + PN) / N

SMA的特点

  • 所有价格权重相同

  • 反应较慢,更平滑

  • 更适合观察中长期趋势

  • 支撑阻力作用更稳定

举个例子,计算5日SMA:

第1天: (100+102+104+103+105) / 5 = 102.8
第2天: (102+104+103+105+107) / 5 = 104.2
第3天: (104+103+105+107+108) / 5 = 105.4

每个价格的权重都是20%(1/5),非常公平。

1.3 EMA:敏感但灵活

EMA则对最近的价格赋予更高的权重,计算方式:

EMA(今日) = EMA(昨日) × (1 - α) + 收盘价(今日) × α

其中:α = 2 / (N + 1)

EMA的特点

  • 对最近价格权重更高

  • 反应更灵敏

  • 更适合捕捉趋势转折

  • 交叉信号更早

举个例子,计算12日EMA:

  • α = 2/(12+1) ≈ 0.154

  • 这意味着今日价格占15.4%权重,昨日EMA占84.6%

这种加权方式让EMA既能快速反应,又不会过于敏感。

在MACD中,我们就是用的EMA而不是SMA,因为要快速捕捉趋势变化。

二、代码实现:如何用Python计算SMA和EMA

理论讲完了,让我们看看如何用代码实现。

2.1 使用TA-Lib计算SMA和EMA

最简单的方式是使用TA-Lib库:

import talib
import numpy as np

def calculate_ma(close_prices: list, period: int = 20):
    """
    计算移动平均线

    Args:
        close_prices: 收盘价序列
        period: 周期
    """
    close_array = np.array(close_prices)

    # 计算SMA
    sma = talib.SMA(close_array, timeperiod=period)

    # 计算EMA
    ema = talib.EMA(close_array, timeperiod=period)

    return sma, ema

就这么简单。TA-Lib已经帮我们实现了所有的计算逻辑。

2.2 在ATMQuant中的实际应用

在我们的项目中,均线被封装在MultiSmaItemMultiEmaItem类中。完整代码在core/charts/multi_sma_item.pymulti_ema_item.py

这里展示核心部分:

# core/charts/multi_sma_item.py

class MultiSmaItem(CandleItem, ConfigurableIndicator):
    """绘制多条SMA的类"""

    def __init__(self, manager, periods: Tuple[int, ...] = (5, 10, 20, 60)):
        super().__init__(manager)
        self.periods = periods
        self.sma_data: Dict[int, Dict[int, float]] = {}

        # 为每个周期设置不同颜色
        colors = [(100, 100, 255), (255, 255, 0),
                  (255, 0, 255), (0, 255, 255)]
        for i, period in enumerate(self.periods):
            color = colors[i % len(colors)]
            self.add_sma_line(period, color, 2)

    def get_sma_value(self, ix: int, sma_window: int) -> float:
        """获取指定位置的SMA值(带缓存)"""
        # 如果缓存中没有,计算所有数据
        if not self.sma_data[sma_window]:
            bars = self._manager.get_all_bars()
            close_data = [bar.close_price for bar in bars]
            sma_array = talib.SMA(np.array(close_data), sma_window)

            # 缓存结果
            for n, value in enumerate(sma_array):
                self.sma_data[sma_window][n] = value

        return self.sma_data[sma_window].get(ix, np.nan)

关键点

  • 支持多周期显示(默认5、10、20、60日线)

  • 使用字典缓存计算结果,提高性能

  • 每条均线用不同颜色区分

  • EMA的实现类似,只是调用talib.EMA

2.3 均线的绘制

均线的绘制很简单,就是连接相邻两点:

def _draw_bar_picture(self, ix: int, bar: BarData):
    """绘制均线"""
    picture = QtGui.QPicture()
    painter = QtGui.QPainter(picture)

    for period, pen in self.lines.items():
        current_value = self.get_sma_value(ix, period)
        last_value = self.get_sma_value(ix - 1, period)

        # 只有当前值和前一个值都有效时才绘制
        if not np.isnan(current_value) and not np.isnan(last_value):
            painter.setPen(pen)
            painter.drawLine(
                QtCore.QPointF(ix - 1, last_value),
                QtCore.QPointF(ix, current_value)
            )

    painter.end()
    return picture

这样在图表上就能看到多条不同颜色的均线了。

三、SMA的实战用法:稳定的支撑阻力

现在你已经理解了SMA的原理,让我们看看在实战中如何使用。

3.1 用法一:SMA作为支撑阻力

这是SMA最经典的用法。

核心逻辑

  • 价格在SMA上方 → SMA是支撑

  • 价格在SMA下方 → SMA是阻力

而且周期越长,支撑阻力作用越强:

  • SMA5/10 → 短期支撑阻力

  • SMA20/30 → 中期支撑阻力

  • SMA60/120 → 长期支撑阻力

在我们的代码中,会自动识别最近的支撑阻力:

# 寻找最近的支撑
nearest_support = None
min_distance = float('inf')

for period, sma_val in sma_values.items():
    if sma_val < current_price:  # SMA在价格下方
        distance = abs(current_price - sma_val) / current_price * 100
        if distance < min_distance:
            nearest_support = (period, sma_val, distance)

实战建议

  • 价格回踩SMA支撑 → 买入机会

  • 价格反弹至SMA阻力 → 卖出机会

  • SMA被突破后,支撑变阻力,阻力变支撑

3.2 用法二:SMA排列判断趋势

这就是经典的"多头排列"和"空头排列"。

多头排列

快线(SMA5) > 中线(SMA10) > 慢线(SMA20) > 价格

说明短期、中期、长期趋势都向上,是稳定的上升趋势。

空头排列

快线(SMA5) < 中线(SMA10) < 慢线(SMA20) < 价格

说明各周期趋势都向下,是稳定的下降趋势。

在代码中的判断:

if len(periods) >= 3:
    fast_sma = sma_values[periods[0]]   # 快线
    mid_sma = sma_values[periods[1]]    # 中线
    slow_sma = sma_values[periods[2]]   # 慢线

    if fast_sma > mid_sma > slow_sma:
        return "SMA多头排列 - 稳定上升趋势"
    elif fast_sma < mid_sma < slow_sma:
        return "SMA空头排列 - 稳定下降趋势"
    else:
        return "SMA震荡排列 - 方向不明"

实战要点

  • 多头排列 → 回调做多,不做空

  • 空头排列 → 反弹做空,不做多

  • 震荡排列 → 等待排列形成

3.3 用法三:SMA散度判断趋势强度

均线之间的距离(散度)反映趋势强度。

# 计算SMA间散度
ma_spread = abs(fast_sma - slow_sma) / slow_sma * 100

if ma_spread > 3.5:
    return "SMA散度大 - 趋势强劲且稳定"
elif ma_spread > 2.0:
    return "SMA散度中等 - 趋势明确"
else:
    return "SMA散度小 - 趋势较弱或整理中"

散度的含义

  • 散度扩大 → 趋势加速

  • 散度稳定 → 趋势持续

  • 散度缩小 → 趋势减弱

  • 散度极小(粘合)→ 变盘在即

3.4 用法四:SMA的黄金交叉与死亡交叉

这是均线交叉的经典信号。

黄金交叉

  • 快线从下向上穿过慢线

  • 短期趋势转强

  • 买入信号

死亡交叉

  • 快线从上向下穿过慢线

  • 短期趋势转弱

  • 卖出信号

代码检测:

# 检测黄金交叉
if prev_fast <= prev_slow and curr_fast > curr_slow:
    return "SMA黄金交叉 - 稳定看涨信号"

# 检测死亡交叉
elif prev_fast >= prev_slow and curr_fast < curr_slow:
    return "SMA死亡交叉 - 稳定看跌信号"

关键点:SMA的交叉比EMA慢,但更可靠,假信号更少。

四、EMA的实战用法:敏感的趋势跟踪

EMA和SMA的用法类似,但有自己的特点。

4.1 用法一:EMA作为动态支撑阻力

EMA的支撑阻力比SMA更灵活。

EMA的特点

  • 对价格变化更敏感

  • 支撑阻力会随价格移动而快速调整

  • 更适合短线交易

在代码中,我们对不同周期的EMA设置了不同的阈值:

def get_ema_thresholds_and_advice(period, distance, is_support=True):
    """根据EMA周期返回阈值和建议"""
    if period <= 20:  # 快线
        close_threshold = 0.6  # EMA的阈值比SMA更小
        if distance < close_threshold:
            return "距离快线EMA支撑极近 - 短线反弹信号强烈"
    elif period <= 60:  # 中线
        close_threshold = 1.0
        if distance < close_threshold:
            return "距离中线EMA支撑很近 - 中期趋势支撑强劲"
    else:  # 慢线
        close_threshold = 1.5
        if distance < close_threshold:
            return "距离慢线EMA支撑很近 - 长期趋势关键支撑"

注意EMA的阈值比SMA小,因为EMA更敏感。

4.2 用法二:EMA的早期交叉信号

EMA最大的优势就是信号更早

在同样的市场变化下:

  • SMA交叉可能需要3-5天

  • EMA交叉可能只需要1-2天

代码中会标注这是"早期"信号:

# EMA黄金交叉
if prev_fast <= prev_slow and curr_fast > curr_slow:
    return "EMA黄金交叉 - 早期看涨信号"  # 注意是"早期"

# EMA死亡交叉
elif prev_fast >= prev_slow and curr_fast < curr_slow:
    return "EMA死亡交叉 - 早期看跌信号"

实战经验

  • EMA交叉 → 准备建仓

  • SMA交叉 → 确认加仓

  • 两者共振 → 重仓

4.3 用法三:EMA收敛预警变盘

EMA比SMA更早发现收敛。

# EMA极度收敛
ema_compression = abs(fast_ema - slow_ema) / slow_ema * 100

if ema_compression < 0.5:  # 注意阈值比SMA的0.8更小
    return "EMA极度收敛 - 重大变盘在即"
elif ema_compression < 1.0:
    return "EMA收敛中 - 准备捕捉早期突破"

当EMA极度收敛时,往往预示着大的行情即将启动。

4.4 用法四:EMA趋势强度判断

通过EMA的斜率判断趋势强度:

# 计算EMA斜率
slope = (curr_ema - prev_ema) / prev_ema * 100

if slope > 0.5:
    return "EMA强势上升 - 积极做多"
elif slope < -0.5:
    return "EMA强势下降 - 积极做空"
elif abs(slope) < 0.15:
    return "EMA横盘整理 - 等待方向明确"

EMA的斜率变化比SMA更明显,更容易捕捉趋势强度变化。

五、SMA vs EMA:如何选择?

到底用SMA还是EMA?这是很多人的困惑。

5.1 SMA的优势

稳定性强

  • 假信号少

  • 支撑阻力可靠

  • 适合中长期趋势判断

适用场景

  • 日线及以上周期

  • 震荡市场

  • 需要稳定信号时

推荐周期

  • SMA5, SMA10, SMA20 - 短期

  • SMA60, SMA120 - 中长期

5.2 EMA的优势

反应灵敏

  • 信号更早

  • 能快速捕捉转折

  • 适合短线交易

适用场景

  • 短周期(5分钟、15分钟、60分钟)

  • 趋势市场

  • 需要快速反应时

推荐周期

  • EMA9, EMA12, EMA26 - 常用于MACD

  • EMA50, EMA200 - 中长期

5.3 组合使用策略

我自己的做法是两者结合

短期看EMA(12, 26)→ 捕捉入场时机
中期看SMA(20, 60)→ 确认趋势方向
长期看SMA(120, 250)→ 判断大趋势

这样既能早发现机会(EMA),又能降低假信号(SMA)。

六、多均线系统:葛兰碧八大法则

均线真正的威力在于多均线系统。

6.1 经典的三均线系统

最常用的是5-10-20日均线系统:

fast_sma = sma_values[5]    # 快线
mid_sma = sma_values[10]    # 中线
slow_sma = sma_values[20]   # 慢线

买入信号

  1. 价格站上所有均线

  2. 快线上穿中线(中期确认)

  3. 快线上穿慢线(长期确认)

  4. 价格回踩快线获得支撑

卖出信号

  1. 价格跌破所有均线

  2. 快线下穿中线

  3. 快线下穿慢线

  4. 价格反弹至快线遇阻

6.2 葛兰碧八大法则(简化版)

葛兰碧八大法则太复杂,我总结成四个核心原则:

原则1:均线方向

  • 均线向上 → 只做多

  • 均线向下 → 只做空

原则2:价格与均线位置

  • 价格在均线上 → 回调做多

  • 价格在均线下 → 反弹做空

原则3:支撑阻力作用

  • 回踩不破 → 支撑有效,继续持有

  • 突破失败 → 阻力有效,继续持有

原则4:发散收敛

  • 均线发散 → 趋势加速,持有

  • 均线收敛 → 准备变盘,减仓

在代码中体现:

if current_price > fast_sma > mid_sma > slow_sma:
    return "完美多头格局 - 强势做多"
elif current_price < fast_sma < mid_sma < slow_sma:
    return "完美空头格局 - 强势做空"

6.3 均线粘合与突破

当多条均线粘合(距离很近)时,往往预示着大行情。

# 检查均线粘合
ma_compression = abs(fast_sma - slow_sma) / slow_sma * 100

if ma_compression < 0.8:  # SMA
    return "SMA极度收敛 - 重大趋势变盘在即"
elif ma_compression < 0.5:  # EMA
    return "EMA极度收敛 - 重大变盘在即"

实战策略

  • 均线粘合时 → 减仓观望

  • 放量突破时 → 顺势重仓

  • 突破方向 = 未来趋势

七、均线的智能解读

在ATMQuant系统中,均线有完整的智能解读。

7.1 排列状态分析

系统会自动识别均线排列:

SMA状态: 多头排列
趋势强度: 稳定上升(SMA确认性更强)
SMA散度: 大 - 趋势强劲且稳定

或者:

EMA状态: 多头排列
趋势强度: 强势上升(EMA敏感反应)
EMA散度: 大 - 趋势加速(EMA快速发散)

7.2 价格位置分析

系统会告诉你价格在均线的什么位置:

价格位置: 全部SMA之上
市场状态: 强势多头(SMA全面支撑)

或者:

价格位置: 2/3 EMA之上
市场状态: 震荡或转换期(关注EMA突破)

7.3 交叉信号识别

系统会自动检测交叉:

SMA黄金交叉 - 稳定看涨信号
价格上穿SMA(20) - 稳定做多信号

或者:

EMA黄金交叉 - 早期看涨信号
价格上穿EMA(12) - 敏感做多信号

7.4 支撑阻力提示

系统会找出最近的支撑阻力并给出建议:

最近支撑: SMA(20) 3850.00 (1.2%)
距离中线SMA支撑很近 - 重要中期买入位

最近阻力: SMA(60) 3950.00 (2.8%)
接近中线SMA阻力 - 中期获利了结位

7.5 趋势强度评估

系统会分析均线的斜率:

SMA趋势: 稳定上升
操作建议: 顺势做多,SMA回踩是良机

或者:

EMA趋势: 强势上升
操作建议: 积极做多,EMA回踩加仓

7.6 策略建议

系统会给出完整的策略建议:

稳定多头格局: 价格>SMA5>SMA10>SMA20
策略: 强势做多,SMA5回踩加仓,SMA10为核心支撑

看,现在均线不再是几条冷冰冰的线,而是一个完整的趋势分析和交易决策系统!

八、实战经验与避坑指南

说几个实际用的时候遇到的坑。

第一个是均线周期的选择。刚开始我也是网上看到别人用什么周期就跟着用,比如5-10-20日线。后来发现不同品种、不同周期需要不同的参数。螺纹钢波动大,5日线太敏感;而铜的波动小,可能需要更短的周期。现在我的做法是:先用默认参数,然后根据品种特性调整,直到找到最适合的组合。

还有个事,就是均线的滞后性。均线本质上是价格的滞后指标,等均线交叉的时候,价格往往已经走了一段。这个没办法完全避免,但可以优化:用EMA代替SMA,或者结合其他先行指标(如MACD)。我自己的做法是:EMA给信号,SMA做确认,MACD看动能,三者配合。

对了,关于均线的假突破。震荡市中,价格经常上穿下穿均线,来回打脸。遇到这种情况怎么办?我的经验是看量和看级别。放量突破才是真突破;日线突破比小时线可靠。还有就是结合布林带,如果布林带收口(波动率低),均线突破往往是假的。

说说均线粘合的问题。很多书上说均线粘合后必有大行情,但实际上并不一定。有时候粘合后继续横盘,有时候假突破后回来。我踩过很多次坑才总结出:粘合只是告诉你"准备好",真正的信号是放量突破。没有放量的突破,宁可错过也不要冲进去。

还有一点要注意,就是不同周期均线的冲突。有时候日线多头排列,但小时线空头排列,这时候到底做多还是做空?我的原则是:大周期定方向,小周期找时机。如果日线多头排列,即使小时线短期回调,也只做多不做空,在小时线找回踩买点。

最后说说多均线的使用。有些人恨不得画十几条均线,结果图上密密麻麻看不清。其实三条就够了:快线(抓时机)、中线(看趋势)、慢线(定方向)。我自己用的是SMA20-60-100或者EMA9-21-60,简单明了。

对于SMA和EMA的选择,我的实战经验是:日线及以上用SMA,小时线及以下用EMA。为什么?因为日线以上需要稳定性,小时线以下需要灵敏性。当然这不是绝对的,关键看你的交易风格。如果你做短线,全部用EMA;如果你做中长线,全部用SMA也行。

九、写在最后

到这里,均线的核心内容基本讲完了。从SMA和EMA的本质区别,到支撑阻力、排列形态、交叉信号,再到多均线系统和葛兰碧法则,均线虽然简单,但用好了威力巨大。

最重要的就是要理解:均线是趋势的体现,也是支撑阻力的参考。顺着均线方向做,在均线支撑处买,在均线阻力处卖,就这么简单。

记住几个关键点:

  1. SMA稳定,EMA敏感,根据需要选择

  2. 多头排列做多,空头排列做空,不要逆势

  3. 均线粘合预示变盘,放量突破跟进

  4. 大周期定方向,小周期找时机

  5. 三条均线就够了,不要贪多

前面六篇我们讲了RSI、布林带、MACD、DMI、均线,基本覆盖了动量、波动率、趋势方向、趋势强度这几个维度。这些指标组合起来,就是一个完整的交易决策系统。

不过说实话,还缺最后一块拼图——成交量。所有的价格分析,如果没有量的确认,都是不完整的。所以下一篇,我们就来深度解码成交量,从量价关系到放量缩量,从堆量到天量,带你真正理解"量在价先"的含义。

先写到这,有问题欢迎留言交流。


本文是《量化指标解码》系列文章的第6篇,完整代码已开源至GitHub:https://github.com/seasonstar/atmquant

本文内容仅供学习交流,不构成任何投资建议。交易有风险,投资需谨慎。


📌 相关标签

#量化交易#技术指标#均线系统#SMA#EMA


加入「量策堂·AI算法指标策略」

想系统性掌握策略研发、指标可视化与回测优化?

加入我的知识星球,获得持续、体系化的成长支持:

图片


往期文章回顾

《量化指标解码》系列

《以AI量化为生》系列(交易系统开发)


Logo

加入社区!打开量化的大门,首批课程上线啦!

更多推荐