4、技术指标计算:移动平均线(MA)、指数移动平均线(EMA)、相对强弱指标(RSI)、布林带(Bollinger Bands)、MACD指标、KDJ指标

技术指标,说白了就是给K线图装上「仪表盘」。我刚开始做量化的时候,觉得裸K线图就够了。后来发现,没有这些指标辅助,很多趋势和拐点根本看不出来。今天咱们就把最常用的六个指标,一个一个掰开揉碎了讲清楚。

核心观点:技术指标不是圣杯,而是工具。它们帮你把价格数据「翻译」成更直观的信号。但记住,任何指标都有滞后性,别迷信单一指标。

4.1 移动平均线(MA)

移动平均线,就是过去N天收盘价的平均值。它平滑了价格波动,让你看清趋势方向。

计算公式:

MA(N) = (P₁ + P₂ + ... + Pₙ) / N

其中P₁到Pₙ是最近N天的收盘价。

代码实现:

import pandas as pd

def calculate_ma(data, window=20):
    """
    计算移动平均线
    data: DataFrame,必须包含'close'列
    window: 窗口大小,默认20日
    """
    data[f'MA_{window}'] = data['close'].rolling(window=window).mean()
    return data

# 使用示例
df = pd.DataFrame({'close': [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]})
df = calculate_ma(df, window=5)
print(df)

实战经验:我个人习惯用MA5、MA20、MA60三条线。MA5代表短期趋势,MA20是中期生命线,MA60是牛熊分界线。我在项目中遇到过,当MA5上穿MA20形成「金叉」,短期上涨概率较大;反之「死叉」则要小心。

小技巧:均线周期不是固定的。做短线交易,用5日、10日均线;做中线,用20日、60日;做长线,用120日、250日。别死板套用。

4.2 指数移动平均线(EMA)

EMA和MA的区别在于,EMA给近期的价格更高的权重。说白了,它比MA更「敏感」,能更快反映价格变化。

计算公式:

EMA(N) = (P × α) + (前一日EMA × (1 - α))
其中 α = 2 / (N + 1)

代码实现:

def calculate_ema(data, window=20):
    """
    计算指数移动平均线
    """
    data[f'EMA_{window}'] = data['close'].ewm(span=window, adjust=False).mean()
    return data

# 使用示例
df = calculate_ema(df, window=5)
print(df)

嗯,这里要注意:EMA的初始值通常用第一个收盘价代替。所以刚开始几天的EMA可能不太准,等数据多了就稳定了。

4.3 相对强弱指标(RSI)

RSI衡量的是价格上涨和下跌的力度对比。它告诉你,当前市场是「超买」还是「超卖」。

计算公式:

RSI = 100 - (100 / (1 + RS))
RS = 平均上涨幅度 / 平均下跌幅度

代码实现:

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.rolling(window=window).mean()
    avg_loss = loss.rolling(window=window).mean()
    
    rs = avg_gain / avg_loss
    data['RSI'] = 100 - (100 / (1 + rs))
    return data

# 使用示例
df = calculate_rsi(df, window=14)
print(df)

避坑指南:我曾经以为RSI低于30就是买入信号,高于70就是卖出信号。结果吃了大亏。在强趋势行情中,RSI可以长时间在超买区或超卖区徘徊。记住:RSI在趋势行情中会失效,它更适合震荡行情。

4.4 布林带(Bollinger Bands)

布林带由三条线组成:中轨(MA)、上轨(中轨+2倍标准差)、下轨(中轨-2倍标准差)。它告诉你价格波动的「正常范围」在哪里。

计算公式:

中轨 = MA(N)
上轨 = 中轨 + k × 标准差
下轨 = 中轨 - k × 标准差
其中k通常取2

代码实现:

def calculate_bollinger(data, window=20, num_std=2):
    """
    计算布林带
    """
    data['BB_MID'] = data['close'].rolling(window=window).mean()
    data['BB_STD'] = data['close'].rolling(window=window).std()
    data['BB_UPPER'] = data['BB_MID'] + num_std * data['BB_STD']
    data['BB_LOWER'] = data['BB_MID'] - num_std * data['BB_STD']
    return data

# 使用示例
df = calculate_bollinger(df, window=20)
print(df[['close', 'BB_MID', 'BB_UPPER', 'BB_LOWER']])

你想想看,当价格触及上轨,说明波动异常大,可能回调;触及下轨,说明跌过头了,可能反弹。但别急着反向操作——价格贴着上轨走,说明趋势很强,做空就是找死。

