[Returnanalytics-commits] r2636 - in pkg/FactorAnalytics: R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Jul 24 00:21:38 CEST 2013
Author: chenyian
Date: 2013-07-24 00:21:38 +0200 (Wed, 24 Jul 2013)
New Revision: 2636
Modified:
pkg/FactorAnalytics/R/factorModelEsDecomposition.R
pkg/FactorAnalytics/R/factorModelMonteCarlo.R
pkg/FactorAnalytics/R/plot.FundamentalFactorModel.r
pkg/FactorAnalytics/man/factorModelEsDecomposition.Rd
pkg/FactorAnalytics/man/factorModelMonteCarlo.Rd
pkg/FactorAnalytics/man/fitFundamentalFactorModel.Rd
pkg/FactorAnalytics/man/plot.FundamentalFactorModel.Rd
pkg/FactorAnalytics/man/predict.FundamentalFactorModel.Rd
Log:
1. Debugging plot.FundamentalFactorModel.Rd and factorModelEsDecomposition.R
2. test factorModelMonteCarlo.R
Modified: pkg/FactorAnalytics/R/factorModelEsDecomposition.R
===================================================================
--- pkg/FactorAnalytics/R/factorModelEsDecomposition.R 2013-07-23 19:43:07 UTC (rev 2635)
+++ pkg/FactorAnalytics/R/factorModelEsDecomposition.R 2013-07-23 22:21:38 UTC (rev 2636)
@@ -1,140 +1,151 @@
-#' 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)
-}
-
+#' 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)
+#'
+#' # fundamental factor model
+#' # try to find factor contribution to ES for STI
+#' idx <- fit.fund$data[,fit.fund$assetvar] == "STI"
+#' asset.ret <- fit.fund$data[idx,fit.fund$returnsvar]
+#' tmpData = cbind(asset.ret, fit.fund$factors,
+#' fit.fund$residuals[,"STI"]/sqrt(fit.fund$resid.variance["STI"]) )
+#' colnames(tmpData)[c(1,length(tmpData[1,]))] = c("STI", "residual")
+#' factorModelEsDecomposition(tmpData,
+#' fit.fund$beta["STI",],
+#' fit.fund$resid.variance["STI"], 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-07-23 19:43:07 UTC (rev 2635)
+++ pkg/FactorAnalytics/R/factorModelMonteCarlo.R 2013-07-23 22:21:38 UTC (rev 2636)
@@ -1,194 +1,164 @@
-#' 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
-#' parameters. The columns of \code{residualData} depend on the value of
-#' \code{residual.dist}. If \code{residual.dist = "normal"}, then
-#' \code{residualData} has one column containing variance values; if
-#' \code{residual.dist = "Cornish-Fisher"}, then \code{residualData} has three
-#' columns containing variance, skewness and excess kurtosis values; if
-#' \code{residual.dist="skew-t"}, then \code{residualData} has four columns
-#' containing location, scale, shape, and df values.
-#' @param 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.
-#' @param boot.method character vector specifying the resampling method.
-#' Choices are "random" for random sampling with replacement (non-parametric
-#' bootstrap); "block" for stationary block bootstrapping.
-#' @param seed integer random number seed used for resampling the factor
-#' returns.
-#' @param return.factors logical; if \code{TRUE} then return resampled factors
-#' in output list object.
-#' @param return.residuals logical; if \code{TRUE} then return simulated
-#' residuals in output list object.
-#' @return A list with the following components:
-#' @returnItem returns \code{n.boot x n.funds} matrix of simulated fund
-#' returns.
-#' @returnItem factors \code{n.boot x n.factors} matrix of resampled factor
-#' returns. Returned only if \code{return.factors = TRUE}.
-#' @returnItem residuals \code{n.boot x n.funds} matrix of simulated fund
-#' residuals. Returned only if \code{return.residuals = TRUE}.
-#' @author Eric Zivot and Yi-An Chen.
-#' @references Jiang, Y. (2009). UW PhD Thesis.
-#' @examples
-#'
-#' # load data from the database
-#' 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)
-#' factorData=factors
-#' Beta.mat=fit$beta.mat
-#' residualData=as.matrix(fit$residVars.vec,1,6)
-#' n.boot=1000
-#' # bootstrap returns data from factor model with residuals sample from normal distribution
-#' bootData <- factorModelMonteCarlo(n.boot, factorData,Beta.mat, residual.dist="normal",
-#' residualData, Alpha.mat=NULL, boot.method="random",
-#' seed = 123, return.factors = "TRUE", return.residuals =
-#' "TRUE")
-#' # Cornish-Fisher distribution
-#' # build different residualData matrix
-#' residualData <- cbind(c(1,2,1,3,0.1,0.5),rnorm(6),c(2,3,1,2,1,0))
-#' colnames(residualData) <- c("var","skew","ekurt")
-#' rownames(residualData) <- colnames(managers.df[,(1:6)])
-#' bootData <- factorModelMonteCarlo(n.boot, factorData,Beta.mat, residual.dist="Cornish-Fisher",
-#' residualData, Alpha.mat=NULL, boot.method="random",
-#' seed = 123, return.factors = "TRUE", return.residuals =
-#' "TRUE")
-#'
-#'
-#' # skew-t distribution
-#' # build residualData matrix
-#' residualData <- cbind(rnorm(6),c(1,2,1,3,0.1,0.5),rnorm(6),c(2,3,1,6,10,100))
-#' colnames(residualData) <- c("location","scale","shape","df")
-#' rownames(residualData) <- colnames(managers.df[,(1:6)])
-#' bootData <- factorModelMonteCarlo(n.boot, factorData,Beta.mat, residual.dist="skew-t",
-#' residualData, Alpha.mat=NULL, boot.method="random",
-#' seed = 123, return.factors = "TRUE", return.residuals =
-#' "TRUE")
-#'
-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
+#' parameters. The columns of \code{residualData} depend on the value of
+#' \code{residual.dist}. If \code{residual.dist = "normal"}, then
+#' \code{residualData} has one column containing variance values; if
+#' \code{residual.dist = "Cornish-Fisher"}, then \code{residualData} has three
+#' columns containing variance, skewness and excess kurtosis values; if
+#' \code{residual.dist="skew-t"}, then \code{residualData} has four columns
+#' containing location, scale, shape, and df values.
+#' @param 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.
+#' @param boot.method character vector specifying the resampling method.
+#' Choices are "random" for random sampling with replacement (non-parametric
+#' bootstrap); "block" for stationary block bootstrapping.
+#' @param seed integer random number seed used for resampling the factor
+#' returns.
+#' @param return.factors logical; if \code{TRUE} then return resampled factors
+#' in output list object.
+#' @param return.residuals logical; if \code{TRUE} then return simulated
+#' residuals in output list object.
+#' @return A list with the following components:
+#' @returnItem returns \code{n.boot x n.funds} matrix of simulated fund
+#' returns.
+#' @returnItem factors \code{n.boot x n.factors} matrix of resampled factor
+#' returns. Returned only if \code{return.factors = TRUE}.
+#' @returnItem residuals \code{n.boot x n.funds} matrix of simulated fund
+#' residuals. Returned only if \code{return.residuals = TRUE}.
+#' @author Eric Zivot and Yi-An Chen.
+#' @references Jiang, Y. (2009). UW PhD Thesis.
+#' @examples
+#'
+#' # load data from the database
+#' data(managers.df)
+#' fit <- fitTimeseriesFactorModel(assets.names=colnames(managers.df[,(1:6)]),
+#' factors.names=c("EDHEC.LS.EQ","SP500.TR"),
+#' data=managers.df,fit.method="OLS")
+#' factorData=factors
+#' Beta.mat=fit$beta.mat
+#' residualData=as.matrix(fit$residVars.vec,1,6)
+#' n.boot=1000
+#' # bootstrap returns data from factor model with residuals sample from normal distribution
+#' bootData <- factorModelMonteCarlo(n.boot, factorData,Beta.mat, residual.dist="normal",
+#' residualData, Alpha.mat=NULL, boot.method="random",
+#' seed = 123, return.factors = "TRUE", return.residuals =
+#' "TRUE")
+#' # Cornish-Fisher distribution
+#' # build different residualData matrix
+#' residualData <- cbind(c(1,2,1,3,0.1,0.5),rnorm(6),c(2,3,1,2,1,0))
+#' colnames(residualData) <- c("var","skew","ekurt")
+#' rownames(residualData) <- colnames(managers.df[,(1:6)])
+#' bootData <- factorModelMonteCarlo(n.boot, factorData,Beta.mat, residual.dist="Cornish-Fisher",
+#' residualData, Alpha.mat=NULL, boot.method="random",
+#' seed = 123, return.factors = "TRUE", return.residuals =
+#' "TRUE")
+#'
+#'
+#' # skew-t distribution
+#' # build residualData matrix
+#' residualData <- cbind(rnorm(6),c(1,2,1,3,0.1,0.5),rnorm(6),c(2,3,1,6,10,100))
+#' colnames(residualData) <- c("location","scale","shape","df")
+#' rownames(residualData) <- colnames(managers.df[,(1:6)])
+#' bootData <- factorModelMonteCarlo(n.boot, factorData,Beta.mat, residual.dist="skew-t",
+#' residualData, Alpha.mat=NULL, boot.method="random",
+#' seed = 123, return.factors = "TRUE", return.residuals =
+#' "TRUE")
+#'
+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 ) {
+
+
+ require(tseries) # for function tsbootstrap()
+ require(sn) # for function rst()
+ require(PerformanceAnalytics)
+
+ 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)
+}
+
Modified: pkg/FactorAnalytics/R/plot.FundamentalFactorModel.r
===================================================================
--- pkg/FactorAnalytics/R/plot.FundamentalFactorModel.r 2013-07-23 19:43:07 UTC (rev 2635)
+++ pkg/FactorAnalytics/R/plot.FundamentalFactorModel.r 2013-07-23 22:21:38 UTC (rev 2636)
@@ -11,9 +11,30 @@
#'
#' @param fit.fund fit object created by fitFundamentalFactorModel.
#' @param which.plot integer indicating which plot to create: "none" will
-#' create a menu to choose. Defualt is none. 1 = "factor returns", 2 = "R
-#' square", 3 = "Variance of Residuals", 4 = "FM Correlation",
-#' @param max.show Maximum assets to plot. Default is 12.
+#' create a menu to choose. Defualt is none.
+#' 1 = "Factor returns",
+#' 2 = "Residual plots",
+#' 3 = "Variance of Residuals",
+#' 4 = "Factor Model Correlation",
+#' 5 = "Factor Contributions to SD",
+#' 6 = "Factor Contributions to ES",
+#' 7 = "Factor Contributions to VaR"
+#' @param max.show Maximum assets to plot. Default is 4.
+#' #' @param plot.single Plot a single asset of lm class. Defualt is FALSE.
+#' @param asset.name Name of the asset to be plotted.
+#' @param which.plot.single integer indicating which plot to create: "none"
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/returnanalytics -r 2636
More information about the Returnanalytics-commits
mailing list