Files

67 lines
2.2 KiB
Plaintext
Raw Permalink Normal View History

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Close-to-Close Volatility (CCV)", "CCV", overlay=false)
//@function Calculates Close-to-Close Volatility using closing price returns
//@param length Period for volatility calculations
//@param method Smoothing method (1=SMA, 2=EMA, 3=WMA)
//@returns float Volatility value
//@optimized Beta precomputation for RMA warmup compensation
ccv(simple int length, simple int method) =>
var int p = math.max(1, length)
var int head = 0
var int count = 0
var array<float> buffer = array.new_float(p, na)
var float sum = 0.0
var float wsum = 0.0
float priceReturn = math.log(close / close[1])
float oldest = array.get(buffer, head)
if not na(oldest)
sum -= oldest
count -= 1
sum += priceReturn
count += 1
array.set(buffer, head, priceReturn)
head := (head + 1) % p
float mean = nz(sum / count)
float squaredSum = 0.0
for i = 0 to length - 1
float val = array.get(buffer, (head - i - 1 + p) % p)
if not na(val)
squaredSum += math.pow(val - mean, 2)
float annualizedStdDev = math.sqrt(squaredSum / count) * math.sqrt(252)
float alpha = 1.0 / float(length)
float beta = 1.0 - alpha
var float EPSILON = 1e-10
var float raw_rma = 0.0
var float e = 1.0
float result = na
if method == 1
result := annualizedStdDev
else if method == 2
raw_rma := (raw_rma * (length - 1) + annualizedStdDev) / length
e *= beta
result := e > EPSILON ? raw_rma / (1.0 - e) : raw_rma
else
float sumWeight = length * (length + 1) / 2
float weightedSum = 0.0
float weight = length
for i = 0 to length - 1
weightedSum += annualizedStdDev * weight
weight -= 1.0
result := weightedSum / sumWeight
result
// ---------- Main loop ----------
// Inputs
i_length = input.int(20, "Length", minval=1, maxval=500, tooltip="Number of bars for volatility calculation")
i_method = input.int(1, "Method", minval=1, maxval=3, tooltip="1=SMA, 2=EMA, 3=WMA")
// Calculation
ccvValue = ccv(i_length, i_method)
// Plot
plot(ccvValue, "CCV", color=color.yellow, linewidth=2)