You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合SMA初始值与EWM计算Wilders移动平均版RSI指标?

实现基于Wilders移动平均的RSI(结合SMA初始值与EWM递推)

Wilders RSI的核心逻辑是:用前n期涨跌的算术平均(SMA)作为初始值,之后每一期的平均涨跌用递推公式计算——avg_gain = (prev_avg_gain*(n-1) + current_gain)/n,avg_loss同理。这个递推逻辑和alpha=1/n且adjust=False的EWM完全等价,所以我们可以结合SMA初始化+EWM递推来高效实现,不用低效的循环。

具体步骤与代码

假设你的DataFrame已经包含close列,以14期RSI为例:

import pandas as pd

# 1. 计算基础涨跌数据
df['change'] = df['close'].diff()
df['gain'] = df['change'].where(df['change'] > 0, 0)  # 正涨幅保留,负的设为0
df['loss'] = df['change'].where(df['change'] < 0, 0).abs()  # 负跌幅取绝对值,正的设为0

# 2. 计算n期初始SMA平均涨跌
n = 14
df['avg_gain'] = df['gain'].rolling(n).mean()
df['avg_loss'] = df['loss'].rolling(n).mean()

# 3. 用EWM生成递推值,替换初始值之后的行
# Wilders平滑系数对应alpha=1/n,adjust=False保证递推逻辑和公式一致
ewm_gain = df['gain'].ewm(alpha=1/n, adjust=False).mean()
ewm_loss = df['loss'].ewm(alpha=1/n, adjust=False).mean()

# 从第n行之后(索引从0开始的话是n位置),用EWM结果覆盖SMA的NaN
df.loc[df.index[n:], 'avg_gain'] = ewm_gain.iloc[n:]
df.loc[df.index[n:], 'avg_loss'] = ewm_loss.iloc[n:]

# 4. 计算RSI,处理avg_loss为0的极端情况(避免除零错误)
df['rsi'] = 100 - (100 / (1 + df['avg_gain'] / df['avg_loss'].replace(0, float('inf'))))

为什么这个方法有效?

Wilders的递推公式和无调整的EWM完全匹配:ewm(alpha=1/n, adjust=False)的计算逻辑就是新值 = alpha*当前值 + (1-alpha)*旧值,代入alpha=1/n就是新值 = (当前值 + (n-1)*旧值)/n,和Wilders公式一致。我们先用SMA得到第一个有效平均涨跌值,之后的行直接用EWM结果覆盖,完美实现了标准Wilders RSI的计算逻辑,比循环高效得多。

内容的提问来源于stack exchange,提问作者SebastianHeeg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:40:17