Momentum:RVGI(相对活力指数)技术指标详解

Momentum:RVGI(相对活力指数)技术指标详解

一、RVGI的定义

RVGI(Relative Vigor Index,相对活力指数) 是由John Ehlers开发的一种动量震荡指标,用于衡量趋势的强度和延续可能性。RVGI与随机振荡器(Stochastic Oscillator)在公式上具有相似性,常被视为其"近亲"。

核心思想

RVGI的设计基于一个核心观察:在上涨趋势中,收盘价倾向于处于K线的高位(高于开盘价);而在下跌趋势中,收盘价倾向于处于K线的低位(低于开盘价)

基于这一原理,RVGI通过比较收盘价与开盘价的差值最高价与最低价的差值之间的比率,来量化当前价格走势的"活力"或"强度"。

RVGI的核心特征

特征 说明
理论基础 收盘价在价格区间中的相对位置反映趋势强度
指标类型 动量震荡指标
数值形式 围绕0轴波动的震荡指标,可为正值或负值
开发者 John Ehlers
默认参数 length=14, swma_length=4

RVGI的双线结构

RVGI指标由两条线组成:

组成部分 名称 计算方式 功能
RVGI线 主震荡线 原始RVGI值 反映当前趋势强度
信号线(Signal Line) 触发线 RVGI值的SWMA平滑 产生交叉交易信号

二、RVGI的计算方法

1. 核心计算公式

RVGI的计算包含多个层次,使用对称加权移动平均(SWMA)进行平滑处理。

第一步:计算原始能量值

对于每个周期,首先计算两个基础量:

CloseOpen=Close−OpenHighLow=High−Low \begin{aligned} \mathrm{CloseOpen} &= \mathrm{Close−Open} \\1.5ex \mathrm{HighLow} &= \mathrm{High−Low} \end{aligned} CloseOpenHighLow=Close−Open=High−Low

其中:

  • Close 和 Open 分别为收盘价和开盘价
  • High 和 Low 分别为最高价和最低价
  • 确保分母不为零(需保证HighLow > 0)
第二步:应用对称加权移动平均(SWMA)

对上述两个差值分别应用SWMA平滑:

SWMACloseOpen=SWMA(CloseOpen,swma_length) \mathrm{SWMA}_{\mathrm{CloseOpen}} = \mathrm{SWMA}(\mathrm{CloseOpen}, \mathrm{swma\_length}) SWMACloseOpen=SWMA(CloseOpen,swma_length)

SWMAHighLow=SWMA(HighLow,swma_length) \mathrm{SWMA}_{\mathrm{HighLow}} = \mathrm{SWMA}(\mathrm{HighLow}, \mathrm{swma\_length}) SWMAHighLow=SWMA(HighLow,swma_length)

其中 swma_length\mathrm{swma\_length}swma_length 为 SWMA\mathrm{SWMA}SWMA 周期,默认值为 444。

对称加权移动平均(SWMA)说明:SWMA对窗口内的数据赋予对称权重,通常中间位置的权重最高,两端权重最低,能够有效平滑数据同时保留趋势特征。

第三步:计算周期累加和

对平滑后的值在 length\mathrm{length}length 周期内求和(默认 length=14\mathrm{length}=14length=14):

SumCloseOpent=∑i=t−length+1tSWMACloseOpen,i \mathrm{SumCloseOpen}t = \sum{i=t-\mathrm{length}+1}^{t} \mathrm{SWMA}_{\mathrm{CloseOpen},i} SumCloseOpent=i=t−length+1∑tSWMACloseOpen,i

SumHighLowt=∑i=t−length+1tSWMAHighLow,i \mathrm{SumHighLow}t = \sum{i=t-\mathrm{length}+1}^{t} \mathrm{SWMA}_{\mathrm{HighLow},i} SumHighLowt=i=t−length+1∑tSWMAHighLow,i

第四步:计算RVGI值

RVGI=SumCloseOpenSumHighLow \mathrm{RVGI} = \frac{\mathrm{SumCloseOpen}}{\mathrm{SumHighLow}} RVGI=SumHighLowSumCloseOpen

