Overlap:RMA(运行移动平均线)技术指标详解
一、RMA的定义
RMA(Running Moving Average,运行移动平均线) 也被称为 Wilder's Moving Average (威尔德移动平均线),是技术分析大师J. Welles Wilder在1978年出版的《技术交易系统新概念》(New Concepts in Technical Trading Systems)一书中引入的一种特殊移动平均线。

核心定位
RMA的本质其实是一种指数移动平均线(EMA),但它采用了一个特定的平滑系数公式。你可以把它理解为"威尔德版本的EMA",而它最著名的应用场景,就是作为RSI(相对强弱指数)指标的核心计算组件。
RMA与EMA的区别
| 对比维度 | RMA(运行移动平均) | EMA(指数移动平均) |
|---|---|---|
| 平滑系数(Alpha) | 固定为 1 / period |
通常为 2 / (period + 1) |
| 与EMA的关系 | RMA是EMA使用特定Alpha时的一种特例 | 更通用的指数平滑形式 |
| 典型应用 | 威尔德系列指标(RSI、ADX等)的核心计算 | 各类趋势跟踪和动量指标 |
| 对近期价格的权重 | 权重相对较小(当period较大时) | 通常给予近期价格更高权重 |
这一公式也说明了为什么RMA(或Wilder平滑)常被评价为"速度较慢",因为它相当于一个有较长有效周期的EMA。
二、RMA的计算方法
1. 核心公式
RMA的计算基于一个递归公式:
RMAt=Pricet×α+RMAt−1×(1−α) \mathrm{RMA}_t = \mathrm{Price}t \times \alpha + \mathrm{RMA}{t-1} \times (1 - \alpha) RMAt=Pricet×α+RMAt−1×(1−α)
其中平滑系数 α\alphaα 为周期的倒数:
α=1length \alpha = \frac{1}{\mathrm{length}} α=length1
2. 计算步骤
第一步:初始化第一个RMA值
与EMA类似,第一个RMA值通常使用简单移动平均(SMA) 作为初始值。
RMAinitial=SMA(Price,length) \mathrm{RMA}_{\text{initial}} = \mathrm{SMA}(\mathrm{Price}, \mathrm{length}) RMAinitial=SMA(Price,length)
第二步:递归计算后续值
从第 length + 1 个数据点开始,使用递推公式计算:
RMAt=1length×Pricet+(1−1length)×RMAt−1 \mathrm{RMA}_t = \frac{1}{\mathrm{length}} \times \mathrm{Price}t + \left(1 - \frac{1}{\mathrm{length}}\right) \times \mathrm{RMA}{t-1} RMAt=length1×Pricet+(1−length1)×RMAt−1
3. 计算示例
以 length = 3 为例:
| 时间 | 价格 | 计算过程 | RMA值 |
|---|---|---|---|
| t1 | 100 | 初始SMA | 100.00 |
| t2 | 105 | 105 × 0.333 + 100 × 0.667 | 101.67 |
| t3 | 102 | 102 × 0.333 + 101.67 × 0.667 | 101.78 |
| t4 | 108 | 108 × 0.333 + 101.78 × 0.667 | 103.85 |
4. pandas_ta中的实现
在pandas_ta库中,RMA函数直接调用了pandas的ewm方法,并传入alpha = 1 / length作为平滑参数:
python
# pandas_ta中RMA的简化实现
def rma(close, length=10):
alpha = 1.0 / length
return close.ewm(alpha=alpha, min_periods=length).mean()
5. 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
close |
pd.Series | 必需 | 收盘价序列 |
length |
int | 10 | RMA的计算周期,控制平滑程度 |
offset |
int | 0 | 结果偏移周期数 |
三、RMA的使用方法
1. 作为RSI的核心计算组件
RMA最广为人知的应用是作为RSI指标的计算基础。在RSI计算中:
- 上涨幅度的平滑使用RMA(周期14)
- 下跌幅度的平滑同样使用RMA(周期14)
2. 作为趋势跟踪工具
与EMA类似,RMA可以作为趋势跟踪均线使用:
| RMA状态 | 趋势含义 | 操作倾向 |
|---|---|---|
| RMA向上运行 | 上升趋势,买方力量主导 | 以做多为主 |
| RMA向下运行 | 下降趋势,卖方力量主导 | 以做空为主 |
| RMA走平 | 趋势可能减弱或进入盘整 | 观望 |
3. 价格穿越信号
价格与RMA的穿越是最简单的入场/出场信号:
| 信号类型 | 触发条件 | 操作建议 |
|---|---|---|
| 买入信号 | 价格从下方上穿RMA | 考虑建立多头仓位 |
| 卖出信号 | 价格从上方下穿RMA | 考虑平仓或建立空头 |
4. 与其他指标配合
RMA本身并不作为独立的交易信号源使用,更多是作为其他指标(如RSI、ADX)的计算基础。pandas_ta库的许多函数都支持通过mamode参数指定使用RMA作为平滑方式。
四、使用pandas_ta计算RMA
1. 函数完整参数
python
pandas_ta.overlap.rma(close, length=None, offset=None, **kwargs)
返回值 :pd.Series------RMA值序列。
2. 示例代码
python
import pandas as pd
import pandas_ta as ta
import numpy as np
import matplotlib.pyplot as plt
# ========== 第一步:准备数据 ==========
np.random.seed(42)
dates = pd.date_range(start='2023-01-01', end='2024-12-31', freq='D')
n = len(dates)
trend = np.linspace(0, 45, n)
cycle = np.sin(np.linspace(0, 6 * np.pi, n)) * 15
noise = np.random.randn(n) * 3
price_series = 100 + trend + cycle + noise
# 添加趋势变化区间
price_series = price_series.astype(float)
for i in range(300, 450):
price_series[i] = price_series[300] + (i-300) * 0.2
for i in range(450, 600):
price_series[i] = price_series[450] - (i-450) * 0.15
df = pd.DataFrame(index=dates[:n])
df['close'] = price_series[:n]
print("=" * 60)
print("数据预览:")
print(df.head())
print("\n" + "=" * 60 + "\n")
# ========== 第二步:计算RMA ==========
# 默认参数 length=10
df['RMA'] = ta.rma(df['close'])
print("RMA计算结果(最近10行):")
print(df[['close', 'RMA']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第三步:不同周期RMA对比 ==========
df['RMA_5'] = ta.rma(df['close'], length=5)
df['RMA_10'] = ta.rma(df['close'], length=10)
df['RMA_20'] = ta.rma(df['close'], length=20)
print("不同周期RMA对比(最近5行):")
print(df[['close', 'RMA_5', 'RMA_10', 'RMA_20']].tail())
print("\n" + "=" * 60 + "\n")
# ========== 第四步:RMA与EMA对比 ==========
# 计算等效周期的EMA进行对比
# RMA(period) ≈ EMA(2*period - 1)
df['EMA_19'] = ta.ema(df['close'], length=19) # 对应RMA(10)
print("RMA(10) vs EMA(19) 对比(最近10行):")
print(df[['close', 'RMA_10', 'EMA_19']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第五步:价格穿越信号 ==========
df['price_above_rma'] = df['close'] > df['RMA_10']
df['cross_above'] = (df['price_above_rma'] == True) & (df['price_above_rma'].shift(1) == False)
df['cross_below'] = (df['price_above_rma'] == False) & (df['price_above_rma'].shift(1) == True)
df['signal'] = ''
df.loc[df['cross_above'], 'signal'] = '买入(价格上穿RMA)'
df.loc[df['cross_below'], 'signal'] = '卖出(价格下穿RMA)'
print("价格穿越信号统计:")
print(f"买入信号数量:{df['cross_above'].sum()}")
print(f"卖出信号数量:{df['cross_below'].sum()}")
print("\n" + "=" * 60 + "\n")
# ========== 第六步:策略回测 ==========
# 策略:价格 > RMA 时持仓多头
df['position'] = (df['close'] > df['RMA_10']).astype(int)
df['returns'] = df['close'].pct_change()
df['strategy_returns'] = df['position'].shift(1) * df['returns']
total_return_buyhold = (1 + df['returns']).prod() - 1
total_return_strategy = (1 + df['strategy_returns']).prod() - 1
print("=" * 60)
print("策略绩效统计(RMA穿越策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"RMA穿越策略总收益率:{total_return_strategy:.2%}")
print("\n注意:此为简化回测,仅供参考")
print("=" * 60 + "\n")
# ========== 第七步:可视化 ==========
plt.figure(figsize=(14, 10))
plt.subplot(2, 1, 1)
plt.plot(df.index[-200:], df['close'][-200:],
label='Close Price', linewidth=1.5, color='black')
plt.plot(df.index[-200:], df['RMA_10'][-200:],
label='RMA (10)', linewidth=1.5, color='blue')
plt.plot(df.index[-200:], df['EMA_19'][-200:],
label='EMA (19) - Equivalent', linewidth=1, color='orange', linestyle='--')
plt.title('RMA(10) vs EMA(19) 对比 (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(2, 1, 2)
plt.plot(df.index[-200:], df['close'][-200:],
label='Close Price', linewidth=1, alpha=0.5, color='black')
plt.plot(df.index[-200:], df['RMA_5'][-200:],
label='RMA (5) - 短线', linewidth=1, alpha=0.7)
plt.plot(df.index[-200:], df['RMA_10'][-200:],
label='RMA (10) - 标准', linewidth=1.5, color='blue')
plt.plot(df.index[-200:], df['RMA_20'][-200:],
label='RMA (20) - 长线', linewidth=1.5, color='green')
plt.title('RMA:不同周期对比与穿越信号', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
五、总结
RMA(运行移动平均线)是技术分析大师威尔德引入的一种特殊移动平均线,其核心价值与定位如下:
| 维度 | 特点 |
|---|---|
| 核心定位 | 威尔德版本EMA,平滑系数 α = 1/period |
| 与EMA关系 | RMA(period) ≈ EMA(2×period - 1) |
| 主要用途 | RSI、ADX等威尔德系列指标的计算基础 |
| 默认参数 | length=10 |
| 最佳应用场景 | 作为RSI、ADX等指标的平滑工具,也可作为趋势跟踪均线 |
| 主要局限 | 本质是EMA的一种特例,不具备独立的理论突破 |