mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-27 17:27:43 +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.
58 lines
2.8 KiB
Plaintext
58 lines
2.8 KiB
Plaintext
// Licensed under the Apache License, Version 2.0
|
|
// © mihakralj
|
|
//@version=6
|
|
indicator("Historical Volatility (HV)", "HV", overlay=false)
|
|
|
|
//@function Calculates Historical Volatility (Close-to-Close).
|
|
//@param src_price The source series to calculate returns from. Default is close.
|
|
//@param length_hv The period length for calculating the standard deviation of returns.
|
|
//@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 Historical Volatility value.
|
|
//@optimized for performance and dirty data
|
|
hv(series float src_price, simple int length_hv, simple bool annualize = true, simple int annualPeriods = 252) =>
|
|
var array<float> _buffer_hv = array.new_float(length_hv, na)
|
|
var int _head_idx_hv = 0
|
|
var int _current_fill_count_hv = 0
|
|
var float _sum_val_hv = 0.0
|
|
var float _sum_sq_val_hv = 0.0
|
|
float logReturn = na(src_price[1]) or src_price[1] == 0 ? na : math.log(src_price / nz(src_price[1], src_price))
|
|
float stdDevLogReturns = na
|
|
if not na(logReturn)
|
|
float _oldest_val_in_buffer_hv = array.get(_buffer_hv, _head_idx_hv)
|
|
if not na(_oldest_val_in_buffer_hv)
|
|
_sum_val_hv -= _oldest_val_in_buffer_hv
|
|
_sum_sq_val_hv -= _oldest_val_in_buffer_hv * _oldest_val_in_buffer_hv
|
|
_current_fill_count_hv -= 1
|
|
float _current_log_return_val = nz(logReturn)
|
|
_sum_val_hv += _current_log_return_val
|
|
_sum_sq_val_hv += _current_log_return_val * _current_log_return_val
|
|
_current_fill_count_hv += 1
|
|
array.set(_buffer_hv, _head_idx_hv, _current_log_return_val)
|
|
_head_idx_hv := (_head_idx_hv + 1) % length_hv
|
|
if _current_fill_count_hv > 1
|
|
float _variance_hv = (_sum_sq_val_hv / _current_fill_count_hv) - math.pow(_sum_val_hv / _current_fill_count_hv, 2)
|
|
stdDevLogReturns := math.sqrt(math.max(0.0, _variance_hv))
|
|
else
|
|
stdDevLogReturns := 0.0
|
|
else
|
|
stdDevLogReturns := na
|
|
float volatility = stdDevLogReturns
|
|
if annualize and not na(volatility)
|
|
volatility := volatility * math.sqrt(float(annualPeriods))
|
|
volatility
|
|
|
|
// ---------- Main loop ----------
|
|
|
|
// Inputs
|
|
i_source = input.source(close, "Source")
|
|
i_length = input.int(20, "Length", minval=2, tooltip="Period for calculating standard deviation of returns")
|
|
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
|
|
hvValue = hv(i_source, i_length, i_annualize, i_annualPeriods)
|
|
|
|
// Plot
|
|
plot(hvValue, "HV", color=color.yellow, linewidth=2)
|