[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