第四节:技术指标计算——移动平均线、RSI、布林带、MACD、OBV
技术指标这东西,说白了就是给价格数据“化妆”。原始K线图看起来乱糟糟的,指标能帮我们提炼出趋势、动量、波动率这些关键信息。我个人习惯,在轮动模型里不会堆砌太多指标,选三四个互补的就够了。
今天咱们把五个最常用的指标过一遍。我会把计算公式、代码实现、以及实战中容易踩的坑都讲清楚。
4.1 移动平均线:SMA 与 EMA
移动平均线是最基础的指标。它把价格“抹平”,让我们看清趋势方向。
简单移动平均线(SMA)
SMA 就是取最近 N 天的收盘价,算个算术平均。公式很简单:
SMA = (P₁ + P₂ + ... + Pₙ) / N
举个例子,5日SMA就是最近5天收盘价加起来除以5。代码实现:
def sma(close, window=20):
return close.rolling(window=window).mean()
嗯,这里要注意:SMA 对每个数据点一视同仁。也就是说,10天前的价格和昨天的价格权重一样。这其实不太合理——昨天的价格显然比10天前更重要。
指数移动平均线(EMA)
EMA 解决了这个问题。它给近期的价格更高的权重。公式稍微复杂一点:
EMA_today = (Price_today × α) + (EMA_yesterday × (1 - α))
其中 α = 2 / (N + 1)
你看,今天的EMA由两部分组成:今天的价格乘以一个权重α,加上昨天的EMA乘以(1-α)。α越大,对近期价格反应越敏感。
def ema(close, window=20):
return close.ewm(span=window, adjust=False).mean()
4.2 相对强弱指标(RSI)
RSI 衡量的是“涨的力度”和“跌的力度”谁更强。取值范围0到100,一般认为70以上超买,30以下超卖。
计算分三步:
- 计算每日涨跌幅:今天收盘 - 昨天收盘
- 分别计算N天内平均涨幅和平均跌幅
- RSI = 100 - 100 / (1 + 平均涨幅/平均跌幅)
def rsi(close, window=14):
delta = close.diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(window=window).mean()
avg_loss = loss.rolling(window=window).mean()
rs = avg_gain / avg_loss
return 100 - (100 / (1 + rs))
4.3 布林带(Bollinger Bands)
布林带由三条线组成:中轨是SMA,上下轨分别是中轨加减两倍标准差。它告诉我们价格相对于历史波动率的位置。
def bollinger_bands(close, window=20, num_std=2):
sma = close.rolling(window=window).mean()
std = close.rolling(window=window).std()
upper = sma + num_std * std
lower = sma - num_std * std
return sma, upper, lower
布林带的核心思想:价格大概率在上下轨之间运行。当价格触及上轨,可能超买;触及下轨,可能超卖。但要注意——强势行情里,价格会沿着上轨一直走,这时候做空就惨了。
4.4 MACD 指标
MACD 由三部分组成:快线(DIF)、慢线(DEA)、柱状图(MACD柱)。它本质上是两条EMA的差值。
计算步骤:
- 计算12日EMA和26日EMA
- DIF = 12日EMA - 26日EMA
- DEA = DIF的9日EMA
- MACD柱 = (DIF - DEA) × 2
def macd(close, fast=12, slow=26, signal=9):
ema_fast = close.ewm(span=fast, adjust=False).mean()
ema_slow = close.ewm(span=slow, adjust=False).mean()
dif = ema_fast - ema_slow
dea = dif.ewm(span=signal, adjust=False).mean()
macd_bar = (dif - dea) * 2
return dif, dea, macd_bar
MACD 最常用的信号是金叉和死叉。DIF上穿DEA是金叉,看涨;下穿是死叉,看跌。但说实话,金叉死叉在震荡市里准确率不高。
4.5 成交量指标(OBV)
OBV 把成交量和价格结合起来。它的逻辑很简单:价格上涨时,成交量是“正”的;价格下跌时,成交量是“负”的。OBV 就是把这些正负成交量累加起来。
def obv(close, volume):
obv = volume.copy()
obv[close.diff() > 0] = volume[close.diff() > 0]
obv[close.diff() < 0] = -volume[close.diff() < 0]
obv[close.diff() == 0] = 0
return obv.cumsum()
OBV 的核心用法是看“背离”。如果价格在涨,但OBV在跌,说明上涨没有成交量支持,可能是虚涨。反过来,价格在跌,OBV在涨,说明有人在悄悄吸筹。
4.6 知识体系总览
下面这张图把五个指标的核心逻辑串起来了。你可以看到,每个指标解决一个不同的问题:
4.7 实战中的组合用法
指标不是越多越好。我见过有人一个策略里塞了十几个指标,结果信号互相矛盾,根本没法交易。我的建议是:
- 趋势类选一个:SMA 或 EMA,二选一就行
- 动量类选一个:RSI 或 MACD,看个人偏好
- 波动率类选一个:布林带
- 量价类选一个:OBV
这样四个指标各司其职,互不重叠。你想想看,如果趋势和动量都看涨,波动率也支持,成交量也在配合,那这个信号的可靠性就高多了。
好了,技术指标的计算就讲到这里。这些代码你直接复制到自己的回测框架里就能用。记住,指标只是工具,关键还是理解它背后的逻辑——为什么涨?为什么跌?成交量在说什么?把这些想明白了,指标才能为你所用。