4.5 MACD指标

MACD是「指数平滑异同移动平均线」的缩写。它由快线(DIF)、慢线(DEA)和柱状线(MACD柱)组成。

计算公式:

DIF = EMA(12) - EMA(26)
DEA = EMA(DIF, 9)
MACD柱 = (DIF - DEA) × 2

代码实现:

def calculate_macd(data, fast=12, slow=26, signal=9):
    """
    计算MACD指标
    """
    data['EMA_fast'] = data['close'].ewm(span=fast, adjust=False).mean()
    data['EMA_slow'] = data['close'].ewm(span=slow, adjust=False).mean()
    data['DIF'] = data['EMA_fast'] - data['EMA_slow']
    data['DEA'] = data['DIF'].ewm(span=signal, adjust=False).mean()
    data['MACD'] = 2 * (data['DIF'] - data['DEA'])
    return data

# 使用示例
df = calculate_macd(df)
print(df[['close', 'DIF', 'DEA', 'MACD']])

关键用法:当DIF上穿DEA形成「金叉」,是买入信号;下穿形成「死叉」,是卖出信号。但更重要的看背离——价格创新低,但DIF没创新低,这叫「底背离」,是强烈的反转信号。我在项目中靠这个抓过好几次大底。

4.6 KDJ指标

KDJ也叫随机指标,它比RSI更灵敏,适合捕捉短期拐点。

计算公式:

RSV = (收盘价 - 最近N天最低价) / (最近N天最高价 - 最近N天最低价) × 100
K = 2/3 × 前一日K + 1/3 × RSV
D = 2/3 × 前一日D + 1/3 × K
J = 3K - 2D

代码实现:

def calculate_kdj(data, n=9, k_factor=1/3, d_factor=1/3):
    """
    计算KDJ指标
    """
    low_n = data['low'].rolling(window=n).min()
    high_n = data['high'].rolling(window=n).max()
    
    data['RSV'] = (data['close'] - low_n) / (high_n - low_n) * 100
    
    data['K'] = 50  # 初始值
    data['D'] = 50  # 初始值
    
    for i in range(1, len(data)):
        data.loc[data.index[i], 'K'] = (1 - k_factor) * data.loc[data.index[i-1], 'K'] + k_factor * data.loc[data.index[i], 'RSV']
        data.loc[data.index[i], 'D'] = (1 - d_factor) * data.loc[data.index[i-1], 'D'] + d_factor * data.loc[data.index[i], 'K']
    
    data['J'] = 3 * data['K'] - 2 * data['D']
    return data

# 使用示例
df = calculate_kdj(df)
print(df[['close', 'K', 'D', 'J']])

KDJ的用法和RSI类似:K值低于20是超卖,高于80是超买。但J值更极端,低于0或高于100时,反转概率更大。我曾经用J值低于0这个条件,在2018年的大熊市中抓到过几次反弹,虽然没赚大钱,但至少没亏。

4.7 指标组合使用

单一指标容易出错,我建议组合使用。比如:

  • 趋势判断:用MA和MACD判断大方向
  • 买卖点:用RSI或KDJ找具体入场时机
  • 风险控制:用布林带判断价格是否异常

举个例子:当MA20向上,MACD金叉,RSI在50以上,说明多头趋势确立。这时候如果价格回踩布林带中轨,就是不错的买入机会。

我的习惯:先用MA看趋势方向,再用MACD确认趋势强度,最后用RSI或KDJ找具体买卖点。布林带用来设止损——价格跌破下轨,说明趋势可能反转,先出来看看。

4.8 知识体系总览

下面这张图帮你理清这六个指标的关系和用途:

技术指标知识体系 技术指标 趋势类指标 MA - 移动平均线 EMA - 指数移动平均线 MACD - 异同移动平均线 震荡类指标 RSI - 相对强弱指标 KDJ - 随机指标 布林带 - 波动率指标 使用建议 趋势类指标判断方向,震荡类指标找买卖点 至少选1个趋势类 + 1个震荡类组合使用

这六个指标,是量化选股最基础的工具。你不需要全部精通,但至少要熟练掌握两三个。我个人建议先从MA和RSI入手,这两个最容易理解,也最实用。等用熟了,再慢慢加MACD和布林带。

记住:指标是死的,市场是活的。别让指标牵着鼻子走,而是用它们来辅助你的判断。


公众号:蓝海资料掘金营,微信deep3321