Title: | Statistical Significance of the Markowitz Portfolio |
---|---|
Description: | A collection of tools for analyzing significance of Markowitz portfolios, using the delta method on the second moment matrix, <arxiv:1312.0557>. |
Authors: | Steven E. Pav [aut, cre] |
Maintainer: | Steven E. Pav <[email protected]> |
License: | LGPL-3 |
Version: | 1.0.2.0002 |
Built: | 2024-11-12 02:39:18 UTC |
Source: | https://github.com/shabbychef/MarkowitzR |
Computes the variance covariance matrix of the inverse unified second moment matrix.
itheta_vcov(X,vcov.func=vcov,fit.intercept=TRUE)
itheta_vcov(X,vcov.func=vcov,fit.intercept=TRUE)
X |
an |
vcov.func |
a function which takes an object of class |
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. |
Given -vector
with mean
and
covariance,
, let
be
with a one prepended. Then let
,
the uncentered second moment matrix. The inverse of
contains the (negative) Markowitz portfolio
and the precision matrix.
Given contemporaneous observations of
-vectors,
stacked as rows in the
matrix
,
this function estimates the mean and the asymptotic
variance-covariance matrix of
.
One may use the default method for computing covariance,
via the vcov
function, or via a 'fancy' estimator,
like sandwich:vcovHAC
, sandwich:vcovHC
, etc.
a list containing the following components:
mu |
a |
Ohat |
the |
n |
the number of rows in |
pp |
the number of assets plus |
By flipping the sign of , the inverse of
contains the positive Markowitz
portfolio and the precision matrix on
. Performing
this transform before passing the data to this function
should be considered idiomatic.
A more general form of this function exists as mp_vcov
.
Replaces similar functionality from SharpeR package, but with modified API.
Steven E. Pav [email protected]
Pav, S. E. "Asymptotic Distribution of the Markowitz Portfolio." 2013 http://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
X <- matrix(rnorm(1000*3),ncol=3) # putting in -X is idiomatic: ism <- itheta_vcov(-X) iSigmas.n <- itheta_vcov(-X,vcov.func="normal") iSigmas.n <- itheta_vcov(-X,fit.intercept=FALSE) # compute the marginal Wald test statistics: qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) # make it fat tailed: X <- matrix(rt(1000*3,df=5),ncol=3) ism <- itheta_vcov(X) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) if (require(sandwich)) { ism <- itheta_vcov(X,vcov.func=vcovHC) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) } # add some autocorrelation to X Xf <- filter(X,c(0.2),"recursive") colnames(Xf) <- colnames(X) ism <- itheta_vcov(Xf) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) if (require(sandwich)) { ism <- itheta_vcov(Xf,vcov.func=vcovHAC) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) }
X <- matrix(rnorm(1000*3),ncol=3) # putting in -X is idiomatic: ism <- itheta_vcov(-X) iSigmas.n <- itheta_vcov(-X,vcov.func="normal") iSigmas.n <- itheta_vcov(-X,fit.intercept=FALSE) # compute the marginal Wald test statistics: qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) # make it fat tailed: X <- matrix(rt(1000*3,df=5),ncol=3) ism <- itheta_vcov(X) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) if (require(sandwich)) { ism <- itheta_vcov(X,vcov.func=vcovHC) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) } # add some autocorrelation to X Xf <- filter(X,c(0.2),"recursive") colnames(Xf) <- colnames(X) ism <- itheta_vcov(Xf) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) if (require(sandwich)) { ism <- itheta_vcov(Xf,vcov.func=vcovHAC) qidx <- 2:ism$pp wald.stats <- ism$mu[qidx] / sqrt(diag(ism$Ohat[qidx,qidx])) }
Inference on the Markowitz portfolio.
Suppose is a
-vector of returns of some assets with expected
value
and covariance
. The
Markowitz Portfolio is the portfolio
. Scale multiples of this portfolio
solve various portfolio optimization problems, among them
This packages supports various statistical tests around the elements of the Markowitz Portfolio, and its Sharpe ratio, including the possibility of hedging, and scalar conditional heteroskedasticity and conditional expectation.
MarkowitzR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
This package is maintained as a hobby.
Steven E. Pav [email protected]
Pav, S. E. "Asymptotic Distribution of the Markowitz Portfolio." 2013 http://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
Britten-Jones, Mark. "The Sampling Error in Estimates of Mean-Variance Efficient Portfolio Weights." The Journal of Finance 54, no. 2 (1999): 655–671. https://www.jstor.org/stable/2697722
Bodnar, Taras and Okhrin, Yarema. "On the Product of Inverse Wishart and Normal Distributions with Applications to Discriminant Analysis and Portfolio Theory." Scandinavian Journal of Statistics 38, no. 2 (2011): 311–331. http://dx.doi.org/10.1111/j.1467-9469.2011.00729.x
Markowitz, Harry. "Portfolio Selection." The Journal of Finance 7, no. 1 (1952): 77–91. https://www.jstor.org/stable/2975974
Brandt, Michael W. "Portfolio Choice Problems." Handbook of Financial Econometrics 1 (2009): 269–336. https://faculty.fuqua.duke.edu/~mbrandt/papers/published/portreview.pdf
News for package ‘MarkowitzR’
emergency fix for broken tests under atlas on CRAN.
move figures around for README on CRAN.
yet again, conform to CRAN rules.
conform to CRAN rules.
fix bug preventing multi-row hedging or constraint matrices.
first CRAN release.
Estimates the Markowitz Portfolio or Markowitz Coefficient subject to subspace and hedging constraints, and heteroskedasticity.
mp_vcov(X,feat=NULL,vcov.func=vcov,fit.intercept=TRUE,weights=NULL,Jmat=NULL,Gmat=NULL)
mp_vcov(X,feat=NULL,vcov.func=vcov,fit.intercept=TRUE,weights=NULL,Jmat=NULL,Gmat=NULL)
X |
an |
feat |
an |
vcov.func |
a function which takes an object of class |
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 |
Jmat |
an optional |
Gmat |
an optional |
Suppose that the expectation of -vector
is linear
in the
-vector
, but the covariance of
is
stationary and independent of
. The 'Markowitz Coefficient'
is the
matrix
such that,
conditional on observing
, the portfolio
maximizes
Sharpe. When
is the constant 1, the Markowitz Coefficient
is the traditional Markowitz Portfolio.
Given observations of the returns and features, given
as matrices
, 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
which define subspace and hedging constraints. Briefly, they constrain
the portfolio optimization problem to portfolios in the row space of
and with zero covariance with the rows of
. It must
be the case that the rows of
span the rows of
.
defaults to the
identity matrix,
and
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.
a list containing the following components:
mu |
Letting |
Ohat |
The |
W |
The estimated Markowitz coefficient, a
|
What |
The estimated variance covariance matrix of |
widxs |
The indices into |
n |
The number of rows in |
ff |
The number of features plus |
p |
The number of assets. |
Should also modify to include the theta estimates.
Steven E. Pav [email protected]
Pav, S. E. "Asymptotic Distribution of the Markowitz Portfolio." 2013 http://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
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)
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)
Computes the variance covariance matrix of sample mean and second moment.
theta_vcov(X,vcov.func=vcov,fit.intercept=TRUE)
theta_vcov(X,vcov.func=vcov,fit.intercept=TRUE)
X |
an |
vcov.func |
a function which takes an object of class |
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. |
Given -vector
, the 'unified' sample is the
vector of 1,
, and
stacked on top
of each other.
Given
contemporaneous observations of
-vectors,
stacked as rows in the
matrix
,
this function computes the mean and the variance-covariance
matrix of the 'unified' sample.
One may use the default method for computing covariance,
via the vcov
function, or via a 'fancy' estimator,
like sandwich:vcovHAC
, sandwich:vcovHC
, etc.
a list containing the following components:
mu |
a |
Ohat |
the |
n |
the number of rows in |
pp |
the number of assets plus |
Replaces similar functionality from SharpeR package, but with modified API.
Steven E. Pav [email protected]
Pav, S. E. "Asymptotic Distribution of the Markowitz Portfolio." 2013 http://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
X <- matrix(rnorm(1000*3),ncol=3) Sigmas <- theta_vcov(X) Sigmas.n <- theta_vcov(X,vcov.func="normal") Sigmas.n <- theta_vcov(X,fit.intercept=FALSE) # make it fat tailed: X <- matrix(rt(1000*3,df=5),ncol=3) Sigmas <- theta_vcov(X) if (require(sandwich)) { Sigmas <- theta_vcov(X,vcov.func=vcovHC) } # add some autocorrelation to X Xf <- filter(X,c(0.2),"recursive") colnames(Xf) <- colnames(X) Sigmas <- theta_vcov(Xf) if (require(sandwich)) { Sigmas <- theta_vcov(Xf,vcov.func=vcovHAC) }
X <- matrix(rnorm(1000*3),ncol=3) Sigmas <- theta_vcov(X) Sigmas.n <- theta_vcov(X,vcov.func="normal") Sigmas.n <- theta_vcov(X,fit.intercept=FALSE) # make it fat tailed: X <- matrix(rt(1000*3,df=5),ncol=3) Sigmas <- theta_vcov(X) if (require(sandwich)) { Sigmas <- theta_vcov(X,vcov.func=vcovHC) } # add some autocorrelation to X Xf <- filter(X,c(0.2),"recursive") colnames(Xf) <- colnames(X) Sigmas <- theta_vcov(Xf) if (require(sandwich)) { Sigmas <- theta_vcov(Xf,vcov.func=vcovHAC) }