Author: Coded by Witold Wozniak
RVI_v1

This technical indicator, known as the Relative Vigor Index (RVI), is designed to help traders gauge the strength and momentum of a market trend by analyzing the relationship between price movement and price range. Unlike standard indicators that might only look at closing prices, this tool incorporates "vigor"—a measure of how aggressively a price moves from its opening point to its high and low extremes.

How the Logic Works

The indicator operates by breaking down market data into two distinct components:

1. Body Momentum (The Numerator) The script first calculates the "Body" of the price movement. It looks at the difference between the opening and closing prices across multiple candles. To ensure the data is smooth and not influenced by one-time outliers, it applies a weighted average. This means it gives more importance to the most recent candle's body while still considering the preceding three candles. This represents the "net progress" made by the market.

2. Range Volatility (The Denominator) Simultaneously, the script calculates the total "Range" of the price movement—the distance between the highest and lowest points reached during each candle. Just like the body momentum, this is weighted to prioritize recent data. This represents the "total effort" or volatility displayed by the market.

3. The RVI Calculation The final RVI value is determined by dividing the total weighted Body Momentum by the total weighted Range Volatility over a specific period (defined by the user, default is 10). By dividing progress by effort, the indicator reveals whether the price is moving decisively in one direction or if it is struggling with high volatility but little actual progress.

Visual Representation and Usage

The script produces two distinct lines on a separate window below your main price chart:

  • The RVI Line: This is the primary indicator showing the current momentum balance. When this line moves above the zero level, it suggests bullish strength; when it moves below, it suggests bearish strength.
  • The Trigger Line: This is a "signal" line that follows the RVI value with a slight delay (tracking the previous candle's data). Traders often look for the relationship between these two lines—such as when the RVI crosses its Trigger—to identify potential shifts in momentum or entry/exit points.

Summary for the Trader

In simple terms, this tool tells you if the "push" in the market is actually moving the price forward. If the price range is wide but the body of the candles remains small, the RVI will reflect a lack of true conviction. If the bodies are large relative to the total range, the RVI confirms a strong, vigorous trend.

Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
RVI_v1
//+------------------------------------------------------------------+
//|                                                          RVI.mq4 |
//|                                                                  |
//| Relative Vigor Index                                             |
//|                                                                  |
//| Algorithm taken from book                                        |
//|     "Cybernetics Analysis for Stock and Futures"                 |
//| by John F. Ehlers                                                |
//|                                                                  |
//|                                              contact@mqlsoft.com |
//|                                          http://www.mqlsoft.com/ |
//+------------------------------------------------------------------+
#property copyright "Coded by Witold Wozniak"
#property link      "www.mqlsoft.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue

#property indicator_level1 0

double RVI[];
double Trigger[];
double Value1[];
double Value2[];

extern int Length = 10;
int buffers = 0;
int drawBegin = 0;

int init() {
    drawBegin = Length;
    initBuffer(RVI, "RVI", DRAW_LINE);
    initBuffer(Trigger, "Trigger", DRAW_LINE);
    initBuffer(Value1);
    initBuffer(Value2);
    IndicatorBuffers(buffers);
    IndicatorShortName("RVI [" + Length + "]");
    return (0);
}

int start() {
    if (Bars <= drawBegin) return (0);
    int countedBars = IndicatorCounted();
    if (countedBars < 0) return (-1);
    if (countedBars > 0) countedBars--;
    int s, limit = Bars - countedBars - 1;
    for (s = limit; s >= 0; s--) {
        Value1[s] = ((Close[s] - Open[s]) + 
            2.0 * (Close[s + 1] - Open[s + 1]) + 
            2.0 * (Close[s + 2] - Open[s + 2]) + 
            (Close[s + 3] - Open[s + 3])) / 6.0;
        Value2[s] = ((High[s] - Low[s]) + 
            2.0 * (High[s + 1] - Low[s + 1]) + 
            2.0 * (High[s + 2] - Low[s + 2]) + 
            (High[s + 3] - Low[s + 3])) / 6.0;
        double Num = 0.0;
        double Denom = 0.0;
        for (int count = 0; count < Length; count++) {
            Num += Value1[s + count];
            Denom += Value2[s + count];
        }        
        if (Denom != 0.0) {
            RVI[s] = Num / Denom;
        } else {
            RVI[s] = 0.0;
        }
        Trigger[s] = RVI[s + 1];        
    }
    return (0);   
}

void initBuffer(double array[], string label = "", int type = DRAW_NONE, int arrow = 0, int style = EMPTY, int width = EMPTY, color clr = CLR_NONE) {
    SetIndexBuffer(buffers, array);
    SetIndexLabel(buffers, label);
    SetIndexEmptyValue(buffers, EMPTY_VALUE);
    SetIndexDrawBegin(buffers, drawBegin);
    SetIndexShift(buffers, 0);
    SetIndexStyle(buffers, type, style, width);
    SetIndexArrow(buffers, arrow);
    buffers++;
}

Comments