第五步:计算信号线

信号线是RVGI值的SWMA平滑:

Signal=SWMA(RVGI,swma_length) \mathrm{Signal = SWMA(RVGI,swma\_length)} Signal=SWMA(RVGI,swma_length)

其中 swma_length\mathrm{swma\_length}swma_length 同样默认为4。

2. 完整公式汇总

将上述步骤合并,RVGI的完整计算公式为:

RVGIt=∑i=0length−1SWMA(CloseOpen,swma_length)t−i∑i=0length−1SWMA(HighLow,swma_length)t−i \mathrm{RVGI}t = \frac{\sum{i=0}^{\mathrm{length}-1} \mathrm{SWMA}(\mathrm{CloseOpen}, \mathrm{swma\length}){t-i}}{\sum_{i=0}^{\mathrm{length}-1} \mathrm{SWMA}(\mathrm{HighLow}, \mathrm{swma\length}){t-i}} RVGIt=∑i=0length−1SWMA(HighLow,swma_length)t−i∑i=0length−1SWMA(CloseOpen,swma_length)t−i

Signalt=SWMA(RVGI,swma_length)t \mathrm{Signal}_t = \mathrm{SWMA}(\mathrm{RVGI}, \mathrm{swma\_length})_t Signalt=SWMA(RVGI,swma_length)t

3. 参数说明

参数 类型 默认值 说明
length int 14 RVGI累加周期,控制指标灵敏度
swma_length int 4 SWMA平滑周期,控制信号线的平滑度
offset int 0 结果偏移周期数

4. 计算示例

假设某股票使用默认参数(length=14, swma_length=4),当前周期的基础数据:

变量 说明 假设值
SWMA₍CloseOpen₎ 平滑后的收盘-开盘均值 0.15
SWMA₍HighLow₎ 平滑后的最高-最低均值 0.10
SumCloseOpen 14周期累加和 2.10
SumHighLow 14周期累加和 1.40

RVGI计算

RVGI=SumCloseOpenSumHighLow=2.101.40=1.5 \mathrm{RVGI} = \frac{\mathrm{SumCloseOpen}}{\mathrm{SumHighLow}} = \frac{2.10}{1.40} = 1.5 RVGI=SumHighLowSumCloseOpen=1.402.10=1.5

信号线计算

假设前4个周期的RVGI值为:1.5, 1.4, 1.3, 1.2

Signal=SQMA(1.5,1.4,1.3,1.2)≈1.35 \mathrm{Signal} = \mathrm{SQMA}(1.5,1.4,1.3,1.2) \approx 1.35 Signal=SQMA(1.5,1.4,1.3,1.2)≈1.35

该RVGI=1.5 > Signal=1.35,RVGI线在信号线上方,表明买方力量较强。

三、RVGI的使用方法

1. 交叉信号------最核心用法

RVGI与信号线的交叉是生成交易信号最基础也是最核心的方法:

信号类型 触发条件 含义 操作建议
看涨交叉(金叉) RVGI线从下方上穿信号线 买方力量开始增强,趋势可能转为上涨 考虑买入/做多
看跌交叉(死叉) RVGI线从上方下穿信号线 卖方力量开始增强,趋势可能转为下跌 考虑卖出/做空

信号增强条件:当交叉发生在RVGI值远离0轴的区域时,信号的可靠性更高。

2. 超买超卖判断

RVGI作为围绕0轴波动的震荡指标,其极端值可反映市场的过热或过冷状态:

RVGI值 状态 含义 操作建议
高正值 超买 买方力量过度释放,市场可能过热 警惕回调,考虑减仓
低负值 超卖 卖方力量过度释放,市场可能过度恐慌 关注反弹机会,考虑分批布局

注意:与RSI等固定范围的指标不同,RVGI的"高"和"低"需结合具体品种的历史波动范围来判断,没有统一固定的阈值。

3. 背离信号------反转预警

RVGI与价格走势的背离是重要的反转预警信号:

