Source code for pandas_ta.volatility.rvi

# -*- coding: utf-8 -*-
from pandas_ta.overlap import ma
from pandas_ta.statistics import stdev
from pandas_ta.utils import get_drift, get_offset
from pandas_ta.utils import unsigned_differences, verify_series


[docs]def rvi(close, high=None, low=None, length=None, scalar=None, refined=None, thirds=None, mamode=None, drift=None, offset=None, **kwargs): """Indicator: Relative Volatility Index (RVI)""" # Validate arguments length = int(length) if length and length > 0 else 14 scalar = float(scalar) if scalar and scalar > 0 else 100 refined = False if refined is None else refined thirds = False if thirds is None else thirds mamode = mamode if isinstance(mamode, str) else "ema" close = verify_series(close, length) drift = get_drift(drift) offset = get_offset(offset) if close is None: return if refined or thirds: high = verify_series(high) low = verify_series(low) # Calculate Result def _rvi(source, length, scalar, mode, drift): """RVI""" std = stdev(source, length) pos, neg = unsigned_differences(source, amount=drift) pos_std = pos * std neg_std = neg * std pos_avg = ma(mode, pos_std, length=length) neg_avg = ma(mode, neg_std, length=length) result = scalar * pos_avg result /= pos_avg + neg_avg return result _mode = "" if refined: high_rvi = _rvi(high, length, scalar, mamode, drift) low_rvi = _rvi(low, length, scalar, mamode, drift) rvi = 0.5 * (high_rvi + low_rvi) _mode = "r" elif thirds: high_rvi = _rvi(high, length, scalar, mamode, drift) low_rvi = _rvi(low, length, scalar, mamode, drift) close_rvi = _rvi(close, length, scalar, mamode, drift) rvi = (high_rvi + low_rvi + close_rvi) / 3.0 _mode = "t" else: rvi = _rvi(close, length, scalar, mamode, drift) # Offset if offset != 0: rvi = rvi.shift(offset) # Handle fills if "fillna" in kwargs: rvi.fillna(kwargs["fillna"], inplace=True) if "fill_method" in kwargs: rvi.fillna(method=kwargs["fill_method"], inplace=True) # Name and Categorize it rvi.name = f"RVI{_mode}_{length}" rvi.category = "volatility" return rvi
rvi.__doc__ = \ """Relative Volatility Index (RVI) The Relative Volatility Index (RVI) was created in 1993 and revised in 1995. Instead of adding up price changes like RSI based on price direction, the RVI adds up standard deviations based on price direction. Sources: https://www.tradingview.com/wiki/Keltner_Channels_(KC) Calculation: Default Inputs: length=14, scalar=100, refined=None, thirds=None EMA = Exponential Moving Average STDEV = Standard Deviation UP = STDEV(src, length) IF src.diff() > 0 ELSE 0 DOWN = STDEV(src, length) IF src.diff() <= 0 ELSE 0 UPSUM = EMA(UP, length) DOWNSUM = EMA(DOWN, length RVI = scalar * (UPSUM / (UPSUM + DOWNSUM)) Args: high (pd.Series): Series of 'high's low (pd.Series): Series of 'low's close (pd.Series): Series of 'close's length (int): The short period. Default: 14 scalar (float): A positive float to scale the bands. Default: 100 refined (bool): Use 'refined' calculation which is the average of RVI(high) and RVI(low) instead of RVI(close). Default: False thirds (bool): Average of high, low and close. Default: False mamode (str): See ```help(ta.ma)```. Default: 'ema' offset (int): How many periods to offset the result. Default: 0 Kwargs: fillna (value, optional): pd.DataFrame.fillna(value) fill_method (value, optional): Type of fill method Returns: pd.DataFrame: lower, basis, upper columns. """