mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-31 02:47:44 +00:00
35a6702b06
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.
64 lines
2.7 KiB
Plaintext
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)
|