背离类型 价格表现 RVGI表现 信号含义
顶背离 价格创出新高 RVGI未能创出新高(形成更低高点) 上涨动能衰竭,卖出信号
底背离 价格创出新低 RVGI未能创出新低(形成更高低点) 下跌动能减弱,买入信号

背离信号通常在趋势末端出现,是捕捉潜在反转点的有效工具。

4. 形态分析

RVGI指标线本身也会形成技术形态,可用于辅助判断:

形态 信号含义
双底(W底) 在低位区域形成后,预示可能上涨
双顶(M顶) 在高位区域形成后,预示可能下跌
头肩顶/底 典型的反转形态信号

5. 与其他指标的配合策略

RVGI的可靠性在使用单一指标时可能受限,建议与其他工具配合使用:

配合工具 策略逻辑 增强效果
移动平均线 SMA交叉确认趋势方向后,结合RVGI信号入场 减少震荡市假信号
RSI(相对强弱指数) RVGI与RSI同时发出超买/超卖信号时可靠性更高 多重验证,提高胜率
KDJ(随机指标) 两个震荡指标同时出现信号时互相验证 降低误判风险
MACD RVGI提供早入场信号,MACD确认趋势延续 取长补短
布林带 RVGI超买/超卖信号 + 价格突破布林带中轨确认 增加入场信心

6. 注意事项与局限性

使用RVGI前需了解以下要点*:

局限性 说明
可能产生假信号 与其他技术指标一样,RVGI在震荡市场中可能产生虚假的交叉信号
需要其他工具确认 不建议将RVGI作为唯一决策依据,应结合价格行为、趋势线等确认
适用性限制 在24/7连续交易且无明确开收盘的加密市场中,RVGI的有效性可能受限
参数敏感 length和swma_length参数的调整会显著影响指标的灵敏度和平滑度
初期预热需求 RVGI需要足够的历史数据完成累加和平滑计算,初期可能出现无效值

四、使用pandas_ta计算RVGI(附示例代码)

1. pandas_ta中的RVGI函数

pandas_ta库内置了RVGI指标的完整实现,函数位于momentum模块中。

2. 函数完整参数

python 复制代码
pandas_ta.momentum.rvgi(open_, high, low, close, length=None, swma_length=None, offset=None, **kwargs)

参数详解

参数 类型 默认值 说明
open_ pd.Series 必需 开盘价序列(注意下划线后缀)
high pd.Series 必需 最高价序列
low pd.Series 必需 最低价序列
close pd.Series 必需 收盘价序列
length int 14 RVGI累加周期
swma_length int 4 对称加权移动平均周期
offset int 0 结果偏移周期数

返回值pd.DataFrame------包含两列:

  • RVGI_{length}_{swma_length}:RVGI主线
  • RVGIs_{length}_{swma_length}:信号线(Signal Line)

3. 示例代码

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, 35, n)
cycle = np.sin(np.linspace(0, 6 * np.pi, n)) * 12
noise = np.random.randn(n) * 2.5
price_series = 100 + trend + cycle + noise

# 添加一个更真实的趋势段:中期上涨 + 下跌 + 盘整
price_series = price_series.astype(float)
for i in range(200, 350):
    price_series[i] = price_series[200] + (i-200) * 0.15
for i in range(350, 500):
    price_series[i] = price_series[350] - (i-350) * 0.12
for i in range(500, 650):
    price_series[i] = price_series[500] + np.random.randn() * 0.5

# 生成OHLC数据
df = pd.DataFrame(index=dates[:n])
df['close'] = price_series[:n]
df['open'] = df['close'] + np.random.randn(n) * 1.5
df['high'] = df[['open', 'close']].max(axis=1) + np.abs(np.random.randn(n)) * 2 + 1
df['low'] = df[['open', 'close']].min(axis=1) - np.abs(np.random.randn(n)) * 2 - 1
df['volume'] = np.random.randint(1000000, 20000000, n)

print("=" * 60)
print("数据预览:")
print(df.head())
print("\n" + "=" * 60 + "\n")

