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

64 lines
2.7 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Volatility of Volatility (VOV)", shorttitle="VOV", format=format.price, precision=4, overlay=false)
//@function Calculates the Volatility of Volatility (VOV) with embedded rolling standard deviation algorithms.
//@param src The source series. Default is `close`.
//@param volatilityPeriod The lookback period for the initial volatility calculation. Default is 20.
//@param vovPeriod The lookback period for calculating the standard deviation of the volatility series. Default is 10.
//@returns float The VOV value.
vov(series float src, int volatilityPeriod, int vovPeriod) =>
var int p1 = 0
var array<float> buffer1 = array.new_float(0)
var int head1 = 0, var int count1 = 0
var float sum1 = 0.0, var float sumSq1 = 0.0
if p1 != volatilityPeriod
p1 := math.max(1, volatilityPeriod)
buffer1 := array.new_float(p1, na)
head1 := 0, count1 := 0, sum1 := 0.0, sumSq1 := 0.0
float oldest1 = array.get(buffer1, head1)
if not na(oldest1)
sum1 -= oldest1
sumSq1 -= oldest1 * oldest1
count1 := count1 == p1 ? count1 - 1 : count1
float val1 = nz(src)
sum1 += val1
sumSq1 += val1 * val1
count1 := count1 < p1 ? count1 + 1 : count1
array.set(buffer1, head1, val1)
head1 := (head1 + 1) % p1
float initialVolatility = count1 > 1 ? math.sqrt(math.max(0.0, (sumSq1 / count1) - math.pow(sum1 / count1, 2))) : 0.0
var int p2 = 0
var array<float> buffer2 = array.new_float(0)
var int head2 = 0, var int count2 = 0
var float sum2 = 0.0, var float sumSq2 = 0.0
if p2 != vovPeriod
p2 := math.max(1, vovPeriod)
buffer2 := array.new_float(p2, na)
head2 := 0, count2 := 0, sum2 := 0.0, sumSq2 := 0.0
float oldest2 = array.get(buffer2, head2)
if not na(oldest2)
sum2 -= oldest2
sumSq2 -= oldest2 * oldest2
count2 := count2 == p2 ? count2 - 1 : count2
float val2 = nz(initialVolatility)
sum2 += val2
sumSq2 += val2 * val2
count2 := count2 < p2 ? count2 + 1 : count2
array.set(buffer2, head2, val2)
head2 := (head2 + 1) % p2
float vovValue = count2 > 1 ? math.sqrt(math.max(0.0, (sumSq2 / count2) - math.pow(sum2 / count2, 2))) : 0.0
vovValue
// Inputs
i_src = input.source(close, "Source")
i_volatilityPeriod = input.int(20, "Volatility Period", minval=1, tooltip="Period for initial volatility calculation.")
i_vovPeriod = input.int(10, "VOV Period", minval=1, tooltip="Period for StDev of the volatility series.")
// Calculation
vovValue = vov(i_src, i_volatilityPeriod, i_vovPeriod)
// Plot
plot(vovValue, "VOV", color=color.yellow, linewidth=2)