Maintainer: | Steven E. Pav <shabbychef@gmail.com> |
Version: | 1.0.3 |
Date: | 2023-08-20 |
License: | LGPL-3 |
Title: | Statistical Significance of the Markowitz Portfolio |
BugReports: | https://github.com/shabbychef/MarkowitzR/issues |
Description: | A collection of tools for analyzing significance of Markowitz portfolios, using the delta method on the second moment matrix, <doi:10.48550/arXiv.1312.0557>. |
Depends: | R (≥ 3.0.2) |
Imports: | matrixcalc, gtools |
Suggests: | sandwich, SharpeR, testthat, formatR, knitr |
URL: | https://github.com/shabbychef/MarkowitzR |
VignetteBuilder: | knitr |
Collate: | 'MarkowitzR.r' 'portinf.r' 'utils.r' 'vcov.r' |
RoxygenNote: | 7.1.1 |
NeedsCompilation: | no |
Packaged: | 2023-08-21 15:57:27 UTC; spav |
Author: | Steven E. Pav |
Repository: | CRAN |
Date/Publication: | 2023-08-21 18:30:09 UTC |
statistics concerning the Markowitz portfolio
Description
Inference on the Markowitz portfolio.
Markowitz Portfolio
Suppose x
is a p
-vector of returns of some assets with expected
value \mu
and covariance \Sigma
. The
Markowitz Portfolio is the portfolio
w = \Sigma^{-1}\mu
. Scale multiples of this portfolio
solve various portfolio optimization problems, among them
\mathrm{argmax}_{w: w^{\top}\Sigma w \le R^2} \frac{\mu^{\top} w -
r_0}{\sqrt{w^{\top}\Sigma w}}
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.
Legal Mumbo Jumbo
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.
Note
This package is maintained as a hobby.
Author(s)
Steven E. Pav shabbychef@gmail.com
Maintainer: Steven E. Pav shabbychef@gmail.com (ORCID)
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
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. doi: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://scholars.duke.edu/publication/964964
See Also
Useful links:
Report bugs at https://github.com/shabbychef/MarkowitzR/issues
News for package 'MarkowitzR':
Description
News for package ‘MarkowitzR’
Changes in MarkowitzR Version 1.0.3 (2023-08-20)
fix package documentation.
Changes in MarkowitzR Version 1.0.2 (2020-01-07)
emergency fix for broken tests under atlas on CRAN.
Changes in MarkowitzR Version 1.0.1 (2018-05-25)
move figures around for README on CRAN.
Changes in MarkowitzR Version 0.9900 (2016-09-15)
yet again, conform to CRAN rules.
Changes in MarkowitzR Version 0.1502 (2015-01-26)
conform to CRAN rules.
Changes in MarkowitzR Version 0.1403 (2014-06-01)
fix bug preventing multi-row hedging or constraint matrices.
MarkowitzR Initial Version 0.1402 (2014-02-14)
first CRAN release.
Compute variance covariance of Inverse 'Unified' Second Moment
Description
Computes the variance covariance matrix of the inverse unified second moment matrix.
Usage
itheta_vcov(X,vcov.func=vcov,fit.intercept=TRUE)
Arguments
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. |
Details
Given p
-vector x
with mean \mu
and
covariance, \Sigma
, let y
be x
with a one prepended. Then let
\Theta = E\left(y y^{\top}\right)
,
the uncentered second moment matrix. The inverse of
\Theta
contains the (negative) Markowitz portfolio
and the precision matrix.
Given n
contemporaneous observations of p
-vectors,
stacked as rows in the n \times p
matrix X
,
this function estimates the mean and the asymptotic
variance-covariance matrix of \Theta^{-1}
.
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 |
a |
Ohat |
the |
n |
the number of rows in |
pp |
the number of assets plus |
Note
By flipping the sign of X
, the inverse of
\Theta
contains the positive Markowitz
portfolio and the precision matrix on X
. 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.
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
Examples
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]))
}
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 |
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 |
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 |
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. |
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
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)
Compute variance covariance of 'Unified' Second Moment
Description
Computes the variance covariance matrix of sample mean and second moment.
Usage
theta_vcov(X,vcov.func=vcov,fit.intercept=TRUE)
Arguments
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. |
Details
Given p
-vector x
, the 'unified' sample is the
(p+1)(p+2)/2
vector of 1, x
, and
\mbox{vech}(x x^{\top})
stacked on top
of each other.
Given n
contemporaneous observations of p
-vectors,
stacked as rows in the n \times p
matrix X
,
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.
Value
a list containing the following components:
mu |
a |
Ohat |
the |
n |
the number of rows in |
pp |
the number of assets plus |
Note
Replaces similar functionality from SharpeR package, but with modified API.
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
Examples
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)
}