第四节:技术指标计算——MA/EMA、RSI、布林带、MACD
技术指标这东西,说白了就是给价格数据“化妆”。
裸K线看起来太素了,加上几条线、几个柱状图,趋势和信号就一目了然。我个人习惯把技术指标分成两类:一类是趋势跟踪型,比如移动平均线、MACD;另一类是震荡型,比如RSI、布林带。两者搭配使用,效果往往更好。
核心观点:技术指标不是预测未来的水晶球,而是帮你描述当前市场状态的工具。我见过太多人沉迷于指标的金叉死叉,结果亏得一塌糊涂。记住,指标只是辅助,策略逻辑才是根本。
4.1 移动平均线:MA与EMA
移动平均线是最基础的指标,没有之一。它的作用就是平滑价格数据,过滤掉短期噪音。
简单移动平均线(MA),就是取N天的收盘价算个平均值。公式很简单:
MA(N) = (P₁ + P₂ + ... + Pₙ) / N
举个例子,5日MA就是最近5天收盘价的平均数。每天滑动窗口,去掉最旧的一天,加入最新的一天。
指数移动平均线(EMA),则给近期的价格更高的权重。我更喜欢用EMA,因为它对价格变化反应更灵敏。
EMA(t) = α × P(t) + (1 - α) × EMA(t-1)
其中 α = 2 / (N + 1)
嗯,这里要注意:EMA的计算需要初始值。通常第一个EMA值直接用第一个收盘价,或者用前几天的MA代替。
我的经验:做短线交易时,我习惯用EMA而不是MA。EMA能更快捕捉到趋势变化。但如果你做长线持仓,MA反而更稳定,不容易被假突破骗线。
4.2 相对强弱指标(RSI)
RSI是用来衡量价格涨跌力度的指标。它告诉你当前市场是超买还是超卖。
计算RSI分三步:
- 计算每日涨跌幅:涨了记为正,跌了记为0;跌了记为负的绝对值,涨了记为0
- 计算N日平均涨幅和平均跌幅(通常用14天)
- RSI = 100 - 100 / (1 + 平均涨幅/平均跌幅)
说白了,RSI就是比较“涨的平均力度”和“跌的平均力度”。如果涨的力度远大于跌的力度,RSI就高,说明市场过热。
def calculate_rsi(prices, period=14):
deltas = [prices[i] - prices[i-1] for i in range(1, len(prices))]
gains = [d if d > 0 else 0 for d in deltas]
losses = [-d if d < 0 else 0 for d in deltas]
avg_gain = sum(gains[:period]) / period
avg_loss = sum(losses[:period]) / period
rsi_values = []
for i in range(period, len(deltas)):
avg_gain = (avg_gain * (period - 1) + gains[i]) / period
avg_loss = (avg_loss * (period - 1) + losses[i]) / period
rs = avg_gain / avg_loss if avg_loss != 0 else float('inf')
rsi = 100 - 100 / (1 + rs)
rsi_values.append(rsi)
return rsi_values
避坑指南:我曾经在RSI低于30时盲目做多,结果被深度套牢。为什么?因为RSI在强趋势行情中会长时间停留在超买/超卖区域。记住:RSI在震荡行情中好用,在趋势行情中容易失效。
4.3 布林带(Bollinger Bands)
布林带由三条线组成:中轨(MA)、上轨(中轨+2倍标准差)、下轨(中轨-2倍标准差)。
它的核心思想是:价格在大多数时间(约95%)会落在上下轨之间。当价格突破上轨或下轨时,往往意味着极端行情。
def bollinger_bands(prices, period=20, num_std=2):
ma = [sum(prices[i-period:i]) / period for i in range(period, len(prices)+1)]
std = []
for i in range(period, len(prices)+1):
s = sum((prices[i-period+j] - ma[i-period])**2 for j in range(period))
std.append((s / period)**0.5)
upper = [ma[i] + num_std * std[i] for i in range(len(ma))]
lower = [ma[i] - num_std * std[i] for i in range(len(ma))]
return ma, upper, lower
你想想看,布林带最妙的地方在于:带宽会变化。带宽收窄时,说明市场在蓄力,即将爆发;带宽扩张时,说明趋势正在加速。
我的用法:布林带收窄+价格突破上轨,我会追多。但前提是突破时成交量要放大。没有成交量的突破,十有八九是假突破。我在实盘中吃过这个亏,后来就加了成交量过滤条件。
4.4 MACD指标
MACD全称是“指数平滑异同移动平均线”,名字很唬人,其实逻辑很简单。
它由三部分组成:
- DIF线:快线(12日EMA)减去慢线(26日EMA)
- DEA线:DIF线的9日EMA
- MACD柱:DIF减去DEA,乘以2
说白了,MACD就是在比较短期趋势和长期趋势的差距。当短期趋势跑赢长期趋势时,DIF为正,说明多头占优。
def macd(prices, fast=12, slow=26, signal=9):
# 计算EMA
def ema(data, period):
alpha = 2 / (period + 1)
result = [data[0]]
for i in range(1, len(data)):
result.append(alpha * data[i] + (1-alpha) * result[-1])
return result
ema_fast = ema(prices, fast)
ema_slow = ema(prices, slow)
dif = [ema_fast[i] - ema_slow[i] for i in range(len(prices))]
dea = ema(dif, signal)
macd_bar = [2 * (dif[i] - dea[i]) for i in range(len(prices))]
return dif, dea, macd_bar
关键信号:
- DIF上穿DEA(金叉)→ 买入信号
- DIF下穿DEA(死叉)→ 卖出信号
- MACD柱由负转正 → 多头动能增强
- 顶背离(价格新高但MACD没新高)→ 警惕反转
为什么会发生背离?因为价格虽然还在涨,但上涨的动能已经跟不上了。就像一个人跑得越来越慢,虽然还在往前,但随时可能停下来。
4.5 知识体系总览
下面这张图,是我梳理的本章知识结构。建议你保存下来,写代码时对照着看。
4.6 实战中的组合用法
单独用任何一个指标,效果都有限。我习惯把几个指标组合起来:
| 指标组合 | 适用场景 | 信号确认 |
|---|---|---|
| MA + RSI | 震荡行情 | 价格回踩MA且RSI超卖 → 做多 |
| 布林带 + MACD | 趋势行情 | 价格突破布林带上轨 + MACD金叉 → 追多 |
| EMA + 布林带 | 趋势跟踪 | EMA多头排列 + 布林带向上开口 → 持有 |
重要提醒:指标组合不是越多越好。我见过有人一个界面放七八个指标,结果信号互相矛盾,根本没法交易。我个人建议:趋势指标选1个,震荡指标选1个,再加一个成交量指标,三个足矣。
好了,技术指标的计算和用法就讲到这里。代码都给你了,建议你拿到真实数据上跑一跑,看看不同参数下指标的表现。实践出真知,光看不练是学不会的。