Nothing
## ----'preamble', include=FALSE, warning=FALSE, message=FALSE, cache=FALSE----
library(knitr)
# set the knitr options ... for everyone!
# if you unset this, then vignette build bonks. oh, joy.
#opts_knit$set(progress=TRUE)
opts_knit$set(eval.after='fig.cap')
# for a package vignette, you do want to echo.
# opts_chunk$set(echo=FALSE,warning=FALSE,message=FALSE)
opts_chunk$set(warning=FALSE,message=FALSE)
#opts_chunk$set(results="asis")
opts_chunk$set(cache=TRUE,cache.path="cache/MarkowitzR")
#opts_chunk$set(fig.path="figure/",dev=c("pdf","cairo_ps"))
opts_chunk$set(fig.path="figure/MarkowitzR",dev=c("pdf"))
opts_chunk$set(fig.width=4.5,fig.height=4,dpi=300)
# doing this means that png files are made of figures;
# the savings is small, and it looks like shit:
#opts_chunk$set(fig.path="figure/",dev=c("png","pdf","cairo_ps"))
#opts_chunk$set(fig.width=4,fig.height=4)
# for figures? this is sweave-specific?
#opts_knit$set(eps=TRUE)
# this would be for figures:
#opts_chunk$set(out.width='.8\\textwidth')
# for text wrapping:
options(width=64,digits=2)
opts_chunk$set(size="small")
opts_chunk$set(tidy=TRUE,tidy.opts=list(width.cutoff=50,keep.blank.line=TRUE))
compile.time <- Sys.time()
# from the environment
# only recompute if FORCE_RECOMPUTE=True w/out case match.
FORCE_RECOMPUTE <-
(toupper(Sys.getenv('FORCE_RECOMPUTE',unset='False')) == "TRUE")
# compiler flags!
# not used yet
LONG.FORM <- FALSE
mc.resolution <- ifelse(LONG.FORM,1000,200)
mc.resolution <- max(mc.resolution,100)
library(MarkowitzR)
gen_norm <- rnorm
lseq <- function(from,to,length.out) {
exp(seq(log(from),log(to),length.out = length.out))
}
## ----'the_proc',echo=TRUE,cache=FALSE-------------------------
require(gtools)
# set the colnames of X appropriately
set.coln <- defmacro(X,expr={
if (is.null(colnames(X))) {
colnames(X) <- paste0(deparse(substitute(X),nlines=1),1:(dim(X)[2]))
}})
# compute Wald scores via this trick
wrap.itheta <- function(rets,ret.what=c('wald','mp'),...) {
set.coln(rets)
ret.what <- match.arg(ret.what)
# 'flipping the sign on returns is idiomatic'
asymv <- itheta_vcov(- as.matrix(rets),...)
qidx <- 2:asymv$pp
mp <- asymv$mu[qidx]
stat <- switch(ret.what,
mp = mp,
wald = mp / sqrt(diag(asymv$Ohat[2:asymv$pp,2:asymv$pp])))
names(stat) <- colnames(rets)
return(stat)
}
wrap.mp <- function(rets,ret.what=c('wald','mp'),...) {
set.coln(rets)
ret.what <- match.arg(ret.what)
asymv <- mp_vcov(as.matrix(rets),...)
mp <- t(asymv$W)
stat <- switch(ret.what,
mp = mp,
wald = mp / sqrt(diag(asymv$What)))
return(stat)
}
# t-stat via Britten-Jones procedure
bjones.ts <- function(rets) {
set.coln(rets)
ones.vec <- matrix(1,nrow=dim(rets)[1],ncol=1)
rets <- as.matrix(rets)
bjones.mod <- lm(ones.vec ~ rets - 1)
bjones.sum <- summary(bjones.mod)
retval <- bjones.sum$coefficients[,3]
names(retval) <- colnames(rets)
return(retval)
}
# compare the procedures
do.both <- function(rets,...) {
set.coln(rets)
retval <- rbind(bjones.ts(rets),wrap.itheta(rets,...))
rownames(retval) <- c("Britten Jones t-stat","via itheta_vcov")
return(retval)
}
do.all <- function(rets,...) {
set.coln(rets)
retval <- do.both(rets,...)
retval <- rbind(retval,wrap.mp(rets,...))
rownames(retval)[dim(retval)[1]] <- "via mp_vcov"
return(retval)
}
n.day <- 1000
n.stock <- 5
## ----'me_vs_bjones',echo=TRUE---------------------------------
# under the null: all returns are zero mean;
set.seed(as.integer(charToRaw("7af85b0b-e521-4059-bebe-55ad9a9a0456")))
rets <- matrix(rnorm(n.day * n.stock),nrow=n.day)
# compare them:
print(do.all(rets))
# returns under the alternative
set.seed(as.integer(charToRaw("464dcbea-375b-49d0-8f38-b48b5a33c7ea")))
rets <- matrix(rnorm(n.day * n.stock,mean=1e-1),nrow=n.day)
print(do.all(rets))
## ----'get_mp',echo=TRUE---------------------------------------
# returns under the alternative
set.seed(as.integer(charToRaw("464dcbea-375b-49d0-8f38-b48b5a33c7ea")))
rets <- matrix(rnorm(n.day * n.stock,mean=1e-1),nrow=n.day)
print(wrap.itheta(rets,ret.what='mp'))
## ----'multiple_correlation',echo=TRUE,cache=FALSE-------------
# multiple correlation coefficients of portfolio
# error to precision errors.
mult.cor <- function(rets,...) {
set.coln(rets)
# 'flipping the sign on returns is idiomatic'
asymv <- itheta_vcov(- as.matrix(rets),...)
Ro <- cov2cor(asymv$Ohat)
prec.idx <- (asymv$p+1):(dim(asymv$Ohat)[1])
prec.Ro <- Ro[prec.idx,prec.idx]
xcor <- Ro[2:asymv$p,prec.idx]
R.sq <- diag(xcor %*% (solve(prec.Ro,t(xcor))))
}
set.seed(as.integer(charToRaw("464dcbea-375b-49d0-8f38-b48b5a33c7ea")))
rets <- matrix(rnorm(n.day * n.stock,mean=8e-2),nrow=n.day)
print(signif(100 * mult.cor(rets),digits=2))
## ----'multiple_correlation2',echo=TRUE,cache=FALSE------------
set.seed(as.integer(charToRaw("464dcbea-375b-49d0-8f38-b48b5a33c7ea")))
rets <- matrix(rnorm(n.day * n.stock,mean=1.6e-1),nrow=n.day)
print(signif(100 * mult.cor(rets),digits=2))
## ----'conditional',echo=TRUE----------------------------------
# generate data with given W, Sigma
Xgen <- function(W,Sigma,Feat) {
Btrue <- Sigma %*% W
Xmean <- Feat %*% t(Btrue)
Shalf <- chol(Sigma)
X <- Xmean + matrix(rnorm(prod(dim(Xmean))),ncol=dim(Xmean)[2]) %*% Shalf
}
n.feat <- 4
n.ret <- 8
n.obs <- 2000
set.seed(12321)
Feat <- matrix(rnorm(n.obs * n.feat),ncol=n.feat)
Wtrue <- 10 * matrix(rnorm(n.feat * n.ret),ncol=n.feat)
Sigma <- cov(matrix(rnorm(100*n.ret),ncol=n.ret))
Sigma <- Sigma + diag(seq(from=1,to=3,length.out=n.ret))
X <- Xgen(Wtrue,Sigma,Feat)
ism <- mp_vcov(X,feat=Feat,fit.intercept=TRUE)
# a bit of legerdemain b/c there's an intercept term
# fit
Wcomp <- cbind(0,Wtrue)
## ----'scatfit',echo=TRUE,cache=FALSE,fig.cap=paste("Scatter of the fit value against the true value of the Markowitz Coefficien is shown, for",n.ret,"assets, and",n.feat,"predictive features, given",n.obs,"days of observations of Gaussian returns. The $y=x$ line is plotted in green.")----
# scatter them against each other
w.true <- Wcomp
w.fit <- ism$W
dim(w.true) <- c(length(w.true),1)
dim(w.fit) <- c(length(w.fit),1)
plot(w.true, w.fit, main="Markowitz coefficient",
xlab="True Value ", ylab="Fit Value ", pch=1)
#abline(lm(w.fit ~ w.true), col="red")
abline(a=0,b=1, col="green")
## ----'check_normality',echo=TRUE,cache=FALSE,fig.cap=paste("Sample quantiles of the error of the \\txtMC, transformed to approximate unit covariance using the estimated covariance, are plotted against those of the normal.")----
n.feat <- 4
n.ret <- 8
n.obs <- 2000
set.seed(12321)
Feat <- matrix(rnorm(n.obs * n.feat),ncol=n.feat)
Wtrue <- 10 * matrix(rnorm(n.feat * n.ret),ncol=n.feat)
Sigma <- cov(matrix(rnorm(100*n.ret),ncol=n.ret))
Sigma <- Sigma + diag(seq(from=1,to=3,length.out=n.ret))
X <- Xgen(Wtrue,Sigma,Feat)
ism <- mp_vcov(X,feat=Feat,fit.intercept=TRUE)
Wcomp <- cbind(0,Wtrue)
# compute the errors
errs <- ism$W - Wcomp
dim(errs) <- c(length(errs),1)
# transform them to approximately identity covariance
Zerr <- solve(t(chol(ism$What)),errs)
# did it work?
qqnorm(Zerr)
qqline(Zerr,col=2)
## ----'cons_zero',echo=TRUE,cache=FALSE------------------------
# first for the case where the real Markowitz Portfolio is actually
# just 'the market': equal dollar long in each stock.
set.seed(as.integer(charToRaw("dbeebe3f-da7e-4d11-b014-feac88a1d6cb")))
rets <- matrix(rnorm(n.day * n.stock,mean=1e-1),nrow=n.day)
Jmat <- matrix(c(1,1,1,-1),nrow=2,ncol=2*n.stock) # overbuilt
Jmat <- Jmat[,1:n.stock] # fixed.
print(Jmat)
# first, unconstrained:
print(wrap.mp(rets))
# now with subspace constraint:
print(wrap.mp(rets,Jmat=Jmat))
# and print the portfolio too:
print(wrap.mp(rets,ret.what='mp',Jmat=Jmat))
# now for the case where the real Markowitz portfolio is not just the market.
set.seed(as.integer(charToRaw("420f1dfd-b19b-4175-83b3-b96548264bf8")))
rets <- matrix(rnorm(n.day * n.stock,mean=0),nrow=n.day)
mu.off <- t(matrix(seq(from=-0.15,to=0.15,length.out=n.stock),nrow=n.stock,ncol=n.day))
rets <- rets + mu.off
print(wrap.mp(rets,Jmat=Jmat))
# and print the portfolio too:
print(wrap.mp(rets,ret.what='mp',Jmat=Jmat))
## ----'cons_one',echo=TRUE,cache=FALSE-------------------------
# first for the case where the real Markowitz Portfolio is actually
# equal dollar long in each stock.
set.seed(as.integer(charToRaw("0bda3ab6-53a7-4f5a-aa6a-0fe21edbaa20")))
rets <- matrix(rnorm(n.day * n.stock,mean=1e-1),nrow=n.day)
Gmat <- matrix(1,nrow=1,ncol=n.stock)
print(wrap.mp(rets,Gmat=Gmat))
# and print the portfolio too:
print(wrap.mp(rets,ret.what='mp',Gmat=Gmat))
# and in the case where it is not.
set.seed(as.integer(charToRaw("420f1dfd-b19b-4175-83b3-b96548264bf8")))
rets <- matrix(rnorm(n.day * n.stock,mean=0),nrow=n.day)
mu.off <- t(matrix(seq(from=-0.8,to=0.8,length.out=n.stock),nrow=n.stock,ncol=n.day))
rets <- rets + mu.off
Gmat <- matrix(1,nrow=1,ncol=n.stock)
print(wrap.mp(rets,Gmat=Gmat))
# and print the portfolio too:
print(wrap.mp(rets,ret.what='mp',Gmat=Gmat))
## ----'rao_giri',echo=TRUE,eval=TRUE---------------------------
rao.giri <- function(rets,Gmat,...) {
set.coln(rets)
asymv <- mp_vcov(as.matrix(rets),Gmat=Gmat,...)
stat <- asymv$mu[1]
a.var <- asymv$Ohat[1,1]
return(list(stat=stat,a.var=a.var,wald=stat/sqrt(a.var)))
}
# here we hedge out G, the rows of which span the true
# Markowitz portfolio
set.seed(as.integer(charToRaw("4618fc2e-9c58-4ea7-81f7-6ed771ace500")))
rets <- matrix(rnorm(n.day * n.stock,mean=1e-1),nrow=n.day)
Gmat <- matrix(1,nrow=1,ncol=n.stock)
print(rao.giri(rets,Gmat)$wald)
# here we hedge out a random G, the rows of which do not
# span the true Markowitz portfolio
set.seed(as.integer(charToRaw("4abaccd9-8cac-4149-b30d-f3b4d32b44df")))
rets <- matrix(rnorm(n.day * n.stock,mean=1e-1),nrow=n.day)
Gmat <- matrix(rnorm(n.stock),nrow=1,ncol=n.stock)
print(rao.giri(rets,Gmat)$wald)
## ----'ff_load',eval=FALSE,echo=TRUE---------------------------
# ff.data <- read.csv(paste0('http://www.quandl.com/api/v1/datasets/',
# 'KFRENCH/FACTORS_M.csv?&trim_start=1926-07-31&trim_end=2013-10-31',
# '&sort_order=asc'), colClasses=c('Month'='Date'))
#
# rownames(ff.data) <- ff.data$Month
# ff.data <- ff.data[,! (colnames(ff.data) %in% c("Month"))]
# # will not matter, but convert pcts:
# ff.data <- 1e-2 * ff.data
## ----'ff_load_sneaky',eval=TRUE,echo=FALSE--------------------
# sleight of hand to load precomputed data instead.
fname <- system.file('extdata','ff_data.rda',package='MarkowitzR')
if (fname == "") {
fname <- 'ff_data.rda'
}
# poofs ff.data here
load(fname)
## ----'ff_process',echo=TRUE,cachc=TRUE------------------------
rfr <- ff.data[,'RF']
ff.ret <- cbind(ff.data[,'Mkt.RF'],
ff.data[,c('HML','SMB')] - rep(rfr,2))
colnames(ff.ret)[1] <- "MKT"
# try both procedures:
print(do.both(ff.ret))
# try with robust s.e.
if (require(sandwich)) {
print(do.both(ff.ret,vcov.func=sandwich::vcovHAC))
}
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.