# ========== 第二步:计算RVGI(基础用法) ==========
# 使用默认参数 length=14, swma_length=4
rvgi_df = ta.rvgi(df['open'], df['high'], df['low'], df['close'])

# 查看返回的DataFrame结构
print("RVGI返回列名称:")
print(rvgi_df.columns.tolist())
print("\n" + "=" * 60 + "\n")

# 将计算结果添加到原DataFrame
df['RVGI'] = rvgi_df.iloc[:, 0]      # RVGI主线
df['Signal'] = rvgi_df.iloc[:, 1]    # 信号线

print("RVGI计算结果(最近10行):")
print(df[['close', 'RVGI', 'Signal']].tail(10))
print("\n" + "=" * 60 + "\n")

# ========== 第三步:手动验证RVGI计算 ==========
def manual_rvgi(open_, high, low, close, length=14, swma_length=4):
    """手动计算RVGI验证pandas_ta结果"""
    # 步骤1:计算原始差值
    close_open = close - open_
    high_low = high - low
    
    # 步骤2:应用SWMA(使用简单加权移动平均近似)
    def swma(series, length):
        """对称加权移动平均近似"""
        weights = np.arange(1, length + 1)
        weights = np.minimum(weights, weights[::-1])
        weights = weights / weights.sum()
        return series.rolling(window=length).apply(
            lambda x: np.sum(weights * x), raw=True
        )
    
    # 步骤3:SWMA平滑
    swma_co = swma(close_open, swma_length)
    swma_hl = swma(high_low, swma_length)
    
    # 步骤4:累加求和
    sum_co = swma_co.rolling(window=length).sum()
    sum_hl = swma_hl.rolling(window=length).sum()
    
    # 步骤5:计算RVGI
    rvgi = sum_co / sum_hl
    
    # 步骤6:计算信号线
    signal = swma(rvgi, swma_length)
    
    return rvgi, signal

df['RVGI_manual'], df['Signal_manual'] = manual_rvgi(
    df['open'], df['high'], df['low'], df['close']
)

# 验证一致性
diff_rvgi = (df['RVGI'] - df['RVGI_manual']).abs().max()
print(f"RVGI主线手动验证最大差异:{diff_rvgi:.10f}")
print("\n" + "=" * 60 + "\n")

# ========== 第四步:不同参数的RVGI对比 ==========
# 短周期参数 (length=9, swma_length=3)
rvgi_short = ta.rvgi(df['open'], df['high'], df['low'], df['close'], length=9, swma_length=3)
df['RVGI_short'] = rvgi_short.iloc[:, 0]
df['Signal_short'] = rvgi_short.iloc[:, 1]

# 长周期参数 (length=21, swma_length=5)
rvgi_long = ta.rvgi(df['open'], df['high'], df['low'], df['close'], length=21, swma_length=5)
df['RVGI_long'] = rvgi_long.iloc[:, 0]
df['Signal_long'] = rvgi_long.iloc[:, 1]

print("不同参数RVGI对比(最近5行):")
print(df[['close', 'RVGI', 'RVGI_short', 'RVGI_long']].tail())
print("\n" + "=" * 60 + "\n")

# ========== 第五步:生成交叉信号 ==========
# 检测RVGI与信号线的交叉
df['RVGI_above_signal'] = df['RVGI'] > df['Signal']
df['cross_above'] = (df['RVGI_above_signal'] == True) & (df['RVGI_above_signal'].shift(1) == False)
df['cross_below'] = (df['RVGI_above_signal'] == False) & (df['RVGI_above_signal'].shift(1) == True)

df['signal'] = ''
df.loc[df['cross_above'], 'signal'] = '金叉(买入信号)'
df.loc[df['cross_below'], 'signal'] = '死叉(卖出信号)'

print("交叉信号统计:")
print(f"金叉数量:{df['cross_above'].sum()}")
print(f"死叉数量:{df['cross_below'].sum()}")

print("\n最近10个交叉信号:")
signals = df[df['signal'] != ''].tail(10)
if not signals.empty:
    print(signals[['close', 'RVGI', 'Signal', 'signal']])
else:
    print("近期无交叉信号")
