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)

ChkSqrtRule-001.jpg

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)

ChkSqrtRule-002.jpg

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)

ChkSqrtRule-004.jpg

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

ChkSqrtRule-005.jpg

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"))

ChkSqrtRule-006.jpg

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"))

ChkSqrtRule-007.jpg

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")
  1. 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"))

ChkSqrtRule-009.jpg