[Returnanalytics-commits] r2351 - in pkg/FactorAnalytics: R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Jun 18 11:52:28 CEST 2013
Author: braverock
Date: 2013-06-18 11:52:27 +0200 (Tue, 18 Jun 2013)
New Revision: 2351
Modified:
pkg/FactorAnalytics/R/chart.Style.R
pkg/FactorAnalytics/R/covEWMA.R
pkg/FactorAnalytics/R/factorModelCovariance.r
pkg/FactorAnalytics/R/factorModelEsDecomposition.R
pkg/FactorAnalytics/R/factorModelMonteCarlo.R
pkg/FactorAnalytics/R/factorModelPerformanceAttribution.r
pkg/FactorAnalytics/R/factorModelSdDecomposition.R
pkg/FactorAnalytics/R/factorModelVaRDecomposition.R
pkg/FactorAnalytics/R/fitFundamentalFactorModel.R
pkg/FactorAnalytics/R/fitMacroeconomicFactorModel.R
pkg/FactorAnalytics/R/fitStatisticalFactorModel.R
pkg/FactorAnalytics/R/impliedFactorReturns.R
pkg/FactorAnalytics/R/modifiedEsReport.R
pkg/FactorAnalytics/R/modifiedIncrementalES.R
pkg/FactorAnalytics/R/modifiedIncrementalVaR.R
pkg/FactorAnalytics/R/modifiedPortfolioEsDecomposition.R
pkg/FactorAnalytics/R/modifiedPortfolioVaRDecomposition.R
pkg/FactorAnalytics/R/modifiedVaRReport.R
pkg/FactorAnalytics/R/nonparametricEsReport.R
pkg/FactorAnalytics/R/nonparametricIncrementalES.R
pkg/FactorAnalytics/R/nonparametricIncrementalVaR.R
pkg/FactorAnalytics/R/nonparametricPortfolioEsDecomposition.R
pkg/FactorAnalytics/R/nonparametricPortfolioVaRDecomposition.R
pkg/FactorAnalytics/R/nonparametricVaRReport.R
pkg/FactorAnalytics/R/normalEsReport.R
pkg/FactorAnalytics/R/normalIncrementalES.R
pkg/FactorAnalytics/R/normalIncrementalVaR.R
pkg/FactorAnalytics/R/normalPortfolioEsDecomposition.R
pkg/FactorAnalytics/R/normalPortfolioVaRDecomposition.R
pkg/FactorAnalytics/R/normalVaRReport.R
pkg/FactorAnalytics/R/plot.FM.attribution.r
pkg/FactorAnalytics/R/plot.FundamentalFactorModel.r
pkg/FactorAnalytics/R/plot.MacroFactorModel.r
pkg/FactorAnalytics/R/plot.StatFactorModel.r
pkg/FactorAnalytics/R/portfolioSdDecomposition.R
pkg/FactorAnalytics/R/print.MacroFactorModel.r
pkg/FactorAnalytics/R/print.StatFactorModel.r
pkg/FactorAnalytics/R/scenarioPredictions.r
pkg/FactorAnalytics/R/scenarioPredictionsPortfolio.r
pkg/FactorAnalytics/R/summary.FM.attribution.r
pkg/FactorAnalytics/R/summary.MacroFactorModel.r
pkg/FactorAnalytics/man/CornishFisher.Rd
pkg/FactorAnalytics/man/covEWMA.Rd
pkg/FactorAnalytics/man/factorModelCovariance.Rd
pkg/FactorAnalytics/man/factorModelEsDecomposition.Rd
pkg/FactorAnalytics/man/factorModelMonteCarlo.Rd
pkg/FactorAnalytics/man/factorModelPerformanceAttribution.Rd
pkg/FactorAnalytics/man/factorModelSdDecomposition.Rd
pkg/FactorAnalytics/man/factorModelVaRDecomposition.Rd
pkg/FactorAnalytics/man/fitFundamentalFactorModel.Rd
pkg/FactorAnalytics/man/fitMacroeconomicFactorModel.Rd
pkg/FactorAnalytics/man/fitStatisticalFactorModel.Rd
pkg/FactorAnalytics/man/impliedFactorReturns.Rd
pkg/FactorAnalytics/man/managers.df.Rd
pkg/FactorAnalytics/man/modifiedEsReport.Rd
pkg/FactorAnalytics/man/modifiedIncrementalES.Rd
pkg/FactorAnalytics/man/modifiedIncrementalVaR.Rd
pkg/FactorAnalytics/man/modifiedPortfolioEsDecomposition.Rd
pkg/FactorAnalytics/man/modifiedPortfolioVaRDecomposition.Rd
pkg/FactorAnalytics/man/modifiedVaRReport.Rd
pkg/FactorAnalytics/man/nonparametricEsReport.Rd
pkg/FactorAnalytics/man/nonparametricIncrementalES.Rd
pkg/FactorAnalytics/man/nonparametricIncrementalVaR.Rd
pkg/FactorAnalytics/man/nonparametricPortfolioEsDecomposition.Rd
pkg/FactorAnalytics/man/nonparametricPortfolioVaRDecomposition.Rd
pkg/FactorAnalytics/man/nonparametricVaRReport.Rd
pkg/FactorAnalytics/man/normalEsReport.Rd
pkg/FactorAnalytics/man/normalIncrementalES.Rd
pkg/FactorAnalytics/man/normalIncrementalVaR.Rd
pkg/FactorAnalytics/man/normalPortfolioEsDecomposition.Rd
pkg/FactorAnalytics/man/normalPortfolioVaRDecomposition.Rd
pkg/FactorAnalytics/man/normalVaRReport.Rd
pkg/FactorAnalytics/man/plot.FM.attribution.Rd
pkg/FactorAnalytics/man/plot.FundamentalFactorModel.Rd
pkg/FactorAnalytics/man/plot.MacroFactorModel.Rd
pkg/FactorAnalytics/man/plot.StatFactorModel.Rd
pkg/FactorAnalytics/man/portfolioSdDecomposition.Rd
pkg/FactorAnalytics/man/print.MacroFactorModel.Rd
pkg/FactorAnalytics/man/print.StatFactorModel.Rd
pkg/FactorAnalytics/man/scenarioPredictions.Rd
pkg/FactorAnalytics/man/scenarioPredictionsPortfolio.Rd
pkg/FactorAnalytics/man/stat.fm.data.Rd
pkg/FactorAnalytics/man/stock.Rd
pkg/FactorAnalytics/man/summary.FM.attribution.Rd
pkg/FactorAnalytics/man/summary.MacroFactorModel.Rd
Log:
- roxygenize all existing package documentation
- regenerate all Rd files using roxygen2
Modified: pkg/FactorAnalytics/R/chart.Style.R
===================================================================
--- pkg/FactorAnalytics/R/chart.Style.R 2013-06-18 00:56:27 UTC (rev 2350)
+++ pkg/FactorAnalytics/R/chart.Style.R 2013-06-18 09:52:27 UTC (rev 2351)
@@ -1,3 +1,128 @@
+#' calculate and display effective style weights
+#'
+#' Functions that calculate effective style weights and display the results in
+#' a bar chart. \code{chart.Style} calculates and displays style weights
+#' calculated over a single period. \code{chart.RollingStyle} calculates and
+#' displays those weights in rolling windows through time. \code{style.fit}
+#' manages the calculation of the weights by method. \code{style.QPfit}
+#' calculates the specific constraint case that requires quadratic programming.
+#'
+#' These functions calculate style weights using an asset class style model as
+#' described in detail in Sharpe (1992). The use of quadratic programming to
+#' determine a fund's exposures to the changes in returns of major asset
+#' classes is usually refered to as "style analysis".
+#'
+#' The "unconstrained" method implements a simple factor model for style
+#' analysis, as in: \deqn{Ri = bi1*F1+bi2*F2+...+bin*Fn+ei}{R_i =
+#' b_{i1}F_1+b_{i2}F_2+\dots+b_{in}F_n +e_i} where \eqn{Ri}{R_i} represents the
+#' return on asset i, \eqn{Fj}{F_j} represents each factor, and \eqn{ei}{e_i}
+#' represents the "non-factor" component of the return on i. This is simply a
+#' multiple regression analysis with fund returns as the dependent variable and
+#' asset class returns as the independent variables. The resulting slope
+#' coefficients are then interpreted as the fund's historic exposures to asset
+#' class returns. In this case, coefficients do not sum to 1.
+#'
+#' The "normalized" method reports the results of a multiple regression
+#' analysis similar to the first, but with one constraint: the coefficients are
+#' required to add to 1. Coefficients may be negative, indicating short
+#' exposures. To enforce the constraint, coefficients are normalized.
+#'
+#' The "constrained" method includes the constraint that the coefficients sum
+#' to 1, but adds that the coefficients must lie between 0 and 1. These
+#' inequality constraints require a quadratic programming algorithm using
+#' \code{\link[quadprog]{solve.QP}} from the 'quadprog' package, and the
+#' implementation is discussed under \code{\link{style.QPfit}}. If set to
+#' TRUE, "leverage" allows the sum of the coefficients to exceed 1.
+#'
+#' According to Sharpe (1992), the calculation for the constrained case is
+#' represented as: \deqn{min var(Rf - sum[wi * R.si]) = min var(F - w*S)}{min
+#' \sigma(R_f - \sum{w_i * R_s_i}) = min \sigma(F - w*S)} \deqn{s.t. sum[wi] =
+#' 1; wi > 0}{ s.t. \sum{w_i} = 1; w_i > 0}
+#'
+#' Remembering that:
+#'
+#' \deqn{\sigma(aX + bY) = a^2 \sigma(X) + b^2 \sigma(Y) + 2ab cov(X,Y) =
+#' \sigma(R.f) + w'*V*w - 2*w'*cov(R.f,R.s)}
+#'
+#' we can drop \eqn{var(Rf)}{\sigma(R_f)} as it isn't a function of weights,
+#' multiply both sides by 1/2:
+#'
+#' \deqn{= min (1/2) w'*V*w - C'w}{= min (1/2) w'*V*w - C'w} \deqn{ s.t. w'*e =
+#' 1, w_i > 0}{ s.t. w'*e = 1, w_i > 0}
+#'
+#' Which allows us to use \code{\link[quadprog]{solve.QP}}, which is specified
+#' as: \deqn{min(-d' b + 1/2 b' D b)}{min(-d' b + 1/2 b' D b)} and the
+#' constraints \deqn{ A' b >= b.0 }{ A' b >= b_0 }
+#'
+#' so: b is the weight vector, D is the variance-covariance matrix of the
+#' styles d is the covariance vector between the fund and the styles
+#'
+#' The chart functions then provide a graphical summary of the results. The
+#' underlying function, \code{\link{style.fit}}, provides the outputs of the
+#' analysis and more information about fit, including an R-squared value.
+#'
+#' Styles identified in this analysis may be interpreted as an average of
+#' potentially changing exposures over the period covered. The function
+#' \code{\link{chart.RollingStyle}} may be useful for examining the behavior of
+#' a manager's average exposures to asset classes over time, using a
+#' rolling-window analysis.
+#'
+#' The chart functions plot a column chart or stacked column chart of the
+#' resulting style weights to the current device. Both \code{style.fit} and
+#' \code{style.QPfit} produce a list of data frames containing 'weights' and
+#' 'R.squared' results. If 'model' = TRUE in \code{style.QPfit}, the full
+#' result set is shown from the output of \code{solve.QP}.
+#'
+#' @aliases chart.Style chart.RollingStyle table.RollingStyle style.fit
+#' style.QPfit
+#' @param R.fund matrix, data frame, or zoo object with fund returns to be
+#' analyzed
+#' @param R.style matrix, data frame, or zoo object with style index returns.
+#' Data object must be of the same length and time-aligned with R.fund
+#' @param method specify the method of calculation of style weights as
+#' "constrained", "unconstrained", or "normalized". For more information, see
+#' \code{\link{style.fit}}
+#' @param leverage logical, defaults to 'FALSE'. If 'TRUE', the calculation of
+#' weights assumes that leverage may be used. For more information, see
+#' \code{\link{style.fit}}
+#' @param model logical. If 'model' = TRUE in \code{\link{style.QPfit}}, the
+#' full result set is shown from the output of \code{solve.QP}.
+#' @param selection either "none" (default) or "AIC". If "AIC", then the
+#' function uses a stepwise regression to identify find the model with minimum
+#' AIC value. See \code{\link{step}} for more detail.
+#' @param unstacked logical. If set to 'TRUE' \emph{and} only one row of data
+#' is submitted in 'w', then the chart creates a normal column chart. If more
+#' than one row is submitted, then this is ignored. See examples below.
+#' @param space the amount of space (as a fraction of the average bar width)
+#' left before each bar, as in \code{\link{barplot}}. Default for
+#' \code{chart.RollingStyle} is 0; for \code{chart.Style} the default is 0.2.
+#' @param main set the chart title, same as in \code{\link{plot}}
+#' @param width number of periods or window to apply rolling style analysis
+#' over
+#' @param ylim set the y-axis limit, same as in \code{\link{plot}}
+#' @param \dots for the charting functions, these are arguments to be passed to
+#' \code{\link{barplot}}. These can include further arguments (such as 'axes',
+#' 'asp' and 'main') and graphical parameters (see 'par') which are passed to
+#' 'plot.window()', 'title()' and 'axis'. For the calculation functions, these
+#' are ignored.
+#' @note None of the functions \code{chart.Style}, \code{style.fit}, and
+#' \code{style.QPfit} make any attempt to align the two input data series. The
+#' \code{chart.RollingStyle}, on the other hand, does merge the two series and
+#' manages the calculation over common periods.
+#' @author Peter Carl
+#' @seealso \code{\link{barplot}}, \code{\link{par}}
+#' @references Sharpe, W. Asset Allocation: Management Style and Performance
+#' Measurement Journal of Portfolio Management, 1992, 7-19. See \url{
+#' http://www.stanford.edu/~wfsharpe/art/sa/sa.htm}
+#' @keywords ts multivariate hplot
+#' @examples
+#'
+#' data(edhec)
+#' data(managers)
+#' style.fit(managers[97:132,2,drop=FALSE],edhec[85:120,], method="constrained", leverage=FALSE)
+#' chart.Style(managers[97:132,2,drop=FALSE],edhec[85:120,], method="constrained", leverage=FALSE, unstack=TRUE, las=3)
+#' chart.RollingStyle(managers[,2,drop=FALSE],edhec[,1:11], method="constrained", leverage=FALSE, width=36, cex.legend = .7, colorset=rainbow12equal, las=1)
+#'
`chart.Style` <-
function (R.fund, R.style, method = c("constrained", "unconstrained", "normalized"), leverage = FALSE, main = NULL, ylim = NULL, unstacked=TRUE, ...)
{ # @author Peter Carl
Modified: pkg/FactorAnalytics/R/covEWMA.R
===================================================================
--- pkg/FactorAnalytics/R/covEWMA.R 2013-06-18 00:56:27 UTC (rev 2350)
+++ pkg/FactorAnalytics/R/covEWMA.R 2013-06-18 09:52:27 UTC (rev 2351)
@@ -1,50 +1,79 @@
-covEWMA <-
-function(factors, lambda=0.96, return.cor=FALSE) {
-## Inputs:
-## factors N x K numerical factors data. data is class data.frame
-## N is the time length and K is the number of the factors.
-## lambda scalar. exponetial decay factor between 0 and 1.
-## return.cor Logical, if TRUE then return EWMA correlation matrices
-## Output:
-## cov.f.ewma array. dimension is N x K x K.
-## comments:
-## 1. add optional argument cov.start to specify initial covariance matrix
-## 2. allow data input to be data class to be any rectangular data object
-
-
-if (is.data.frame(factors)){
- factor.names = colnames(factors)
- t.factor = nrow(factors)
- k.factor = ncol(factors)
- factors = as.matrix(factors)
- t.names = rownames(factors)
-} else {
- stop("factor data should be saved in data.frame class.")
-}
-if (lambda>=1 || lambda <= 0){
- stop("exponential decay value lambda should be between 0 and 1.")
-} else {
- cov.f.ewma = array(,c(t.factor,k.factor,k.factor))
- cov.f = var(factors) # unconditional variance as EWMA at time = 0
- FF = (factors[1,]- mean(factors)) %*% t(factors[1,]- mean(factors))
- cov.f.ewma[1,,] = (1-lambda)*FF + lambda*cov.f
- for (i in 2:t.factor) {
- FF = (factors[i,]- mean(factors)) %*% t(factors[i,]- mean(factors))
- cov.f.ewma[i,,] = (1-lambda)*FF + lambda*cov.f.ewma[(i-1),,]
- }
-
-}
- # 9/15/11: add dimnames to array
- dimnames(cov.f.ewma) = list(t.names, factor.names, factor.names)
-
- if(return.cor) {
- cor.f.ewma = cov.f.ewma
- for (i in 1:dim(cor.f.ewma)[1]) {
- cor.f.ewma[i, , ] = cov2cor(cov.f.ewma[i, ,])
- }
- return(cor.f.ewma)
- } else{
- return(cov.f.ewma)
- }
-}
-
+#' Compute RiskMetrics-type EWMA Covariance Matrix
+#'
+#' Compute time series of RiskMetrics-type EWMA covariance matrices of returns.
+#' Initial covariance matrix is assumed to be the unconditional covariance
+#' matrix.
+#'
+#' The EWMA covariance matrix at time \code{t} is compute as \cr \code{Sigma(t)
+#' = lambda*Sigma(t-1) + (1-lambda)*R(t)t(R(t))} \cr where \code{R(t)} is the
+#' \code{K x 1} vector of returns at time \code{t}.
+#'
+#' @param factors \code{T x K} data.frame containing asset returns, where
+#' \code{T} is the number of time periods and \code{K} is the number of assets.
+#' @param lambda Scalar exponential decay factor. Must lie between between 0
+#' and 1.
+#' @param return.cor Logical, if TRUE then return EWMA correlation matrices.
+#' @return \code{T x K x K} array giving the time series of EWMA covariance
+#' matrices if \code{return.cor=FALSE} and EWMA correlation matrices if
+#' \code{return.cor=TRUE}.
+#' @author Eric Zivot and Yi-An Chen.
+#' @references Zivot, E. and J. Wang (2006), \emph{Modeling Financial Time
+#' Series with S-PLUS, Second Edition}, Springer-Verlag.
+#' @examples
+#'
+#' # compute time vaying covariance of factors.
+#' data(managers.df)
+#' factors = managers.df[,(7:9)]
+#' cov.f.ewma <- covEWMA(factors)
+#' cov.f.ewma[120,,]
+#'
+covEWMA <-
+function(factors, lambda=0.96, return.cor=FALSE) {
+## Inputs:
+## factors N x K numerical factors data. data is class data.frame
+## N is the time length and K is the number of the factors.
+## lambda scalar. exponetial decay factor between 0 and 1.
+## return.cor Logical, if TRUE then return EWMA correlation matrices
+## Output:
+## cov.f.ewma array. dimension is N x K x K.
+## comments:
+## 1. add optional argument cov.start to specify initial covariance matrix
+## 2. allow data input to be data class to be any rectangular data object
+
+
+if (is.data.frame(factors)){
+ factor.names = colnames(factors)
+ t.factor = nrow(factors)
+ k.factor = ncol(factors)
+ factors = as.matrix(factors)
+ t.names = rownames(factors)
+} else {
+ stop("factor data should be saved in data.frame class.")
+}
+if (lambda>=1 || lambda <= 0){
+ stop("exponential decay value lambda should be between 0 and 1.")
+} else {
+ cov.f.ewma = array(,c(t.factor,k.factor,k.factor))
+ cov.f = var(factors) # unconditional variance as EWMA at time = 0
+ FF = (factors[1,]- mean(factors)) %*% t(factors[1,]- mean(factors))
+ cov.f.ewma[1,,] = (1-lambda)*FF + lambda*cov.f
+ for (i in 2:t.factor) {
+ FF = (factors[i,]- mean(factors)) %*% t(factors[i,]- mean(factors))
+ cov.f.ewma[i,,] = (1-lambda)*FF + lambda*cov.f.ewma[(i-1),,]
+ }
+
+}
+ # 9/15/11: add dimnames to array
+ dimnames(cov.f.ewma) = list(t.names, factor.names, factor.names)
+
+ if(return.cor) {
+ cor.f.ewma = cov.f.ewma
+ for (i in 1:dim(cor.f.ewma)[1]) {
+ cor.f.ewma[i, , ] = cov2cor(cov.f.ewma[i, ,])
+ }
+ return(cor.f.ewma)
+ } else{
+ return(cov.f.ewma)
+ }
+}
+
Modified: pkg/FactorAnalytics/R/factorModelCovariance.r
===================================================================
--- pkg/FactorAnalytics/R/factorModelCovariance.r 2013-06-18 00:56:27 UTC (rev 2350)
+++ pkg/FactorAnalytics/R/factorModelCovariance.r 2013-06-18 09:52:27 UTC (rev 2351)
@@ -1,28 +1,61 @@
-factorModelCovariance <-
-function(beta.mat, factor.cov, residVars.vec) {
-## Inputs:
-## beta.mat n x k matrix of factor betas
-## factor.cov k x k factor return covariance matrix
-## residVars.vec n x 1 vector of residual variances from factor model
-## Output:
-## cov.fm n x n return covariance matrix based on
-## estimated factor model.
- beta.mat = as.matrix(beta.mat)
- factor.cov = as.matrix(factor.cov)
- sig.e = as.vector(residVars.vec)
- if (length(sig.e) > 1) {
- D.e = diag(as.vector(sig.e))
- } else {
- D.e = as.matrix(sig.e)
- }
- if (ncol(beta.mat) != ncol(factor.cov))
- stop("beta.mat and factor.cov must have same number of columns")
-
- if (nrow(D.e) != nrow(beta.mat))
- stop("beta.mat and D.e must have same number of rows")
- cov.fm = beta.mat %*% factor.cov %*% t(beta.mat) + D.e
- if (any(diag(chol(cov.fm)) == 0))
- warning("Covariance matrix is not positive definite")
- return(cov.fm)
-}
-
+#' Compute Factor Model Covariance Matrix.
+#'
+#' Compute asset return covariance matrix from factor model parameters.
+#'
+#' The return on asset \code{i} (\code{i = 1,...,N}) is assumed to follow the
+#' factor model \cr \code{R(i,t) = alpha + t(beta)*F(t) + e(i,t), e(i,t) ~ iid
+#' (0, sig(i)^2)} \cr where \code{beta} is a \code{K x 1} vector of factor
+#' exposures. The return variance is then \cr \code{var(R(i,t) =
+#' t(beta)*var(F(t))*beta + sig(i)^2}, \cr and the \code{N x N} covariance
+#' matrix of the return vector \code{R} is \cr \code{var(R) = B*var(F(t))*t(B)
+#' + D} \cr where B is the \code{N x K} matrix of asset betas and \code{D} is a
+#' diagonal matrix with \code{sig(i)^2} values along the diagonal.
+#'
+#' @param beta.mat \code{N x K} matrix of factor betas, where \code{N} is the
+#' number of assets and \code{K} is the number of factors.
+#' @param factor.cov \code{K x K} factor return covariance matrix.
+#' @param residVars.vec \code{N x 1} vector of asset specific residual
+#' variances from the factor model.
+#' @return \code{N x N} return covariance matrix based on factor model
+#' parameters.
+#' @author Eric Zivot and Yi-An Chen.
+#' @references Zivot, E. and J. Wang (2006), \emph{Modeling Financial Time
+#' Series with S-PLUS, Second Edition}, Springer-Verlag.
+#' @examples
+#'
+#' # factorModelCovariance
+#' data(managers.df)
+#' factors = managers.df[,(7:9)]
+#' ret.assets = managers.df[,(1:6)]
+#' fit <-fitMacroeconomicFactorModel(ret.assets,factors,fit.method="OLS",
+#' variable.selection="all subsets", factor.set = 3)
+#' factorModelCovariance(fit$beta.mat,var(factors),fit$residVars.vec)
+#'
+factorModelCovariance <-
+function(beta.mat, factor.cov, residVars.vec) {
+## Inputs:
+## beta.mat n x k matrix of factor betas
+## factor.cov k x k factor return covariance matrix
+## residVars.vec n x 1 vector of residual variances from factor model
+## Output:
+## cov.fm n x n return covariance matrix based on
+## estimated factor model.
+ beta.mat = as.matrix(beta.mat)
+ factor.cov = as.matrix(factor.cov)
+ sig.e = as.vector(residVars.vec)
+ if (length(sig.e) > 1) {
+ D.e = diag(as.vector(sig.e))
+ } else {
+ D.e = as.matrix(sig.e)
+ }
+ if (ncol(beta.mat) != ncol(factor.cov))
+ stop("beta.mat and factor.cov must have same number of columns")
+
+ if (nrow(D.e) != nrow(beta.mat))
+ stop("beta.mat and D.e must have same number of rows")
+ cov.fm = beta.mat %*% factor.cov %*% t(beta.mat) + D.e
+ if (any(diag(chol(cov.fm)) == 0))
+ warning("Covariance matrix is not positive definite")
+ return(cov.fm)
+}
+
Modified: pkg/FactorAnalytics/R/factorModelEsDecomposition.R
===================================================================
--- pkg/FactorAnalytics/R/factorModelEsDecomposition.R 2013-06-18 00:56:27 UTC (rev 2350)
+++ pkg/FactorAnalytics/R/factorModelEsDecomposition.R 2013-06-18 09:52:27 UTC (rev 2351)
@@ -1,79 +1,140 @@
-factorModelEsDecomposition <-
-function(Data, beta.vec, sig2.e, tail.prob = 0.05) {
-## Compute factor model factor ES decomposition based on Euler's theorem given historic
-## or simulated data and factor model parameters.
-## The partial derivative of ES wrt factor beta is computed
-## as the expected factor return given fund return is less than or equal to its VaR
-## VaR is compute either as the sample quantile or as an estimated quantile
-## using the Cornish-Fisher expansion
-## inputs:
-## Data B x (k+2) matrix of data. First column contains the fund returns,
-## second through k+1 columns contain factor returns, (k+2)nd column contain residuals
-## scaled to have variance 1.
-## beta.vec k x 1 vector of factor betas
-## sig2.e scalar, residual variance from factor model
-## tail.prob scalar tail probability
-## output:
-## A list with the following components:
-## VaR scalar, nonparametric VaR value for fund reported as a positive number
-## n.exceed scalar, number of observations beyond VaR
-## idx.exceed n.exceed x 1 vector giving index values of exceedences
-## ES scalar, nonparametric ES value for fund reported as a positive number
-## mcES k+1 x 1 vector of factor marginal contributions to ES
-## cES k+1 x 1 vector of factor component contributions to ES
-## pcES k+1 x 1 vector of factor percent contributions to ES
-## Remarks:
-## The factor model has the form
-## R(t) = beta'F(t) + e(t) = beta.star'F.star(t)
-## where beta.star = (beta, sig.e)' and F.star(t) = (F(t)', z(t))'
-## By Euler's theorem
-## ES.fm = sum(cES.fm) = sum(beta.star*mcES.fm)
-## References:
-## 1. Hallerback (2003), "Decomposing Portfolio Value-at-Risk: A General Analysis",
-## The Journal of Risk 5/2.
-## 2. Yamai and Yoshiba (2002). "Comparative Analyses of Expected Shortfall and
-## Value-at-Risk: Their Estimation Error, Decomposition, and Optimization
-## Bank of Japan.
-## 3. Meucci (2007). "Risk Contributions from Generic User-Defined Factors," Risk.
- Data = as.matrix(Data)
- ncol.Data = ncol(Data)
- if(is.matrix(beta.vec)) {
- beta.names = c(rownames(beta.vec), "residual")
- } else if(is.vector(beta.vec)) {
- beta.names = c(names(beta.vec), "residual")
- } else {
- stop("beta.vec is not an n x 1 matrix or a vector")
- }
- beta.names = c(names(beta.vec), "residual")
- beta.star.vec = c(beta.vec, sqrt(sig2.e))
- names(beta.star.vec) = beta.names
-
- VaR.fm = quantile(Data[, 1], prob=tail.prob)
- idx = which(Data[, 1] <= VaR.fm)
- ES.fm = -mean(Data[idx, 1])
-
- ##
- ## compute marginal contribution to ES
- ##
- ## compute marginal ES as expected value of factor return given fund
- ## return is less than or equal to VaR
- mcES.fm = -as.matrix(colMeans(Data[idx, -1]))
-
-## compute correction factor so that sum of weighted marginal ES adds to portfolio ES
-#cf = as.numeric( ES.fm / sum(mcES.fm*beta.star.vec) )
-#mcES.fm = cf*mcES.fm
-cES.fm = mcES.fm*beta.star.vec
-pcES.fm = cES.fm/ES.fm
-colnames(mcES.fm) = "MCES"
-colnames(cES.fm) = "CES"
-colnames(pcES.fm) = "PCES"
-ans = list(VaR = -VaR.fm,
- n.exceed = length(idx),
- idx.exceed = idx,
- ES = ES.fm,
- mcES = t(mcES.fm),
- cES = t(cES.fm),
- pcES = t(pcES.fm))
-return(ans)
-}
-
+#' Compute Factor Model Factor ES Decomposition
+#'
+#' Compute the factor model factor expected shortfall (ES) decomposition for an
+#' asset based on Euler's theorem given historic or simulated data and factor
+#' model parameters. The partial derivative of ES with respect to factor beta
+#' is computed as the expected factor return given fund return is less than or
+#' equal to its value-at-risk (VaR). VaR is compute as the sample quantile of
+#' the historic or simulated data.
+#'
+#' The factor model has the form \cr \code{R(t) = t(beta)*F(t) + e(t) =
+#' t(beta.star)*F.star(t)} \cr where \code{beta.star = t(beta, sig.e)} and
+#' \code{F.star(t) = (t(F(t)), t(z(t)))} By Euler's theorem \cr \code{ES.fm =
+#' sum(cES.fm) = sum(beta.star*mcES.fm)} \cr
+#'
+#' @param Data \code{B x (k+2)} matrix of historic or simulated data. The first
+#' column contains the fund returns, the second through \code{k+1}st columns
+#' contain the returns on the \code{k} factors, and the \code{(k+2)}nd column
+#' contain residuals scaled to have unit variance.
+#' @param beta.vec \code{k x 1} vector of factor betas.
+#' @param sig2.e scalar, residual variance from factor model.
+#' @param tail.prob scalar, tail probability for VaR quantile. Typically 0.01
+#' or 0.05.
+#' @return A list with the following components:
+#' @returnItem VaR Scalar, nonparametric VaR value for fund reported as a
+#' positive number.
+#' @returnItem n.exceed Scalar, number of observations beyond VaR.
+#' @returnItem idx.exceed \code{n.exceed x 1} vector giving index values of
+#' exceedences.
+#' @returnItem ES scalar, nonparametric ES value for fund reported as a
+#' positive number.
+#' @returnItem mcES \code{(K+1) x 1} vector of factor marginal contributions to
+#' ES.
+#' @returnItem cES \code{(K+1) x 1} vector of factor component contributions to
+#' ES.
+#' @returnItem pcES \code{(K+1) x 1} vector of factor percent contributions to
+#' ES.
+#' @author Eric Zviot and Yi-An Chen.
+#' @references 1. Hallerback (2003), "Decomposing Portfolio Value-at-Risk: A
+#' General Analysis", \emph{The Journal of Risk} 5/2. \cr 2. Yamai and Yoshiba
+#' (2002). "Comparative Analyses of Expected Shortfall and Value-at-Risk: Their
+#' Estimation Error, Decomposition, and Optimization", Bank of Japan. \cr 3.
+#' Meucci (2007). "Risk Contributions from Generic User-Defined Factors,"
+#' \emph{Risk}.
+#' @examples
+#'
+#' data(managers.df)
+#' ret.assets = managers.df[,(1:6)]
+#' factors = managers.df[,(7:9)]
+#' # fit the factor model with OLS
+#' fit <- fitMacroeconomicFactorModel(ret.assets,factors,fit.method="OLS",
+#' variable.selection="all subsets",factor.set=3)
+#' # risk factor contribution to ETL
+#' # combine fund returns, factor returns and residual returns for HAM1
+#' tmpData = cbind(ret.assets[,1], factors,
+#' residuals(fit$asset.fit$HAM1)/sqrt(fit$residVars.vec[1]))
+#' colnames(tmpData)[c(1,5)] = c("HAM1", "residual")
+#' factor.es.decomp.HAM1 = factorModelEsDecomposition(tmpData, fit$beta.mat[1,],
+#' fit$residVars.vec[1], tail.prob=0.05)
+#'
+#'
+#'
+factorModelEsDecomposition <-
+function(Data, beta.vec, sig2.e, tail.prob = 0.05) {
+## Compute factor model factor ES decomposition based on Euler's theorem given historic
+## or simulated data and factor model parameters.
+## The partial derivative of ES wrt factor beta is computed
+## as the expected factor return given fund return is less than or equal to its VaR
+## VaR is compute either as the sample quantile or as an estimated quantile
+## using the Cornish-Fisher expansion
+## inputs:
+## Data B x (k+2) matrix of data. First column contains the fund returns,
+## second through k+1 columns contain factor returns, (k+2)nd column contain residuals
+## scaled to have variance 1.
+## beta.vec k x 1 vector of factor betas
+## sig2.e scalar, residual variance from factor model
+## tail.prob scalar tail probability
+## output:
+## A list with the following components:
+## VaR scalar, nonparametric VaR value for fund reported as a positive number
+## n.exceed scalar, number of observations beyond VaR
+## idx.exceed n.exceed x 1 vector giving index values of exceedences
+## ES scalar, nonparametric ES value for fund reported as a positive number
+## mcES k+1 x 1 vector of factor marginal contributions to ES
+## cES k+1 x 1 vector of factor component contributions to ES
+## pcES k+1 x 1 vector of factor percent contributions to ES
+## Remarks:
+## The factor model has the form
+## R(t) = beta'F(t) + e(t) = beta.star'F.star(t)
+## where beta.star = (beta, sig.e)' and F.star(t) = (F(t)', z(t))'
+## By Euler's theorem
+## ES.fm = sum(cES.fm) = sum(beta.star*mcES.fm)
+## References:
+## 1. Hallerback (2003), "Decomposing Portfolio Value-at-Risk: A General Analysis",
+## The Journal of Risk 5/2.
+## 2. Yamai and Yoshiba (2002). "Comparative Analyses of Expected Shortfall and
+## Value-at-Risk: Their Estimation Error, Decomposition, and Optimization
+## Bank of Japan.
+## 3. Meucci (2007). "Risk Contributions from Generic User-Defined Factors," Risk.
+ Data = as.matrix(Data)
+ ncol.Data = ncol(Data)
+ if(is.matrix(beta.vec)) {
+ beta.names = c(rownames(beta.vec), "residual")
+ } else if(is.vector(beta.vec)) {
+ beta.names = c(names(beta.vec), "residual")
+ } else {
+ stop("beta.vec is not an n x 1 matrix or a vector")
+ }
+ beta.names = c(names(beta.vec), "residual")
+ beta.star.vec = c(beta.vec, sqrt(sig2.e))
+ names(beta.star.vec) = beta.names
+
+ VaR.fm = quantile(Data[, 1], prob=tail.prob)
+ idx = which(Data[, 1] <= VaR.fm)
+ ES.fm = -mean(Data[idx, 1])
+
+ ##
+ ## compute marginal contribution to ES
+ ##
+ ## compute marginal ES as expected value of factor return given fund
+ ## return is less than or equal to VaR
+ mcES.fm = -as.matrix(colMeans(Data[idx, -1]))
+
+## compute correction factor so that sum of weighted marginal ES adds to portfolio ES
+#cf = as.numeric( ES.fm / sum(mcES.fm*beta.star.vec) )
+#mcES.fm = cf*mcES.fm
+cES.fm = mcES.fm*beta.star.vec
+pcES.fm = cES.fm/ES.fm
+colnames(mcES.fm) = "MCES"
+colnames(cES.fm) = "CES"
+colnames(pcES.fm) = "PCES"
+ans = list(VaR = -VaR.fm,
+ n.exceed = length(idx),
+ idx.exceed = idx,
+ ES = ES.fm,
+ mcES = t(mcES.fm),
+ cES = t(cES.fm),
+ pcES = t(pcES.fm))
+return(ans)
+}
+
Modified: pkg/FactorAnalytics/R/factorModelMonteCarlo.R
===================================================================
--- pkg/FactorAnalytics/R/factorModelMonteCarlo.R 2013-06-18 00:56:27 UTC (rev 2350)
+++ pkg/FactorAnalytics/R/factorModelMonteCarlo.R 2013-06-18 09:52:27 UTC (rev 2351)
@@ -1,109 +1,194 @@
-factorModelMonteCarlo <-
-function(n.boot=1000, factorData, Beta.mat, Alpha.mat=NULL,
- residualData, residual.dist = c("normal", "Cornish-Fisher", "skew-t"),
- boot.method = c("random", "block"),
- seed=123, return.factors= FALSE , return.residuals= FALSE ) {
-## inputs:
-## n.boot number of bootstrap samples
-## factorData n.months x n.funds matrix or data.frame of factor returns
-## Beta.mat n.funds x n.factors matrix of factor betas
-## Alpha.mat n.funds x 1 matrix of factor alphas (intercepts). If NULL then
-## assume that all alphas are zero.
-## residualData n.funds x n.parms matrix of residual distribution parameters. The
-## columns of residualData depend on the value of residual.dist. If
-## residual.dist = "normal", then residualData has one column vector
-## containing variance values; if residual.dist = "Cornish-Fisher",
-## then residualData has three columns containing variance,
-## skewness and excess kurtosis values; if residual.dist="skew-t",
-## then residualData has four columns containing location, scale,
-## shape and df values.
-## residual.dist character vector specifying the residual distribution. Choices are
-## "normal" for the normal distribution; "Cornish-Fisher" for the
-## Cornish-Fisher distribution based on the Cornish-Fisher expansion
-## of the normal distribution quantile; "skew-t" for the skewed Student's
-## t distribution of Azzalini and Captiano.
-## boot.method character vector specifying the resampling method. Choices are
-## "random" for random sampling with replacement (non-parametric bootstrap);
-## "block" for stationary block bootstrapping.
-## seed integer random number seed.
-## return.factors logical; if TRUE then return resampled factors
-## return.residuals logical; if TRUE then return simulated residuals
-##
-## output: A list with the following components:
-## returns n.boot x n.funds matrix of simulated fund returns
-## factors n.boot x n.factors matrix of resampled factor returns. Returned
-## only if return.factors = TRUE.
-## residuals n.boot x n.funds matrix of simulated fund residuals. Returned only
-## if return.residuals = TRUE.
- require(tseries) # for function tsbootstrap()
- require(sn) # for function rst()
- boot.method = boot.method[1]
- residual.dist = residual.dist[1]
- set.seed(seed)
- if (nrow(Beta.mat) != nrow(residualData)) {
- stop("Beta.mat and residualData have different number of rows")
- }
- factorData = as.matrix(factorData)
- n.funds = nrow(Beta.mat)
- fund.names = rownames(Beta.mat)
- if (is.null(Alpha.mat)) {
- Alpha.mat = matrix(0, nrow(Beta.mat))
- rownames(Alpha.mat) = fund.names
- }
-##
-## reseample from empirical distribution of factors
-##
- if (boot.method == "random") {
- bootIdx = sample(nrow(factorData), n.boot, replace=TRUE)
- } else {
- n.samples = round(n.boot/nrow(factorData))
- n.adj = n.boot - n.samples*nrow(factorData)
- bootIdx = as.vector(tsbootstrap(1:nrow(factorData), nb=n.samples))
- if (n.adj > 0) {
-## need to make sure that length(bootIdx) = n.boot
- bootIdx = c(bootIdx, bootIdx[1:n.adj])
- }
- }
- factorDataBoot = factorData[bootIdx, ]
-##
-## run factor model Monte Carlo loop over funds
-##
- fundReturnsBoot = matrix(0, n.boot, n.funds)
- residualsSim = matrix(0, n.boot, n.funds)
- colnames(fundReturnsBoot) = colnames(residualsSim) = fund.names
- for (i in fund.names) {
- ## set random number seed for fund specific residual simulations
- set.seed(which(fund.names == i))
- ## simulate from residual distributions
- if (residual.dist == "normal") {
- residualsSim[, i] = rnorm(n.boot, sd=sqrt(residualData[i,]))
- } else if (residual.dist == "Cornish-Fisher") {
- ## residual distribution is CornishFisher
- residualsSim[, i] = rCornishFisher(n.boot,
- sigma=sqrt(residualData[i,"var"]),
- skew=residualData[i,"skew"],
- ekurt=residualData[i,"ekurt"])
- } else if (residual.dist == "skew-t") {
- ## residual distribution is CornishFisher
- residualsSim[, i] = rst(n.boot,
- location=residualData[i, "location"],
- scale=residualData[i,"scale"],
- shape=residualData[i,"shape"],
- df=residualData[i,"df"])
- } else {
- stop("Invalid residual distribution")
- }
- ## simulated fund returns
- fundReturnsBoot[, i] = Alpha.mat[i,1] + factorDataBoot[, colnames(Beta.mat)] %*% t(Beta.mat[i, ,drop=FALSE]) + residualsSim[, i]
- } # end loop over funds
-
- ans = list(returns=fundReturnsBoot)
- if (return.factors) {
- ans$factors=factorDataBoot
- }
- if (return.residuals) {
- ans$residuals=residualsSim
- }
- return(ans)
-}
-
+#' Simulate returns using factor model Monte Carlo method.
+#'
+#' Simulate returns using factor model Monte Carlo method. Parametric method
+#' like normal distribution, Cornish-Fisher and skew-t distribution for
+#' residuals can be selected. Resampling method like non-parametric bootstrap
+#' or stationary bootstrap can be selected.
+#'
+#' The factor model Monte Carlo method is described in Jiang (2009).
+#'
+#' @param n.boot Integer number of bootstrap samples.
+#' @param factorData \code{n.months x n.funds} matrix or data.frame of factor
+#' returns.
+#' @param Beta.mat \code{n.funds x n.factors} matrix of factor betas.
+#' @param Alpha.mat \code{n.funds x 1} matrix of factor alphas (intercepts). If
+#' \code{NULL} then assume that all alphas are zero.
+#' @param residualData \code{n.funds x n.parms} matrix of residual distribution
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/returnanalytics -r 2351
More information about the Returnanalytics-commits
mailing list