print("\n" + "=" * 60 + "\n")

# ========== 第六步:零轴穿越分析 ==========
df['RVGI_above_zero'] = df['RVGI'] > 0
df['cross_above_zero'] = (df['RVGI_above_zero'] == True) & (df['RVGI_above_zero'].shift(1) == False)
df['cross_below_zero'] = (df['RVGI_above_zero'] == False) & (df['RVGI_above_zero'].shift(1) == True)

print("零轴穿越信号统计:")
print(f"上穿零轴数量:{df['cross_above_zero'].sum()}")
print(f"下穿零轴数量:{df['cross_below_zero'].sum()}")
print("\n" + "=" * 60 + "\n")

# ========== 第七步:RVGI与价格背离检测 ==========
# 计算局部极值点(简化检测)
def find_local_extrema(series, window=5):
    """寻找局部极值点"""
    peaks = []
    troughs = []
    for i in range(window, len(series) - window):
        if series.iloc[i] == max(series.iloc[i-window:i+window+1]):
            peaks.append(i)
        if series.iloc[i] == min(series.iloc[i-window:i+window+1]):
            troughs.append(i)
    return peaks, troughs

# 简化版背离检测(20日方向对比)
df['price_change_20d'] = df['close'].diff(20)
df['rvgi_change_20d'] = df['RVGI'].diff(20)

# 潜在顶背离:价格涨但RVGI跌
df['potential_bearish_div'] = (df['price_change_20d'] > 0) & (df['rvgi_change_20d'] < 0)
# 潜在底背离:价格跌但RVGI涨
df['potential_bullish_div'] = (df['price_change_20d'] < 0) & (df['rvgi_change_20d'] > 0)

print("潜在背离信号统计(20日尺度):")
print(f"潜在顶背离(价格涨RVGI跌)数量:{df['potential_bearish_div'].sum()}")
print(f"潜在底背离(价格跌RVGI涨)数量:{df['potential_bullish_div'].sum()}")
print("注:完整背离需结合局部高/低点分析,此处为简化方向对比")
print("\n" + "=" * 60 + "\n")

# ========== 第八步:策略回测(交叉信号策略) ==========
# 策略:RVGI > Signal 时持仓多头
df['position_cross'] = (df['RVGI'] > df['Signal']).astype(int)

# 策略2:RVGI > 0 时持仓多头
df['position_zero'] = (df['RVGI'] > 0).astype(int)

# 计算收益
df['returns'] = df['close'].pct_change()
df['strategy_cross_returns'] = df['position_cross'].shift(1) * df['returns']
df['strategy_zero_returns'] = df['position_zero'].shift(1) * df['returns']

total_return_buyhold = (1 + df['returns']).prod() - 1
total_return_cross = (1 + df['strategy_cross_returns']).prod() - 1
total_return_zero = (1 + df['strategy_zero_returns']).prod() - 1

