Checking Square Root Rule
Purpose
To check the square root rule for NIFTYBeES volatility and check for daily , weekly, monthly , yearly returns and see whether location dispersion ellipsoid can be used to verify the rule
NIFTY BeES
> library(xts) > nifty_jnr <- read.csv("C:/Cauldron/garage/R/soulcraft/Volatility/Learn/AttilioMeucci/nifty_jnr.csv", + header = T, stringsAsFactors = F) > nifty_jnr$trade.date <- as.Date(nifty_jnr[, 1], format = "%d-%b-%y") > nifty_jnr <- xts(nifty_jnr[, 2:3], nifty_jnr$trade.date) > par(mfrow = c(2, 1)) > plot(nifty_jnr[, 1], main = "NIFTY", , major.ticks = "months", + minor.ticks = FALSE) > plot(nifty_jnr[, 2], main = "NIFTY Junior", major.ticks = "months", + minor.ticks = FALSE) |
Daily Returns and Daily Covariance Matrix
> library(fPortfolio) > daily.ret <- as.xts(returns(nifty_jnr)[-1, ]) > par(mfrow = c(2, 1)) > plot(daily.ret[, 1], main = "NIFTY", major.ticks = "months", + minor.ticks = FALSE) > plot(daily.ret[, 2], main = "NIFTY Jnr", major.ticks = "months", + minor.ticks = FALSE) |
TwoDimEllipsoid Function
> TwoDimEllipsoid <- function(sample.mean, sample.cov, Scale, x, + main) { + x1 <- sample.mean[1] - sqrt(sample.cov[1, 1]) * Scale + x2 <- sample.mean[1] + sqrt(sample.cov[1, 1]) * Scale + y1 <- sample.mean[2] + sqrt(sample.cov[2, 2]) * Scale + y2 <- sample.mean[2] - sqrt(sample.cov[2, 2]) * Scale + vecs <- eigen(sample.cov)$vectors + evals <- eigen(sample.cov)$values + length1 <- sqrt(evals[1]) + length2 <- sqrt(evals[2]) + angles <- seq(from = 0, to = 2 * pi, by = pi/500) + ang.points <- matrix(data = NA, nrow = length(angles), ncol = 2) + for (i in seq_along(angles)) { + ang.points[i, 1] <- (cos(angles[i])) * sqrt(evals[1]) * + Scale + ang.points[i, 2] <- (sin(angles[i])) * sqrt(evals[2]) * + Scale + } + ellipsoid <- matrix(data = NA, nrow = dim(x)[1], ncol = 2) + ellipsoid <- (ang.points %*% t(vecs)) + ellipsoid[, 1] <- (ellipsoid[, 1]) + sample.mean[1] + ellipsoid[, 2] <- (ellipsoid[, 2]) + sample.mean[2] + return(ellipsoid) + } |
> daily.ret <- as.xts(returns(nifty_jnr)[-1, ]) > daily.mean <- colMeans(daily.ret) > daily.cov <- cov(daily.ret) |
Calculate weekly , monthly , quarterly and annual returns
> nifty_jnr.wk <- cbind(to.weekly(nifty_jnr[, 1]), to.weekly(nifty_jnr[, + 2]))[, c(4, 8)] > nifty_jnr.mon <- cbind(to.monthly(nifty_jnr[, 1]), to.monthly(nifty_jnr[, + 2]))[, c(4, 8)] > nifty_jnr.wk.ret <- (returns(nifty_jnr.wk)[-1, ]) > nifty_jnr.mon.ret <- (returns(nifty_jnr.mon)[-1, ]) > head(nifty_jnr.wk.ret) nifty_jnr...1..Close nifty_jnr...2..Close 2005-01-14 -0.042777515 -0.042965078 2005-01-20 -0.003007989 -0.011145791 2005-01-28 0.042206793 0.024337378 2005-02-04 0.034093238 0.039122739 2005-02-11 0.001971154 0.003336688 2005-02-18 -0.012809533 -0.014883536 |
Comparision of Aggregated Daily and Weekly returns
> sample.mean <- daily.mean * 5 > sample.cov <- daily.cov * 5 > z1 <- TwoDimEllipsoid(sample.mean, sample.cov, 4, coredata(daily.ret * + 5), "Daily Returns Modif") > weekly.mean <- colMeans(nifty_jnr.wk.ret) > weekly.cov <- cov(nifty_jnr.wk.ret) > sample.mean <- weekly.mean > sample.cov <- weekly.cov > sample.data <- nifty_jnr.wk.ret > z2 <- TwoDimEllipsoid(sample.mean, sample.cov, 4, sample.data, + "Weekly Returns") > par(mfrow = c(1, 1)) > plot(z1, xlim = c(-0.2, 0.2), col = "red", xlab = "", ylab = "", + ylim = c(-0.2, 0.2)) > par(new = T) > plot(z2, xlim = c(-0.2, 0.2), col = "blue", xlab = "", ylab = "", + ylim = c(-0.2, 0.2)) > legend("topleft", legend = c("Weekly agg", "Monthly"), fill = c("red", + "blue")) |
Comparision of Aggregated Daily and Monthly returns
> head(nifty_jnr.mon.ret) nifty_jnr...1..Close nifty_jnr...2..Close Feb 2005 0.02194351 0.032517918 Mar 2005 -0.03266859 -0.026099931 Apr 2005 -0.06764637 -0.060443358 May 2005 0.09282232 0.081139260 Jun 2005 0.06178630 0.006554181 Jul 2005 0.04046527 0.113056315 > monthly.mean <- colMeans(nifty_jnr.mon.ret) > monthly.cov <- cov(nifty_jnr.mon.ret) > sample.mean <- monthly.mean > sample.cov <- monthly.cov > sample.data <- nifty_jnr.mon.ret > z3 <- TwoDimEllipsoid(sample.mean, sample.cov, 4, sample.data, + "Weekly Returns") > sample.mean <- daily.mean * 20 > sample.cov <- daily.cov * 20 > z4 <- TwoDimEllipsoid(sample.mean, sample.cov, 4, coredata(daily.ret * + 5), "Daily Returns Modif") > par(mfrow = c(1, 1)) > plot(z4, xlim = c(-0.6, 0.6), col = "red", xlab = "", ylab = "", + ylim = c(-0.6, 0.6)) > par(new = T) > plot(z3, xlim = c(-0.6, 0.6), col = "blue", xlab = "", ylab = "", + ylim = c(-0.6, 0.6)) > legend("topleft", legend = c("Daily agg", "Monthly"), fill = c("red", + "blue")) |
As the ellipses are close by, it looks like the square root vol rule applies to equities The whole purpose of this exercise is to check whether the square root rule can be applied to weekly aggregated and rolling annualized returns
Preparing annualized returns
> annualized.returns <- function(x) { + n <- length(x) + (x[n] - x[1])/x[1] + } > nifty.ret.roll.y <- cbind(rollapply(nifty_jnr[, 1], width = 252, + annualized.returns, align = "right"), rollapply(nifty_jnr[, + 2], width = 252, annualized.returns, align = "right")) > annualized <- coredata(nifty.ret.roll.y) > annualized <- annualized[is.finite(annualized[, 1]) & is.finite(annualized[, + 2]), ] > plot(annualized) > weekly.mean <- colMeans(nifty_jnr.wk.ret) > weekly.cov <- cov(nifty_jnr.wk.ret) > sample.mean <- weekly.mean * 52 > sample.cov <- weekly.cov * 52 > sample.data <- nifty_jnr.wk.ret > z2 <- TwoDimEllipsoid(sample.mean, sample.cov, 4, sample.data, + "Weekly Returns") > yearly.mean <- colMeans(annualized) > yearly.cov <- cov(annualized) > sample.mean <- yearly.mean > sample.cov <- yearly.cov > sample.data <- annualized > z3 <- TwoDimEllipsoid(sample.mean, sample.cov, 4, sample.data, + "Weekly Returns") |
- After working for 2 hours ,I finally see the ellipsoid which shows that it is not ok to just multiply the weekly risk and return by 52 to get annualized risk and return
> par(mfrow = c(1, 1)) > plot(z2, xlim = c(-2, 2), col = "red", xlab = "", ylab = "", + ylim = c(-2, 3)) > par(new = T) > plot(z3, xlim = c(-2, 2), col = "blue", xlab = "", ylab = "", + ylim = c(-2, 3)) > legend("topleft", legend = c("Weekly agg", "Annualized Rolling"), + fill = c("red", "blue")) |