R code: Range-Based Volatility Estimator

This post uses TTR R package to calculate various range-based volatility estimators such as Parkinson (1980), Garman and Klass (1989) and so on.

Riding on volatile waves


Range-Based Volatility



Unlike the standard volatility which is based on the close-to-close prices, the range-based volatility measure is calculated from the intraday information regarding price movements such as high, low or opening and closing prices.

The main advantage of these range-based measures is that they take into account intraday information and, as a consequence, even if two consecutive closing prices were the same, these measures could detect high intraday volatility. There is evidence that the range-based volatility is more efficient than the standard volatility measure and is known to be robust to market microstructure noise.


Daily Range-based volatility measure


Daily Range-based volatility measure (as variance term or squared price range) is the counterpart to the squared return.

The Parkinson (1980) volatility measure is derived by assuming that the asset price follows a simple diffusion model without a drift term. This price range (\(\hat{R}_P\)) or volatility (\(\hat{R}_P^2\)) is defined by using only high and low price in a day.

\[\begin{align} \hat{R}_P^2 = \frac{1}{4 \ln 2}[\ln(H/L)]^2 \end{align}\]
Garman and Klass (1980) extend it by including additional two data points (O, C).

\[\begin{align} \hat{R}_{GK}^2 = 0.5 [\ln(H/L)]^2 - [2 \ln2 - 1][\ln(C/O)]^2 \end{align}\]
Besides, there are another type of the range-based volatilities such as Rogers and Satchell (1991), Yang and Zhang (2000), and so on.


Range-based volatility estimator


Range-based volatility estimator is the counterpart to the standard deviation.

The Parkinson (1980)

\[\begin{align} \hat{\sigma}_P = \sqrt{\frac{Z}{4 \ln 2} \sum_{i=1}^{n} {[\ln(H_i/L_i)]^2}} \end{align}\]
Garman and Klass (1980)

\[\begin{align} \hat{\sigma}_{GK} = \sqrt{\frac{Z}{n} \sum_{i=1}^{n} \left( 0.5 [\ln(H_i/L_i)]^2 - [2 \ln2 - 1][\ln(C_i/O_i)]^2 \right)} \end{align}\]
here \(Z\) is the number of closing prices in a year and \(n\) is the number of historical days use in the volatility estimate. \(Z\) is just an annualized factor, for example, \(\sqrt{Z} = \sqrt{252} \).


Specification of volatility() function


TTR R package provides the volatility() function to calculate the range-based volatility estimators including Parkinson, Garman-Klass, and so on.


volatility(OHLC, n = 10, calc = "close", N = 260, mean0 = FALSE, ...)

  • OHLC : Object that is coercible to xts or matrix and contains Open-High-Low-Close prices (or only Close prices, if calc="close")
  • n : Number of periods for the volatility estimate
  • calc : The calculation (type) of estimator to use ("close", "parkinson", "garman.klass", "rogers.satchell", "yang.zhang", "gk.yz")
  • N : Number of periods per year
  • mean0 : Use a mean of 0 rather than the sample mean
  • ... : Additional information



R code


The following R code use volatility() function to calculate rolling range-based volatilities with a window width of 25 and an annualized factor of 252.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#========================================================#
# Quantitative ALM, Financial Econometrics & Derivatives 
# ML/DL using R, Python, Tensorflow by Sang-Heon Lee 
#
# https://shleeai.blogspot.com
#--------------------------------------------------------#
# Range-based volatility estimator
#========================================================#
 
graphics.off(); rm(list = ls())
 
library(TTR)
library(quantmod)
 
# the 25-day rolling volatility of 
# the S&P 500 from 2007 onwards
getSymbols("SPY",from="2007/01/01")
ohlc <- SPY[,1:4]
colnames(ohlc) <- c("Open","High","Low","Close")
 
# n=25  : 25 day rolling volatility 
# N=252 : a year has 252 days
vCl <- volatility(ohlc, n=25, N=252, calc="close")
vGK <- volatility(ohlc, n=25, N=252, calc="garman")
vPk <- volatility(ohlc, n=25, N=252, calc="parkinson")
 
# draw graph
x11(width=6, height=8)
par(mfcol=c(4,1) , mar=c(3,4,2,2))
plot(ohlc[,4] , ylab = "", xlab="", main = "S&P index")    
plot(vCl, ylim = c(0,1), main = "close-to-close")   
plot(vPk, ylim = c(0,1), main = "Parkinson")   
plot(vGK, ylim = c(0,1), main = "Garman & Klass")    
 
cs

We can draw plots of these rolling volatilities.
R code: Range-Based Volatility Estimator


Concluding Remarks


This post introduces TTR R package to calculate various range-based volatility estimators. These are alternatives of squared return or standard deviation. Naturally, stochastic volatility or GARCH version of the ranged volatility are also developed by many researchers. \(\blacksquare\)


No comments:

Post a Comment

Tentative Topics (Keeping Track to Avoid Forgetting)

Segmented Nelson-Siegel model
Shifting Endpoints Nelson-Siegel model
Nadaraya-Watson estimator
Locally weighted scatterplot smoothing (LOWESS)
Time-Varying Parameter Vector Autoregressions (TVP-VAR)
Time-varying or Dynamic Copula
Bayesian VAR
Adrian-Crump-Moench (ACM) term premium model
GARCH-EVT-Copula approach