print("=" * 60)
print("策略绩效统计(RVGI策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"RVGI > Signal 策略总收益率:{total_return_cross:.2%}")
print(f"RVGI > 0 策略总收益率:{total_return_zero:.2%}")
print("\n注意:此为简化回测,仅供参考")
print("=" * 60 + "\n")

# ========== 第九步:可视化 ==========
plt.figure(figsize=(14, 12))

# 子图1:价格走势
plt.subplot(2, 1, 1)
plt.plot(df.index[-200:], df['close'][-200:], label='Close Price', 
         linewidth=1.5, color='black')
plt.title('Price Chart (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)

# 子图2:RVGI指标
plt.subplot(2, 1, 2)
plt.plot(df.index[-200:], df['RVGI'][-200:], label='RVGI线', 
         linewidth=1.5, color='blue')
plt.plot(df.index[-200:], df['Signal'][-200:], label='信号线', 
         linewidth=1.5, color='orange', linestyle='--')
plt.axhline(y=0, color='gray', linestyle='-', linewidth=1, label='零轴')

# 标记交叉点
buy_signals = df[df['cross_above']]
sell_signals = df[df['cross_below']]
plt.scatter(buy_signals.index[-30:], buy_signals['RVGI'][-30:], 
            color='green', marker='^', s=80, label='金叉(买入)', alpha=0.8)
plt.scatter(sell_signals.index[-30:], sell_signals['RVGI'][-30:], 
            color='red', marker='v', s=80, label='死叉(卖出)', alpha=0.8)

plt.title('RVGI (Relative Vigor Index) - 相对活力指数', fontsize=14)
plt.xlabel('Date')
plt.ylabel('RVGI Value')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# ========== 第十步:数据清洗提示 ==========
nan_count = df['RVGI'].isna().sum()
print(f"\nRVGI初始NaN数量:{nan_count}")
print("原因:RVGI需要至少 max(length, swma_length) 个周期的数据才能计算")
print("处理建议:df_clean = df.iloc[14:].copy()")
print("\n" + "=" * 60)
print("RVGI使用提示:")
print("1. RVGI > Signal 为多头信号,RVGI < Signal 为空头信号")
print("2. 金叉/死叉是最核心的交易信号,建议在零轴附近使用时更谨慎")
print("3. 建议与移动平均线、RSI等工具配合使用,提高信号可靠性")
print("4. 在强趋势行情中,RVGI可能长期处于极端值区域,此时应以趋势跟踪为主")
print("=" * 60)

五、总结

RVGI(相对活力指数)是一种基于价格区间位置理论的动量震荡指标,其核心价值与定位如下:

维度 特点
核心原理 上涨趋势中收盘价趋于高位,下跌趋势中收盘价趋于低位
核心公式 SWMA(Close-Open)累加和 ÷ SWMA(High-Low)累加和
双线结构 RVGI线 + 信号线(SWMA平滑)
三大核心信号 金叉/死叉、零轴穿越、顶底背离
默认参数 length=14, swma_length=4
最佳应用场景 趋势确认、动量判断、多指标组合策略
主要局限 可能产生假信号、需配合其他工具确认、参数敏感

实战使用三原则

  1. 交叉信号优先:RVGI线与信号线的金叉/死叉是最可靠的交易信号,应作为核心入场/出场依据
  2. 多指标验证提高胜率:RVGI应与移动平均线、RSI或MACD等指标配合使用,通过多重确认减少假信号
  3. 背离是最强预警:当RVGI与价格出现背离时,往往是重要的趋势反转信号,应给予高度重视

最后提醒:RVGI的价值在于帮助交易者回答"当前趋势的强度是否可持续"这一问题。它通过比较收盘价在价格区间中的相对位置来量化市场动力。与其他震荡指标类似,RVGI在单一使用时可能产生假信号,建议将其作为多指标分析体系中的一环。当RVGI与价格行为、趋势线、移动平均线等工具发出共振信号时,其指示意义才最为可靠。

相关推荐
Promise微笑3 小时前
洞察无形:红外热像仪行业标准解析与深度选型指南
网络·人工智能·算法
Bruce_Liuxiaowei3 小时前
智能音箱数据分析与优化方案
人工智能·数据挖掘·数据分析·智能音箱·智能体
YangYang9YangYan3 小时前
2026数据分析对报考大数据专业的价值分析
大数据·数据挖掘·数据分析·高考
珠海西格电力3 小时前
零碳园区的竞争力体现在哪些方面?
大数据·人工智能·算法·架构·能源
星川皆无恙3 小时前
Python豆瓣电影数据分析可视化系统:爬虫采集+数据清洗+可视化大屏完整项目
人工智能·爬虫·python·数据分析
Tattoo_Welkin3 小时前
一些常用的金融和区块链的概念
金融·区块链
孬甭_3 小时前
从基础到优化:深入理解插入排序与希尔排序
数据结构·算法·排序算法
好家伙VCC3 小时前
Rust+Bioinfo:80ms极速SNP注释引擎
java·开发语言·算法·rust
天青色等烟雨..3 小时前
AI大语言模型助力高效办公、论文与项目撰写、数据分析、机器学习与深度学习建模等深度科研
人工智能·语言模型·数据分析