3、技术指标计算:移动平均线(SMA/EMA)、相对强弱指标(RSI)、布林带(Bollinger Bands)、MACD指标
技术指标这东西,说白了就是给价格数据「化妆」。原始的价格走势太粗糙,我们需要一些数学工具来提炼规律。我个人习惯把指标分为两类:一类是趋势跟踪型,比如均线、MACD;另一类是震荡型,比如RSI、布林带。今天咱们就把这四个最常用的指标,从原理到代码,彻底讲透。
3.1 移动平均线:SMA 与 EMA
移动平均线是最基础的指标,没有之一。它的核心思想就是「平滑」——把短期的噪音过滤掉,看清长期趋势。
3.1.1 简单移动平均线(SMA)
SMA 的计算很简单:取最近 N 天的收盘价,求算术平均值。公式如下:
SMA = (P₁ + P₂ + ... + Pₙ) / N
其中 P 是收盘价,N 是周期数。比如 20 日 SMA,就是最近 20 个收盘价的平均值。
我在项目中遇到过一个问题:SMA 对每个数据点一视同仁,这其实不太合理。你想想看,昨天的价格和 20 天前的价格,对当前趋势的影响能一样吗?所以就有了 EMA。
3.1.2 指数移动平均线(EMA)
EMA 给近期的数据更高的权重。公式稍微复杂一点:
EMA_today = (Price_today × α) + (EMA_yesterday × (1 - α))
其中 α = 2 / (N + 1),N 是周期数。比如 20 日 EMA,α = 2 / 21 ≈ 0.095。
嗯,这里要注意:EMA 的第一个值通常用 SMA 来初始化。我建议直接用 pandas 的 ewm 函数,省得自己手算。
实战经验:我个人习惯用 EMA 而不是 SMA。原因很简单——EMA 对价格变化反应更快。在趋势行情里,EMA 能帮你早一步进场;在震荡行情里,虽然信号会多一些,但配合其他指标可以过滤掉。
3.1.3 代码实现
import pandas as pd
import numpy as np
def calculate_sma(data, window=20):
"""计算简单移动平均线"""
return data['close'].rolling(window=window).mean()
def calculate_ema(data, window=20):
"""计算指数移动平均线"""
return data['close'].ewm(span=window, adjust=False).mean()
# 使用示例
df['SMA_20'] = calculate_sma(df, 20)
df['EMA_20'] = calculate_ema(df, 20)
小技巧:pandas 的 rolling() 函数默认是「右对齐」的。也就是说,第 20 天的 SMA 值,用的是第 1 天到第 20 天的数据。这在回测中不会引入未来信息,放心用。
3.2 相对强弱指标(RSI)
RSI 是用来衡量价格「超买」或「超卖」的指标。它的取值范围是 0 到 100。一般认为,RSI 高于 70 是超买,低于 30 是超卖。
公式其实不复杂:
RSI = 100 - (100 / (1 + RS))
RS = 平均上涨幅度 / 平均下跌幅度
这里的「平均」通常用 SMA 或 EMA 来计算。我个人习惯用 Wilder 的平滑方法,也就是用 EMA 来计算平均涨跌幅。
3.2.1 计算步骤
- 计算每日价格变化:delta = close - close.shift(1)
- 分离上涨和下跌:gain = max(delta, 0),loss = abs(min(delta, 0))
- 计算平均上涨和平均下跌(用 EMA 平滑)
- 计算 RS = avg_gain / avg_loss
- 计算 RSI = 100 - 100 / (1 + RS)
3.2.2 代码实现
def calculate_rsi(data, window=14):
"""计算相对强弱指标"""
delta = data['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.ewm(span=window, adjust=False).mean()
avg_loss = loss.ewm(span=window, adjust=False).mean()
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
return rsi
df['RSI_14'] = calculate_rsi(df, 14)
避坑指南:我曾经在回测中直接用 RSI 低于 30 就买入,结果亏得很惨。为什么?因为在强下跌趋势中,RSI 可以长期低于 30,你抄底抄在半山腰。后来我加了趋势过滤——只有在大周期均线向上的时候,才用 RSI 超卖信号进场。
3.3 布林带(Bollinger Bands)
布林带由三条线组成:中轨(通常是 20 日 SMA)、上轨(中轨 + 2 倍标准差)、下轨(中轨 - 2 倍标准差)。
它的核心思想是:价格在正常情况下会落在上下轨之间。当价格突破上轨或下轨时,意味着波动加剧,可能发生趋势反转或延续。
3.3.1 计算公式
中轨 = SMA(close, 20)
上轨 = 中轨 + 2 × std(close, 20)
下轨 = 中轨 - 2 × std(close, 20)
其中 std 是标准差。注意,这里用的是「样本标准差」,pandas 默认就是样本标准差,所以直接用 rolling().std() 就行。
3.3.2 代码实现
def calculate_bollinger_bands(data, window=20, num_std=2):
"""计算布林带"""
df = data.copy()
df['middle'] = df['close'].rolling(window=window).mean()
df['std'] = df['close'].rolling(window=window).std()
df['upper'] = df['middle'] + num_std * df['std']
df['lower'] = df['middle'] - num_std * df['std']
return df[['middle', 'upper', 'lower']]
bands = calculate_bollinger_bands(df)
df['BB_upper'] = bands['upper']
df['BB_middle'] = bands['middle']
df['BB_lower'] = bands['lower']
个人经验:布林带最常用的策略是「回归均值」——当价格触及下轨时买入,触及上轨时卖出。但要注意,在强趋势行情中,价格可以沿着上轨或下轨「爬行」很久。我一般会结合 ADX 指标来判断当前是趋势行情还是震荡行情。
3.4 MACD 指标
MACD 的全称是「指数平滑异同移动平均线」。它由三部分组成:
- DIF 线:快线(12 日 EMA)减去慢线(26 日 EMA)
- DEA 线:DIF 的 9 日 EMA
- MACD 柱:(DIF - DEA) × 2
MACD 的核心逻辑是:当快线向上穿过慢线(金叉),是买入信号;当快线向下穿过慢线(死叉),是卖出信号。
3.4.1 计算步骤
- 计算 12 日 EMA 和 26 日 EMA
- DIF = EMA_12 - EMA_26
- DEA = DIF 的 9 日 EMA
- MACD 柱 = (DIF - DEA) × 2
3.4.2 代码实现
def calculate_macd(data, fast=12, slow=26, signal=9):
"""计算MACD指标"""
df = data.copy()
df['ema_fast'] = df['close'].ewm(span=fast, adjust=False).mean()
df['ema_slow'] = df['close'].ewm(span=slow, adjust=False).mean()
df['dif'] = df['ema_fast'] - df['ema_slow']
df['dea'] = df['dif'].ewm(span=signal, adjust=False).mean()
df['macd'] = 2 * (df['dif'] - df['dea'])
return df[['dif', 'dea', 'macd']]
macd = calculate_macd(df)
df['MACD_DIF'] = macd['dif']
df['MACD_DEA'] = macd['dea']
df['MACD_HIST'] = macd['macd']
使用技巧:MACD 的金叉和死叉在震荡行情中会频繁出现,导致很多假信号。我建议只看「零轴上方」的金叉和「零轴下方」的死叉。零轴上方代表多头市场,金叉的可靠性更高;零轴下方代表空头市场,死叉的可靠性更高。
3.5 知识体系总览
下面这张图展示了四个指标的核心逻辑和它们之间的关系:
3.6 实战中的组合用法
单独使用一个指标,效果往往一般。我习惯把多个指标组合起来,形成「信号共振」。
| 组合方式 | 买入条件 | 卖出条件 | 适用场景 |
|---|---|---|---|
| EMA + RSI | 价格在 EMA 上方 + RSI 低于 30 | 价格跌破 EMA + RSI 高于 70 | 趋势中的回调 |
| 布林带 + MACD | 价格触及下轨 + MACD 金叉 | 价格触及上轨 + MACD 死叉 | 震荡行情 |
| EMA 双线 + RSI | 快线上穿慢线 + RSI 在 40-60 之间 | 快线下穿慢线 + RSI 在 40-60 之间 | 趋势启动 |
重要提醒:指标组合不是越多越好。我曾经试过把 5 个指标叠加在一起,结果信号少得可怜,一年都开不了几次仓。后来我精简到 2-3 个核心指标,效果反而更好。记住:信号越复杂,样本内拟合越严重,实盘表现往往越差。
好了,技术指标的计算和用法就讲到这里。这些代码你直接复制到自己的回测框架里就能用。记住,指标只是工具,真正重要的是你对市场的理解和对风险的控制。
公众号:蓝海资料掘金营,微信deep3321