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