Nothing
#
# TTR: Technical Trading Rules
#
# Copyright (C) 2007-2013 Joshua M. Ulrich
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#' Volatility
#'
#' Selected volatility estimators/indicators; various authors.
#'
#' \itemize{
#' \item Close-to-Close Volatility (\code{calc="close"})\cr
#' \deqn{ \sigma_{cl} = \sqrt{\frac{N}{n-2} \sum_{i=1}^{n-1}(r_i-\bar{r})^2}
#' }{sqrt(N) * runSD(ROC(Cl), n-1)}
#' \deqn{where\;\; r_i = \log \left(\frac{C_i}{C_{i-1}}\right) }
#' \deqn{and\;\; \bar{r} = \frac{r_1+r_2+\ldots +r_{n-1}}{n-1} }
#'
#' \item OHLC Volatility: Garman and Klass (\code{calc="garman.klass"})\cr The
#' Garman and Klass estimator for estimating historical volatility assumes
#' Brownian motion with zero drift and no opening jumps (i.e. the opening =
#' close of the previous period). This estimator is 7.4 times more efficient
#' than the close-to-close estimator.\cr
#' \deqn{ \sigma = \sqrt{ \frac{N}{n} \sum
#' \left[ \textstyle\frac{1}{2}\displaystyle
#' \left( \log \frac{H_i}{L_i} \right)^2 - (2\log 2-1)
#' \left( \log \frac{C_i}{O_i} \right)^2 \right] }
#' }{sqrt(N/n * runSum(0.5 * log(Hi/Lo)^2 -
#' (2*log(2)-1) * log(Cl/Op)^2, n))}
#'
#' \item High-Low Volatility: Parkinson (\code{calc="parkinson"})\cr
#' The Parkinson formula for estimating the historical volatility of
#' an underlying based on high and low prices.\cr
#' \deqn{ \sigma = \sqrt{ \frac{N}{4 n \times \log 2} \sum_{i=1}^{n}
#' \left(\log \frac{H_i}{L_i}\right)^2}
#' }{sqrt(N/(4*n*log(2)) * runSum(log(Hi/Lo)^2, n))}
#'
#' \item OHLC Volatility: Rogers and Satchell (\code{calc="rogers.satchell"})\cr
#' The Roger and Satchell historical volatility estimator allows for non-zero
#' drift, but assumed no opening jump.\cr
#' \deqn{ \sigma = \sqrt{ \textstyle\frac{N}{n} \sum \left[
#' \log \textstyle\frac{H_i}{C_i} \times \log \textstyle\frac{H_i}{O_i} +
#' \log \textstyle\frac{L_i}{C_i} \times \log \textstyle\frac{L_i}{O_i} \right] }
#' }{sqrt(N/n * runSum(log(Hi/Cl) * log(Hi/Op) +
#' log(Lo/Cl) * log(Lo/Op), n))}
#'
#' \item OHLC Volatility: Garman and Klass - Yang and Zhang
#' (\code{calc="gk.yz"})\cr This estimator is a modified version of the Garman
#' and Klass estimator that allows for opening gaps.\cr
#' \deqn{ \sigma = \sqrt{ \textstyle\frac{N}{n} \sum \left[
#' \left( \log \textstyle\frac{O_i}{C_{i-1}} \right)^2 +
#' \textstyle\frac{1}{2}\displaystyle
#' \left( \log \textstyle\frac{H_i}{L_i} \right)^2 - (2 \times \log 2-1)
#' \left( \log \textstyle\frac{C_i}{O_i} \right)^2 \right] }
#' }{sqrt(N/n * runSum(log(Op/lag(Cl,1))^2 +
#' 0.5 * log(Hi/Lo)^2 - (2*log(2)-1) * log(Cl/Op)^2 , n))}
#'
#' \item OHLC Volatility: Yang and Zhang (\code{calc="yang.zhang"})\cr The Yang
#' and Zhang historical volatility estimator has minimum estimation error, and
#' is independent of drift and opening gaps. It can be interpreted as a
#' weighted average of the Rogers and Satchell estimator, the close-open
#' volatility, and the open-close volatility.
#'
#' Users may override the default values of \eqn{\alpha} (1.34 by default) or
#' \eqn{k} used in the calculation by specifying \code{alpha} or \code{k} in
#' \code{\dots}, respectively. Specifying \code{k} will cause \code{alpha} to be
#' ignored, if both are provided.\cr
#' \deqn{ \sigma^2 = \sigma_o^2 + k\sigma_c^2 + (1-k)\sigma_{rs}^2
#' }{ s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2)) }
#' \deqn{ \sigma_o^2 =\textstyle \frac{N}{n-1} \sum
#' \left( \log \frac{O_i}{C_{i-1}}-\mu_o \right)^2
#' }{ s2o <- N * runVar(log(Op/lag(Cl,1)), n=n) }
#' \deqn{ \mu_o=\textstyle \frac{1}{n} \sum \log \frac{O_i}{C_{i-1}} }
#' \deqn{ \sigma_c^2 =\textstyle \frac{N}{n-1} \sum
#' \left( \log \frac{C_i}{O_i}-\mu_c \right)^2
#' }{ s2c <- N * runVar(log(Cl/Op), n=n) }
#' \deqn{ \mu_c=\textstyle \frac{1}{n} \sum \log \frac{C_i}{O_i} }
#' \deqn{ \sigma_{rs}^2 = \textstyle\frac{N}{n} \sum \left(
#' \log \textstyle\frac{H_i}{C_i} \times \log \textstyle\frac{H_i}{O_i} +
#' \log \textstyle\frac{L_i}{C_i} \times \log \textstyle\frac{L_i}{O_i}
#' \right)
#' }{ s2rs <- volatility(OHLC, n, "rogers.satchell", N, ...) }
#' \deqn{ k=\frac{\alpha-1}{alpha+\frac{n+1}{n-1}}
#' }{ k <- (alpha-1) / (alpha + (n+1)/(n-1)) }
#' }
#'
#' @aliases volatility garman.klass parkinson rogers.satchell gk.yz yang.zhang
#' @param OHLC Object that is coercible to xts or matrix and contains
#' Open-High-Low-Close prices (or only Close prices, if \code{calc="close"}).
#' @param n Number of periods for the volatility estimate.
#' @param calc The calculation (type) of estimator to use.
#' @param N Number of periods per year.
#' @param mean0 Use a mean of 0 rather than the sample mean.
#' @param \dots Arguments to be passed to/from other methods.
#' @return A object of the same class as \code{OHLC} or a vector (if
#' \code{try.xts} fails) containing the chosen volatility estimator values.
#' @author Joshua Ulrich
#' @seealso See \code{\link{TR}} and \code{\link{chaikinVolatility}} for other
#' volatility measures.
#' @references The following sites were used to code/document these
#' indicators. All were created by Thijs van den Berg under the GNU Free
#' Documentation License and were retrieved on 2008-04-20. The original
#' links are dead, but can be accessed via internet archives.\cr
#' \cr Close-to-Close Volatility (\code{calc="close"}):\cr
#' \url{https://web.archive.org/web/20100421083157/http://www.sitmo.com/eq/172}\cr
#' \cr OHLC Volatility: Garman Klass (\code{calc="garman.klass"}):\cr
#' \url{https://web.archive.org/web/20100326172550/http://www.sitmo.com/eq/402}\cr
#' \cr High-Low Volatility: Parkinson (\code{calc="parkinson"}):\cr
#' \url{https://web.archive.org/web/20100328195855/http://www.sitmo.com/eq/173}\cr
#' \cr OHLC Volatility: Rogers Satchell (\code{calc="rogers.satchell"}):\cr
#' \url{https://web.archive.org/web/20091002233833/http://www.sitmo.com/eq/414}\cr
#' \cr OHLC Volatility: Garman Klass - Yang Zhang (\code{calc="gk.yz"}):\cr
#' \url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\cr
#' \cr OHLC Volatility: Yang Zhang (\code{calc="yang.zhang"}):\cr
#' \url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\cr
#' @keywords ts
#' @examples
#'
#' data(ttrc)
#' ohlc <- ttrc[,c("Open","High","Low","Close")]
#' vClose <- volatility(ohlc, calc="close")
#' vClose0 <- volatility(ohlc, calc="close", mean0=TRUE)
#' vGK <- volatility(ohlc, calc="garman")
#' vParkinson <- volatility(ohlc, calc="parkinson")
#' vRS <- volatility(ohlc, calc="rogers")
#'
"volatility" <-
function(OHLC, n=10, calc="close", N=260, mean0=FALSE, ...) {
OHLC <- try.xts(OHLC, error=as.matrix)
# Choose an arg name that doesn't clash with ROC's 'type' arg
calc <- match.arg(calc,
c("close","garman.klass","parkinson",
"rogers.satchell","gk.yz","yang.zhang"))
# s Volatility
# N Number of closing prices in a year
# n Number of historical prices used for the volatility estimate
# ci The closing price on the ith day
# ri Log return on the ith day
# Historical Close-to-Close Volatility
# http://www.sitmo.com/eq/172
if( calc=="close" ) {
# Add univariate case from Cedrick Johnson's R-SIG-Finance post
if( NCOL(OHLC) == 1 ) {
r <- ROC(OHLC[, 1], 1, ...)
} else {
r <- ROC(OHLC[, 4], 1, ...)
}
if( isTRUE(mean0) ) {
# This is an alternative SD calculation using an effective mean of 0
s <- sqrt(N) * sqrt(runSum(r^2, n-1) / (n-2))
} else {
# This is the standard SD calculation using the sample mean
s <- sqrt(N) * runSD(r, n-1)
}
}
# Historical Open-High-Low-Close Volatility: Garman Klass
# http://www.sitmo.com/eq/402
if( calc=="garman.klass" ) {
s <- sqrt( N/n * runSum( .5 * log(OHLC[,2]/OHLC[,3])^2 -
(2*log(2)-1) * log(OHLC[,4]/OHLC[,1])^2 , n ) )
}
if( calc=="parkinson" ) {
# Historical High-Low Volatility: Parkinson
# http://www.sitmo.com/eq/173
s <- sqrt( N/(4*n*log(2)) * runSum( log(OHLC[,2]/OHLC[,3])^2, n ) )
}
if( calc=="rogers.satchell" ) {
# Historical Open-High-Low-Close Volatility: Rogers Satchell
# http://www.sitmo.com/eq/414
s <- sqrt( N/n * runSum(
log(OHLC[,2]/OHLC[,4]) * log(OHLC[,2]/OHLC[,1]) +
log(OHLC[,3]/OHLC[,4]) * log(OHLC[,3]/OHLC[,1]), n ) )
}
if( calc=="gk.yz" ) {
#if( calc=="garman.klass.yang.zhang" ) {
# Historical Open-High-Low-Close Volatility: Garman and Klass (Yang Zhang)
# http://www.sitmo.com/eq/409
if(is.xts(OHLC)) {
Cl1 <- lag.xts(OHLC[,4])
} else {
Cl1 <- c( NA, OHLC[-NROW(OHLC),4] )
}
s <- sqrt( N/n * runSum(
log(OHLC[,1]/Cl1)^2 +
.5 * log(OHLC[,2]/OHLC[,3])^2 -
(2*log(2)-1) * log(OHLC[,4]/OHLC[,1])^2 , n) )
#s <- sqrt( Z/n * runSum(
# log(op/cl[-1])^2 +
# .5*log(hi/lo)^2 -
# (2*log(2)-1)*log(cl/op)^2 ) )
}
if( calc=="yang.zhang" ) {
# Historical Open-High-Low-Close Volatility: Yang Zhang
# http://www.sitmo.com/eq/417
if(is.xts(OHLC)) {
Cl1 <- lag.xts(OHLC[,4])
} else {
Cl1 <- c( NA, OHLC[-NROW(OHLC),4] )
}
dots <- list(...)
if(is.null(dots$alpha)) {
alpha <- 1.34
}
if(is.null(dots$k)) {
k <- (alpha-1) / ( alpha + (n+1)/(n-1) )
}
s2o <- N * runVar(log(OHLC[,1] / Cl1), n=n)
s2c <- N * runVar(log(OHLC[,4] / OHLC[,1]), n=n)
s2rs <- volatility(OHLC=OHLC, n=n, calc="rogers.satchell", N=N, ...)
s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2))
}
reclass(s,OHLC)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.