mp_vcov {MarkowitzR}R Documentation

Estimate Markowitz Portfolio

Description

Estimates the Markowitz Portfolio or Markowitz Coefficient subject to subspace and hedging constraints, and heteroskedasticity.

Usage

mp_vcov(X,feat=NULL,vcov.func=vcov,fit.intercept=TRUE,weights=NULL,Jmat=NULL,Gmat=NULL)

Arguments

X

an n \times p matrix of observed returns.

feat

an n \times f matrix of observed features. defaults to none, in which case fit.intercept must be TRUE. If fit.intercept is true, ones will be prepended to the features.

vcov.func

a function which takes an object of class lm, and computes a variance-covariance matrix. If equal to the string "normal", we assume multivariate normal returns.

fit.intercept

a boolean controlling whether we add a column of ones to the data, or fit the raw uncentered second moment. For now, must be true when assuming normal returns.

weights

an optional n vector of the weights. The returns and features will be multiplied by the weights. Weights should be inverse volatility estimates. Defaults to homoskedasticity.

Jmat

an optional p_j \times p matrix of the subspace in which we constrain portfolios. Defaults essentially to the p \times p identity matrix.

Gmat

an optional p_g \times p matrix of the subspace to which we constrain portfolios to have zero covariance. The rowspace of Gmat must be spanned by the rowspace of Jmat. Defaults essentially to the 0 \times p empty matrix.

Details

Suppose that the expectation of p-vector x is linear in the f-vector f, but the covariance of x is stationary and independent of f. The 'Markowitz Coefficient' is the p \times f matrix W such that, conditional on observing f, the portfolio Wf maximizes Sharpe. When f is the constant 1, the Markowitz Coefficient is the traditional Markowitz Portfolio.

Given n observations of the returns and features, given as matrices X, F, this code computes the Markowitz Coefficient along with the variance-covariance matrix of the Coefficient and the precision matrix. One may give optional weights, which are inverse conditional volatility. One may also give optional matrix J, G which define subspace and hedging constraints. Briefly, they constrain the portfolio optimization problem to portfolios in the row space of J and with zero covariance with the rows of G. It must be the case that the rows of J span the rows of G. J defaults to the p \times p identity matrix, and G defaults to a null matrix.

One may use the default method for computing covariance, via the vcov function, or via a 'fancy' estimator, like sandwich:vcovHAC, sandwich:vcovHC, etc.

Value

a list containing the following components:

mu

Letting r = f + p + fit.intercept, this is a q = (r)(r+1)/2 vector...

Ohat

The q \times q estimated variance covariance matrix of mu.

W

The estimated Markowitz coefficient, a p \times (fit.intercept + f) matrix. The first column corresponds to the intercept term if it is fit. Note that for convenience this function performs the sign flip, which is not performed on mu.

What

The estimated variance covariance matrix of vech(W). Letting s = p(fit.intercept + f), this is a s \times s matrix.

widxs

The indices into mu giving W, and into Ohat giving What.

n

The number of rows in X.

ff

The number of features plus as.numeric(fit.intercept).

p

The number of assets.

Note

Should also modify to include the theta estimates.

Author(s)

Steven E. Pav shabbychef@gmail.com

References

Pav, S. E. "Asymptotic Distribution of the Markowitz Portfolio." 2013 https://arxiv.org/abs/1312.0557

Pav, S. E. "Portfolio Inference with this One Weird Trick." R in Finance, 2014 http://past.rinfinance.com/agenda/2014/talk/StevenPav.pdf

See Also

theta_vcov, itheta_vcov

Examples

set.seed(1001)
X <- matrix(rnorm(1000*3),ncol=3)
ism <- mp_vcov(X,fit.intercept=TRUE)
walds <- ism$W / sqrt(diag(ism$What))
print(t(walds))
# subspace constraint
Jmat <- matrix(rnorm(6),ncol=3)
ism <- mp_vcov(X,fit.intercept=TRUE,Jmat=Jmat)
walds <- ism$W / sqrt(diag(ism$What))
print(t(walds))
# hedging constraint
Gmat <- matrix(1,nrow=1,ncol=3)
ism <- mp_vcov(X,fit.intercept=TRUE,Gmat=Gmat)
walds <- ism$W / sqrt(diag(ism$What))

# now conditional expectation:

# 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 <- 2
n.ret <- 8
n.obs <- 10000
set.seed(101)
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)
errs <- ism$W - Wcomp
dim(errs) <- c(length(errs),1)
Zerr <- solve(t(chol(ism$What)),errs)


[Package MarkowitzR version 1.0.3 Index]