Possible enhancement to volatility in TTR
Hi Cedrick,
Sorry for the slow response. How about this quick change to
TTR::volatility() and the code below? I agree that OHLC should be
allowed to be univariate in the case of calc="close". I'm hesitant to
add the other logic though, since the same results can be achieved
with an external call to apply() -- see below.
volatility3 <-
function (OHLC, n = 10, N = 260, calc = "close", ...)
{
<snip>
if (calc == "close") {
# Add univariate case for calc="close"
if (NCOL(OHLC) == 1) {
r <- ROC(OHLC, 1, ...)
} else {
r <- ROC(OHLC[, 4], 1, ...)
}
rBar <- runSum(r, n - 1)/(n - 1)
s <- sqrt(N/(n - 2) * runSum((r - rBar)^2, n - 1))
}
<snip>
reclass(s, OHLC)
}
Then you can get pretty volatilities via a command like:
require(xts) data(sample_matrix) # Pretty volatility (note "v" will always be a matrix, even if OHLC is xts) v <- round(apply(sample_matrix, 2, volatility3)*100,0) tail(v)
Open High Low Close 2007-06-25 6 5 5 6 2007-06-26 6 6 6 6 2007-06-27 6 6 6 6 2007-06-28 6 5 6 5 2007-06-29 5 5 6 5 2007-06-30 5 5 6 5
tail( volatility3(sample_matrix)*100 )
[,1] 2007-06-25 5.656552 2007-06-26 5.729933 2007-06-27 5.732217 2007-06-28 4.771530 2007-06-29 4.764216 2007-06-30 4.818589 HTH, Josh -- http://www.fosstrading.com On Mon, Sep 28, 2009 at 9:34 AM, Cedrick Johnson
<cedrick at cedrickjohnson.com> wrote:
As promised, here's my attempt at incorporating it into the original
volatility() function (for the sake of testing, I've renamed the new
function volatility2(..). Thanks to Murali for the suggestion to use
apply.rolling, I've added in a few new variables in the function definition.
So far it seems to work well here.
volatility2 <- function (OHLC, n = 10, N = 260, calc = "close",
roundValue=FALSE, roundNum=2, normalize=FALSE, nonOHLC=FALSE, ...)
{
??? if (nonOHLC == FALSE) {
??? ??? OHLC <- try.xts(OHLC, error = as.matrix)
??? ??? calc <- match.arg(calc, c("close", "garman.klass", "parkinson",
??? ??????? "rogers.satchell"))
??? ??? if (calc == "close") {
??? ??? ?r <- ROC(OHLC[, 4], 1, ...)
??? ??????? rBar <- runSum(r, n - 1)/(n - 1)
?????? ??? ?s <- sqrt(N/(n - 2) * runSum((r - rBar)^2, n - 1))
??? ??? }
??? ??? if (calc == "garman.klass") {
??? ??????? s <- sqrt(N/n * runSum(0.5 * log(OHLC[, 2]/OHLC[, 3])^2 -
??? ??????????? (2 * log(2) - 1) * log(OHLC[, 4]/OHLC[, 1])^2, n))
??? ??? }
??? ??? if (calc == "parkinson") {
??? ??????? s <- sqrt(N/(4 * n * log(2)) * runSum(log(OHLC[, 2]/OHLC[,
??? ??????????? 3])^2, n))
??? ??? }
??? ??? if (calc == "rogers.satchell") {
??? ??????? 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))
??? ??? }
??? } else {
??? #still using the OHLC object, since this is indeed a matrix
??? # diff(log(OHLC)) provides the same output as ROC(x,1) so we should be
goog. Thanks to Murali Menon
??? # for the suggested use of apply.rolling
??? s <- apply.rolling(R = diff(log(OHLC)), width=n, FUN="sd", na.pad=FALSE)
* sqrt(N)
??? }
??? if (roundValue == TRUE) {
??? s <- round(s, roundNum)
??? }
??? if (normalize == TRUE) {
??? s <- s * 100
??? }
??? reclass(s, OHLC)
}
Cedrick Johnson wrote:
Howdy-
I came up with some code that has served me well, perhaps if anyone runs
into the problem of needing to calculate historical volatility(close) on a
non-OHLC series (or a bunch of "univariate" series stored in a matrix):
?????????? US2Y US5Y US10Y US30Y UKG5 UKG10 USSP2 USSP5 USSP10 USSP30
2009-01-02 0.88 1.72? 2.46? 2.83 2.67? 3.36? 1.50? 2.17?? 2.61?? 2.78
2009-01-05 0.78 1.67? 2.49? 3.00 2.75? 3.47? 1.60? 2.31?? 2.82?? 3.03
2009-01-06 0.80 1.68? 2.51? 3.04 2.79? 3.57? 1.55? 2.34?? 2.88?? 3.18
2009-01-07 0.82 1.66? 2.52? 3.05 2.80? 3.60? 1.44? 2.16?? 2.69?? 2.99
....
blahblah..
I adapted the code to use 'close' from Josh Ulrich's volatility function
(since all of these are closing prices), and here's my result:
volatility.matrix <- function(Matrix, n = 10, N = 252, pretty=TRUE, ...) {
??? volm <- Matrix
??? for(i in 1:ncol(Matrix)) {
??? ??? r <- ROC(Matrix[,i], 1,...)
??? ??? rBar <- runSum(r, n -1)/(n - 1)
??? ??? s <- sqrt(N/(n - 2) * runSum((r - rBar)^2, n - 1))
??? ??? #because i like to make it pretty
??? ??? volm[,i] <- round(s,2) * 100
??? }
??? volm <- na.omit(volm)
??? reclass(volm, Matrix)
}
The Result:
volatility.matrix(Yields, n=30)
?????????? US2Y US5Y US10Y US30Y UKG5 UKG10 USSP2 USSP5 USSP10 USSP30 2009-03-24? 116? 110??? 73??? 45?? 54??? 57??? 67??? 65???? 60???? 51 2009-03-25? 115? 112??? 75??? 46?? 51??? 55??? 67??? 65???? 60???? 51 2009-03-26? 114? 110??? 74??? 44?? 50??? 55??? 65??? 64???? 60???? 50 2009-03-27? 114? 110??? 74??? 44?? 50??? 55??? 67??? 64???? 60???? 51 2009-03-30? 111? 104??? 68??? 39?? 52??? 55??? 67??? 63???? 58???? 51 2009-03-31? 107? 100??? 68??? 39?? 51??? 55??? 67??? 63???? 58???? 50 2009-04-01? 107? 100??? 67??? 38?? 51??? 54??? 67??? 62???? 57???? 49 2009-04-02? 107? 100??? 67??? 37?? 58??? 57??? 65??? 61???? 56???? 48 ...... What I get is a nice matrix of volatilities in a pretty format (rounded, etc.) I'll give it a shot tonight trying to implement it into the current volatility function, however I'm sure the code that I have here could be done better. Regards, c
________________________________ _______________________________________________ R-SIG-Finance at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. -- If you want to post, subscribe first. _______________________________________________ R-SIG-Finance at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. -- If you want to post, subscribe first.