Files
QuanTAlib/lib/volatility/hlv/hlv.pine
T
Miha Kralj 86fe32a682 SIMD Refactor: Merge simd-dev into dev (#55)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
Co-authored-by: Warp <agent@warp.dev>
2026-01-18 19:02:03 -08:00

43 lines
2.3 KiB
Plaintext

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("High-Low Volatility (HLV)", "HLV", overlay=false)
//@function Calculates High-Low Volatility based on the Parkinson number.
//@param length The period length for smoothing the Parkinson estimator.
//@param annualize Boolean to indicate if the volatility should be annualized. Default is true.
//@param annualPeriods Number of periods in a year for annualization. Default is 252 for daily data.
//@returns float The High-Low Volatility value.
//@optimized for performance and dirty data
hlv(simple int length, simple bool annualize = true, simple int annualPeriods = 252) =>
if length <= 0
runtime.error("Length must be greater than 0")
if annualize and annualPeriods <= 0
runtime.error("Annual periods must be greater than 0 if annualizing")
float lnH = math.log(high), float lnL = math.log(low)
float C_4LN2_INV = 0.3606737602 // 1.0 / (4.0 * math.log(2.0))
float parkinsonEstimator = C_4LN2_INV * math.pow(lnH - lnL, 2)
var float raw_rma_parkinson = 0.0, var float e_rma = 1.0
float rma_alpha = 1.0 / float(length)
if not na(parkinsonEstimator)
raw_rma_parkinson := na(raw_rma_parkinson[1]) ? parkinsonEstimator : (nz(raw_rma_parkinson[1], parkinsonEstimator) * (length - 1) + parkinsonEstimator) / length
e_rma := na(e_rma[1]) ? (1.0 - rma_alpha) : (1.0 - rma_alpha) * nz(e_rma[1], 1.0)
float EPSILON = 1e-10
float corrected_rma_parkinson = e_rma > EPSILON and not na(raw_rma_parkinson) ? raw_rma_parkinson / (1.0 - e_rma) : raw_rma_parkinson
float smoothedParkinsonEstimator = nz(corrected_rma_parkinson, parkinsonEstimator)
float volatility = smoothedParkinsonEstimator < 0 ? na : math.sqrt(smoothedParkinsonEstimator)
annualize and not na(volatility) ? volatility * math.sqrt(float(annualPeriods)) : volatility
// ---------- Main loop ----------
// Inputs
i_length = input.int(20, "Length", minval=1, tooltip="Period for smoothing the Parkinson estimator")
i_annualize = input.bool(true, "Annualize Volatility", tooltip="Annualize the volatility output")
i_annualPeriods = input.int(252, "Annual Periods", minval=1, tooltip="Number of periods in a year for annualization (e.g., 252 for daily, 52 for weekly)")
// Calculation
hlvValue = hlv(i_length, i_annualize, i_annualPeriods)
// Plot
plot(hlvValue, "HLV", color=color.yellow, linewidth=2)