Files
Miha Kralj 35a6702b06 fix(docs): correct .md documentation across errors, dynamics, filters, forecasts, momentum, numerics, oscillators, reversals, statistics, trends, volatility, volume
Deep review of all indicator categories verified .md headers against .cs WarmupPeriod, parameters, inputs, and outputs. Fixes include warmup corrections, parameter documentation, output type accuracy, and Pine Script alignment.
2026-03-10 18:38:23 -07:00

72 lines
3.3 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Relative Volatility Index (RVI)", shorttitle="RVI", overlay=false)
//@function Calculates the Relative Volatility Index (RVI).
//@param src The source series to calculate RVI from. Default is `close`.
//@param stdevLength The lookback period for calculating the standard deviation of source prices. Default is 10.
//@param rmaLength The lookback period for Wilder's smoothing (RMA) of the upward and downward standard deviations. Default is 14.
//@returns float The Relative Volatility Index value.
rvi(series float src = close, simple int stdevLength = 10, simple int rmaLength = 14) =>
float currentStdDev = 0.0
var array<float> buffer_stddev = array.new_float(stdevLength, na) // p_stddev simplified
var int head_stddev = 0, var int count_stddev = 0
var float sum_stddev = 0.0, var float sumSq_stddev = 0.0
float oldest_stddev = array.get(buffer_stddev, head_stddev)
if not na(oldest_stddev)
sum_stddev -= oldest_stddev
sumSq_stddev -= oldest_stddev * oldest_stddev
count_stddev -= 1
float val_stddev = nz(src)
sum_stddev += val_stddev
sumSq_stddev += val_stddev * val_stddev
count_stddev += 1
array.set(buffer_stddev, head_stddev, val_stddev)
head_stddev := (head_stddev + 1) % stdevLength // p_stddev simplified
if count_stddev > 1
currentStdDev := math.sqrt(math.max(0.0, (sumSq_stddev / count_stddev) - math.pow(sum_stddev / count_stddev, 2)))
else
currentStdDev := 0.0
float priceChange = src - src[1]
float upStd_val = 0.0, float downStd_val = 0.0
if priceChange > 0
upStd_val := currentStdDev
else if priceChange < 0
downStd_val := currentStdDev
var float raw_rma_up = 0.0, var float e_up = 1.0
var float avgUpStd = 0.0 , var float EPSILON_rma = 1e-10
if not na(upStd_val)
float alpha_up = 1.0 / float(rmaLength)
raw_rma_up := (raw_rma_up * (rmaLength - 1) + upStd_val) / rmaLength
e_up := (1 - alpha_up) * e_up
avgUpStd := e_up > EPSILON_rma ? raw_rma_up / (1.0 - e_up) : raw_rma_up
if rmaLength == 0
avgUpStd := upStd_val
var float raw_rma_down = 0.0, var float e_down = 1.0
var float avgDownStd = 0.0
if not na(downStd_val)
float alpha_down = 1.0 / float(rmaLength)
raw_rma_down := (raw_rma_down * (rmaLength - 1) + downStd_val) / rmaLength
e_down := (1 - alpha_down) * e_down
avgDownStd := e_down > EPSILON_rma ? raw_rma_down / (1.0 - e_down) : raw_rma_down
if rmaLength == 0
avgDownStd := downStd_val
float rviValue = 50.0
float sumAvgStd = nz(avgUpStd) + nz(avgDownStd)
if sumAvgStd != 0
rviValue := 100 * nz(avgUpStd) / sumAvgStd
rviValue
// ---------- Main loop ----------
// Inputs
i_src_rvi = input.source(close, "Source")
i_stdevLength_rvi = input.int(10, "StdDev Length", minval=2, tooltip="Lookback period for calculating the Standard Deviation of source prices.")
i_rmaLength_rvi = input.int(14, "RMA Length (Wilder's Smoothing)", minval=1, tooltip="Lookback period for smoothing Upward and Downward Standard Deviations.")
// Calculation
rviValue = rvi(i_src_rvi, i_stdevLength_rvi, i_rmaLength_rvi)
// Plot
plot(rviValue, "RVI", color=color.yellow, linewidth=2)