diff --git a/DESCRIPTION b/DESCRIPTION index d9085dc..2b22f8d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -25,6 +25,7 @@ Imports: lars, lattice, leaps, + methods, parallel, PerformanceAnalytics, RCurl, diff --git a/NAMESPACE b/NAMESPACE index 82e2961..5b5eea5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -153,6 +153,7 @@ importFrom(lattice,panel.xyplot) importFrom(lattice,strip.custom) importFrom(lattice,xyplot) importFrom(leaps,regsubsets) +importFrom(methods,is) importFrom(parallel,clusterEvalQ) importFrom(parallel,clusterExport) importFrom(parallel,detectCores) diff --git a/R/fitFfmDT.R b/R/fitFfmDT.R index 7e61722..18f2b4d 100644 --- a/R/fitFfmDT.R +++ b/R/fitFfmDT.R @@ -193,7 +193,7 @@ standardizeExposures <- function(specObj, weight.var <- specObj$weight.var dataDT <- data.table::copy(specObj$dataDT) # hard_copy # we did have a copy but do we really need a full copy, reference should be oka here - if (class(specObj) != "ffmSpec") { + if (is(specObj) != "ffmSpec") { stop("specObj must be class ffmSpec") } Std.Type = toupper(Std.Type[1]) @@ -711,6 +711,8 @@ fitFfmDT <- function(ffMSpecObj, #' @details this function operates on the specObje data and the output of fitFfm #' to get information on the fundamental factor. #' +#' @importFrom methods is +#' #' @seealso \code{\link{specFfm}} and \code{\link{fitFfmDT}} for information on the definition of the specFfm #' object and the usage of fitFfmDT. #' @importFrom RobStatTM covRob @@ -999,15 +1001,8 @@ extractRegressionStats <- function(specObj, fitResults, full.resid.cov=FALSE){ class(result) <- "ffm" return(result) - - - } - - - - #' @title calcFLAM #' #' @description function to calculate fundamental law of active management @@ -1287,7 +1282,7 @@ convert.ffmSpec <- function(SpecObj, FitObj, RegStatsObj, ...) { # clean up - class(ffmObj) <- "ffm" +class(ffmObj) <- "ffm" return(ffmObj) diff --git a/R/paFm.r b/R/paFm.r index eb5e22d..581b456 100644 --- a/R/paFm.r +++ b/R/paFm.r @@ -1,114 +1,115 @@ #' @title Compute cumulative mean attribution for factor models -#' -#' @description Decompose total returns into returns attributed to factors and -#' specific returns. An object of class \code{"pafm"} is generated, with +#' +#' @description Decompose total returns into returns attributed to factors and +#' specific returns. An object of class \code{"pafm"} is generated, with #' methods for generic functions \code{plot}, \code{summary} and \code{print}. -#' -#' @details Total returns can be decomposed into returns attributed to factors +#' +#' @details Total returns can be decomposed into returns attributed to factors #' and specific returns. \cr \eqn{R_t = \sum b_k * f_kt + u_t, t=1...T} \cr -#' \code{b_k} is exposure to factor k and \code{f_kt} is factor k's return at -#' time t. The return attributed to factor k is \code{b_k * f_kt} and specific -#' return is \code{u_t}. -#' +#' \code{b_k} is exposure to factor k and \code{f_kt} is factor k's return at +#' time t. The return attributed to factor k is \code{b_k * f_kt} and specific +#' return is \code{u_t}. +#' #' @importFrom PerformanceAnalytics checkData Return.cumulative chart.TimeSeries #' @importFrom xts xts #' @importFrom zoo index -#' +#' @importFrom methods is +#' #' @param fit an object of class \code{tsfm}, \code{sfm} or \code{ffm}. #' @param ... other arguments/controls passed to the fit methods. -#' +#' #' @return The returned object is of class \code{"pafm"} containing #' \item{cum.ret.attr.f}{N X K matrix of cumulative return attributed to #' factors.} #' \item{cum.spec.ret}{length-N vector of cumulative specific returns.} #' \item{attr.list}{list of time series of attributed returns for every #' portfolio.} -#' +#' #' @author Yi-An Chen and Sangeetha Srinivasan -#' -#' @references Grinold, R. and Kahn, R. (1999) Active Portfolio Management: A -#' Quantitative Approach for Producing Superior Returns and Controlling Risk. +#' +#' @references Grinold, R. and Kahn, R. (1999) Active Portfolio Management: A +#' Quantitative Approach for Producing Superior Returns and Controlling Risk. #' McGraw-Hill. -#' -#' @seealso \code{\link{fitTsfm}}, \code{\link{fitFfm}} +#' +#' @seealso \code{\link{fitTsfm}}, \code{\link{fitFfm}} #' for the factor model fitting functions. -#' -#' The \code{pafm} methods for generic functions: -#' \code{\link{plot.pafm}}, \code{\link{print.pafm}} and -#' \code{\link{summary.pafm}}. -#' +#' +#' The \code{pafm} methods for generic functions: +#' \code{\link{plot.pafm}}, \code{\link{print.pafm}} and +#' \code{\link{summary.pafm}}. +#' #' @examples #' data(managers, package = 'PerformanceAnalytics') -#' fit <- fitTsfm(asset.names=colnames(managers[, (1:6)]), -#' factor.names=c("EDHEC LS EQ","SP500 TR"), +#' fit <- fitTsfm(asset.names=colnames(managers[, (1:6)]), +#' factor.names=c("EDHEC LS EQ","SP500 TR"), #' data=managers) #' # without benchmark #' paFm(fit) -#' +#' #' @export -#' +#' paFm <- function(fit, ...) { - + # check input object validity if (!inherits(fit, c("tsfm", "sfm", "ffm"))) { stop("Invalid argument: fit should be of class 'tsfm', 'sfm' or 'ffm'.") } - - # TSFM chunk - - if (class(fit)=="tsfm") { - + + # TSFM chunk + + if (is(fit)=="tsfm") { + # return attributed to factors cum.attr.ret <- fit$beta cum.spec.ret <- fit$alpha factorNames <- fit$factor.names fundNames <- fit$asset.names - + attr.list <- list() - + for (k in fundNames) { fit.lm <- fit$asset.fit[[k]] - + ## extract information from lm, lmRob or lars object reg.xts <- na.omit(fit$data[, c(k, factorNames)]) dates <- as.Date(zoo::index(reg.xts)) actual.xts <- xts::xts(fit.lm$model[1], dates) # attributed returns - # active portfolio management p.512 17A.9 + # active portfolio management p.512 17A.9 # top-down method - + cum.ret <- PerformanceAnalytics::Return.cumulative(actual.xts) # setup initial value attr.ret.xts.all <- xts::xts(order.by = dates) - + for ( i in factorNames ) { - + if (is.na(fit$beta[k, i])) { cum.attr.ret[k, i] <- NA - attr.ret.xts.all <- xts::xts(x = rep(NA, length(dates)), + attr.ret.xts.all <- xts::xts(x = rep(NA, length(dates)), order.by = dates) - + } else { - attr.ret.xts <- actual.xts - - xts::xts(as.matrix(fit.lm$model[i])%*%as.matrix(fit.lm$coef[i]), dates) - cum.attr.ret[k, i] <- cum.ret - - PerformanceAnalytics::Return.cumulative(actual.xts-attr.ret.xts) + attr.ret.xts <- actual.xts - + xts::xts(as.matrix(fit.lm$model[i])%*%as.matrix(fit.lm$coef[i]), dates) + cum.attr.ret[k, i] <- cum.ret - + PerformanceAnalytics::Return.cumulative(actual.xts-attr.ret.xts) attr.ret.xts.all <- merge(attr.ret.xts.all, attr.ret.xts) } } - - # specific returns - spec.ret.xts <- actual.xts - - xts::xts(as.matrix(fit.lm$model[,factorNames])%*%as.matrix(fit.lm$coef[-1]), + + # specific returns + spec.ret.xts <- actual.xts - + xts::xts(as.matrix(fit.lm$model[,factorNames])%*%as.matrix(fit.lm$coef[-1]), dates) cum.spec.ret[k,1] <- cum.ret - PerformanceAnalytics::Return.cumulative(actual.xts-spec.ret.xts) attr.list[[k]] <- merge(attr.ret.xts.all, spec.ret.xts) colnames(attr.list[[k]]) <- c(factorNames, "specific.returns") } - } - - if (class(fit)=="ffm" ) { + } + + if (is(fit)=="ffm" ) { # if benchmark is provided # if (!is.null(benchmark)) { # stop("use fitFundamentalFactorModel instead") @@ -118,7 +119,7 @@ paFm <- function(fit, ...) { factor.names <- colnames(fit$beta) date <- zoo::index(factor.returns) ticker <- fit$asset.names - + #cumulative return attributed to factors if (factor.names[1] == "(Intercept)") { # discard intercept @@ -130,26 +131,26 @@ paFm <- function(fit, ...) { } cum.spec.ret <- rep(0, length(ticker)) names(cum.spec.ret) <- ticker - - # make list of every asstes and every list contains return attributed to + + # make list of every asstes and every list contains return attributed to # factors and specific returns - attr.list <- list() - + attr.list <- list() + for (k in ticker) { idx <- which(fit$data[, fit$assetvar]== k) returns <- fit$data[idx, fit$returnsvar] - num.f.names <- intersect(fit$exposure.names, factor.names) - + num.f.names <- intersect(fit$exposure.names, factor.names) + # check if there is industry factors if (length(setdiff(fit$exposure.names, factor.names)) > 0) { - ind.f <- matrix(rep(fit$beta[k, ][-(1:length(num.f.names))], + ind.f <- matrix(rep(fit$beta[k, ][-(1:length(num.f.names))], length(idx)), nrow=length(idx), byrow=TRUE) colnames(ind.f) <- colnames(fit$beta)[-(1:length(num.f.names))] - exposure <- cbind(fit$data[idx, num.f.names], ind.f) + exposure <- cbind(fit$data[idx, num.f.names], ind.f) } else { exposure <- fit$data[idx, num.f.names] } - + attr.factor <- exposure * coredata(factor.returns) specific.returns <- returns - apply(attr.factor, 1, sum) attr <- cbind(attr.factor, specific.returns) @@ -158,9 +159,9 @@ paFm <- function(fit, ...) { cum.spec.ret[k] <- PerformanceAnalytics::Return.cumulative(specific.returns) } } - - if (class(fit)=="sfm") { - + + if (is(fit)=="sfm") { + # return attributed to factors cum.attr.ret <- fit$loadings cum.spec.ret <- fit$r2 @@ -170,9 +171,9 @@ paFm <- function(fit, ...) { # create list for attribution attr.list <- list() # pca method - + if ( dim(fit$data)[1] > dim(fit$data)[2] ) { - + for (k in fundNames) { fit.lm <- fit$asset.fit[[k]] ## extract information from lm object @@ -180,23 +181,23 @@ paFm <- function(fit, ...) { # probably needs more general Date setting actual.xts <- xts::xts(fit.lm$model[1], as.Date(date)) # attributed returns - # active portfolio management p.512 17A.9 + # active portfolio management p.512 17A.9 cum.ret <- PerformanceAnalytics::Return.cumulative(actual.xts) # setup initial value attr.ret.xts.all <- xts::xts(, as.Date(date)) - + for (i in factorNames) { - attr.ret.xts <- actual.xts - - xts::xts(as.matrix(fit.lm$model[i])%*%as.matrix(fit.lm$coef[i]), - as.Date(date)) - cum.attr.ret[k,i] <- cum.ret - - PerformanceAnalytics::Return.cumulative(actual.xts - attr.ret.xts) + attr.ret.xts <- actual.xts - + xts::xts(as.matrix(fit.lm$model[i])%*%as.matrix(fit.lm$coef[i]), + as.Date(date)) + cum.attr.ret[k,i] <- cum.ret - + PerformanceAnalytics::Return.cumulative(actual.xts - attr.ret.xts) attr.ret.xts.all <- merge(attr.ret.xts.all, attr.ret.xts) } - - # specific returns - spec.ret.xts <- actual.xts - - xts::xts(as.matrix(fit.lm$model[, -1])%*%as.matrix(fit.lm$coef[-1]), + + # specific returns + spec.ret.xts <- actual.xts - + xts::xts(as.matrix(fit.lm$model[, -1])%*%as.matrix(fit.lm$coef[-1]), as.Date(date)) cum.spec.ret[k] <- cum.ret - PerformanceAnalytics::Return.cumulative(actual.xts- spec.ret.xts) attr.list[[k]] <- merge(attr.ret.xts.all, spec.ret.xts) @@ -207,37 +208,37 @@ paFm <- function(fit, ...) { # fit$loadings # N X K # fit$factors # T X K date <- zoo::index(fit$factors) - + for (k in fundNames) { attr.ret.xts.all <- xts::xts(, as.Date(date)) actual.xts <- xts::xts(fit$data[,k], as.Date(date)) cum.ret <- PerformanceAnalytics::Return.cumulative(actual.xts) - + for (i in factorNames) { attr.ret.xts <- xts::xts(fit$factors[,i]*fit$loadings[k,i], as.Date(date)) attr.ret.xts.all <- merge(attr.ret.xts.all, attr.ret.xts) - cum.attr.ret[k,i] <- cum.ret - PerformanceAnalytics::Return.cumulative(actual.xts - + cum.attr.ret[k,i] <- cum.ret - PerformanceAnalytics::Return.cumulative(actual.xts - attr.ret.xts) } - spec.ret.xts <- actual.xts - xts::xts(fit$factors%*%t(fit$loadings[k,]), + spec.ret.xts <- actual.xts - xts::xts(fit$factors%*%t(fit$loadings[k,]), as.Date(date)) cum.spec.ret[k] <- cum.ret - PerformanceAnalytics::Return.cumulative(actual.xts- spec.ret.xts) attr.list[[k]] <- merge(attr.ret.xts.all, spec.ret.xts) - colnames(attr.list[[k]]) <- c(factorNames, "specific.returns") + colnames(attr.list[[k]]) <- c(factorNames, "specific.returns") } - } + } } - - ans <- list(cum.ret.attr.f=cum.attr.ret, cum.spec.ret=cum.spec.ret, + + ans <- list(cum.ret.attr.f=cum.attr.ret, cum.spec.ret=cum.spec.ret, attr.list=attr.list) - class(ans) <- "pafm" + class(ans) <- "pafm" return(ans) } # If benchmark is provided, active return attribution will be calculated. -# active returns = total returns - benchmark returns. Specifically, -# \eqn{R_t^A = \sum_j b_{j}^A * f_{jt} + u_t^A},t=1..T, \eqn{b_{j}^A} is -# \emph{active exposure} to factor j and \eqn{f_{jt}} is factor j. The active -# returns attributed to factor j is \eqn{b_{j}^A * f_{jt}} specific returns is -# \eqn{u_t^A} +# active returns = total returns - benchmark returns. Specifically, +# \eqn{R_t^A = \sum_j b_{j}^A * f_{jt} + u_t^A},t=1..T, \eqn{b_{j}^A} is +# \emph{active exposure} to factor j and \eqn{f_{jt}} is factor j. The active +# returns attributed to factor j is \eqn{b_{j}^A * f_{jt}} specific returns is +# \eqn{u_t^A} diff --git a/R/repRisk.R b/R/repRisk.R index a88b2e2..3076d27 100644 --- a/R/repRisk.R +++ b/R/repRisk.R @@ -1,87 +1,88 @@ #' @title Decompose portfolio risk into individual factor contributions and provide tabular report -#' -#' @description Compute the factor contributions to standard deviation (SD), Value-at-Risk (VaR), -#' Expected Tail Loss or Expected Shortfall (ES) of the return of individual asset within a portfolio +#' +#' @description Compute the factor contributions to standard deviation (SD), Value-at-Risk (VaR), +#' Expected Tail Loss or Expected Shortfall (ES) of the return of individual asset within a portfolio #' return of a portfolio based on Euler's theorem, given the fitted factor model. -#' +#' #' @importFrom lattice barchart #' @importFrom data.table melt as.data.table -#' +#' @importFrom methods is +#' #' @param object fit object of class \code{tsfm}, or \code{ffm}. #' @param p tail probability for calculation. Default is 0.05. -#' @param weights a vector of weights of the assets in the portfolio, names of -#' the vector should match with asset names. Default is NULL, in which case an +#' @param weights a vector of weights of the assets in the portfolio, names of +#' the vector should match with asset names. Default is NULL, in which case an #' equal weights will be used. -#' @param risk one of 'Sd' (standard deviation), 'VaR' (Value-at-Risk) or 'ES' (Expected Tail +#' @param risk one of 'Sd' (standard deviation), 'VaR' (Value-at-Risk) or 'ES' (Expected Tail #' Loss or Expected Shortfall for calculating risk decompositon. Default is 'Sd' -#' @param decomp one of 'FMCR' (factor marginal contribution to risk), +#' @param decomp one of 'FMCR' (factor marginal contribution to risk), #' 'FCR' 'factor contribution to risk' or 'FPCR' (factor percent contribution to risk). #' @param digits digits of number in the resulting table. Default is NULL, in which case digtis = 3 will be -#' used for decomp = ( 'FMCR', 'FCR'), digits = 1 will be used for decomp = 'FPCR'. Used only when +#' used for decomp = ( 'FMCR', 'FCR'), digits = 1 will be used for decomp = 'FPCR'. Used only when #' isPrint = 'TRUE' #' @param nrowPrint a numerical value deciding number of assets/portfolio in result vector/table to print -#' or plot -#' @param type one of "np" (non-parametric) or "normal" for calculating VaR & Es. +#' or plot +#' @param type one of "np" (non-parametric) or "normal" for calculating VaR & Es. #' Default is "np". #' @param sliceby one of 'factor' (slice/condition by factor) or 'asset' (slice/condition by asset) or 'riskType' -#' Used only when isPlot = 'TRUE' +#' Used only when isPlot = 'TRUE' #' @param invert a logical variable to change VaR/ES to positive number, default #' is False and will return positive values. #' @param layout layout is a numeric vector of length 2 or 3 giving the number of columns, rows, and pages (optional) in a multipanel display. #' @param stripText.cex a number indicating the amount by which strip text in the plot(s) should be scaled relative to the default. 1=default, 1.5 is 50\% larger, 0.5 is 50\% smaller, etc. #' @param axis.cex a number indicating the amount by which axis in the plot(s) should be scaled relative to the default. 1=default, 1.5 is 50\% larger, 0.5 is 50\% smaller, etc. -#' @param portfolio.only logical variable to choose if to calculate portfolio only decomposition, in which case multiple risk measures are +#' @param portfolio.only logical variable to choose if to calculate portfolio only decomposition, in which case multiple risk measures are #' allowed. #' @param isPlot logical variable to generate plot or not. #' @param isPrint logical variable to print numeric output or not. #' @param use an optional character string giving a method for computing factor -#' covariances in the presence of missing values. This must be (an -#' abbreviation of) one of the strings "everything", "all.obs", -#' "complete.obs", "na.or.complete", or "pairwise.complete.obs". Default is +#' covariances in the presence of missing values. This must be (an +#' abbreviation of) one of the strings "everything", "all.obs", +#' "complete.obs", "na.or.complete", or "pairwise.complete.obs". Default is #' "pairwise.complete.obs". -#' @param ... other optional arguments passed to \code{\link[stats]{quantile}} and +#' @param ... other optional arguments passed to \code{\link[stats]{quantile}} and #' optional arguments passed to \code{\link[stats]{cov}} #' -#' @return A table containing -#' \item{decomp = 'FMCR'}{(N + 1) * (K + 1) matrix of marginal contributions to risk of portfolio -#' return as well assets return, with first row of values for the portfolio and the remaining rows for +#' @return A table containing +#' \item{decomp = 'FMCR'}{(N + 1) * (K + 1) matrix of marginal contributions to risk of portfolio +#' return as well assets return, with first row of values for the portfolio and the remaining rows for #' the assets in the portfolio, with (K + 1) columns containing values for the K risk factors and the #' residual respectively} -#' \item{decomp = 'FCR'}{(N + 1) * (K + 2) matrix of component contributions to risk of portfolio -#' return as well assets return, with first row of values for the portfolio and the remaining rows for +#' \item{decomp = 'FCR'}{(N + 1) * (K + 2) matrix of component contributions to risk of portfolio +#' return as well assets return, with first row of values for the portfolio and the remaining rows for #' the assets in the portfolio, with first column containing portfolio and asset risk values and remaining #' (K + 1) columns containing values for the K risk factors and the residual respectively} -#' \item{decomp = 'FPCR'}{(N + 1) * (K + 1) matrix of percentage component contributions to risk -#' of portfolio return as well assets return, with first row of values for the portfolio and the remaining rows for +#' \item{decomp = 'FPCR'}{(N + 1) * (K + 1) matrix of percentage component contributions to risk +#' of portfolio return as well assets return, with first row of values for the portfolio and the remaining rows for #' the assets in the portfolio, with (K + 1) columns containing values for the K risk factors and the #' residual respectively} #' Where, K is the number of factors, N is the number of assets. -#' +#' #' @author Douglas Martin, Lingjie Yi -#' -#' +#' +#' #' @seealso \code{\link{fitTsfm}}, \code{\link{fitFfm}} #' for the different factor model fitting functions. -#' -#' +#' +#' #' @examples #' # Time Series Factor Model -#' +#' #' data(managers, package = 'PerformanceAnalytics') -#' +#' #' fit.macro <- fitTsfm(asset.names = colnames(managers[,(1:6)]), #' factor.names = colnames(managers[,(7:9)]), -#' rf.name = colnames(managers[,10]), +#' rf.name = colnames(managers[,10]), #' data = managers) -#' -#' report <- repRisk(fit.macro, risk = "ES", decomp = 'FPCR', +#' +#' report <- repRisk(fit.macro, risk = "ES", decomp = 'FPCR', #' nrowPrint = 10) -#' report -#' +#' report +#' #' # plot -#' repRisk(fit.macro, risk = "ES", decomp = 'FPCR', isPrint = FALSE, +#' repRisk(fit.macro, risk = "ES", decomp = 'FPCR', isPrint = FALSE, #' isPlot = TRUE) -#' +#' #' # Fundamental Factor Model #' data("stocks145scores6") #' dat = stocks145scores6 @@ -91,39 +92,39 @@ #' #' # Load long-only GMV weights for the return data #' data("wtsStocks145GmvLo") -#' wtsStocks145GmvLo = round(wtsStocks145GmvLo,5) -#' +#' wtsStocks145GmvLo = round(wtsStocks145GmvLo,5) +#' #' # fit a fundamental factor model #' exposure.vars = c("SECTOR","ROE","BP","PM12M1M","SIZE","ANNVOL1M", "EP") -#' fit.cross <- fitFfm(data = dat, +#' fit.cross <- fitFfm(data = dat, #' exposure.vars = exposure.vars, -#' date.var = "DATE", -#' ret.var = "RETURN", -#' asset.var = "TICKER", -#' fit.method="WLS", +#' date.var = "DATE", +#' ret.var = "RETURN", +#' asset.var = "TICKER", +#' fit.method="WLS", #' z.score = "crossSection") -#' +#' #' repRisk(fit.cross, risk = "Sd", decomp = 'FCR', nrowPrint = 10, -#' digits = 4) -#' -#' # get the factor contributions of risk -#' repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', -#' nrowPrint = 10) -#' +#' digits = 4) +#' +#' # get the factor contributions of risk +#' repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', +#' nrowPrint = 10) +#' #' # portfolio only decomposition -#' repRisk(fit.cross, wtsStocks145GmvLo, risk = c("VaR", "ES"), decomp = 'FPCR', -#' portfolio.only = TRUE) -#' +#' repRisk(fit.cross, wtsStocks145GmvLo, risk = c("VaR", "ES"), decomp = 'FPCR', +#' portfolio.only = TRUE) +#' #' # plot -#' repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', -#' isPrint = FALSE, nrowPrint = 15, isPlot = TRUE, layout = c(4,2)) -#' @export +#' repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', +#' isPrint = FALSE, nrowPrint = 15, isPlot = TRUE, layout = c(4,2)) +#' @export repRisk <- function(object, ...) { - + # check input object validity - + if(inherits(object, "list")) { for(i in 1: length(object)) @@ -133,30 +134,30 @@ repRisk <- function(object, ...) { } UseMethod("repRisk", object[[1]]) } - + else { if (!inherits(object, c("tsfm", "ffm"))) stop("Invalid argument: Object should be of class 'tsfm' or 'ffm'.") UseMethod("repRisk") } - - + + } # #' @rdname repRisk # #' @method repRisk list # #' @importFrom utils head # #' @export -# -# repRisk.list <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), +# +# repRisk.list <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), # decomp = c('FPCR','FCR','FMCR' ), digits = NULL, invert = FALSE, -# nrowPrint = 20, p=0.05, type=c("np","normal"), use="pairwise.complete.obs", +# nrowPrint = 20, p=0.05, type=c("np","normal"), use="pairwise.complete.obs", # sliceby = c('factor', 'asset'), isPrint = TRUE, isPlot = FALSE, layout =NULL, # portfolio.only = FALSE, ...) { -# -# riskReport = function(object,weight, risk, +# +# riskReport = function(object,weight, risk, # decomp, digits,invert, -# nrowPrint, p, type, use, +# nrowPrint, p, type, use, # sliceby, isPrint, isPlot, layout, # portfolio.only) # { @@ -164,28 +165,28 @@ repRisk <- function(object, ...) { # if (!inherits(object, c("tsfm", "ffm"))) # stop("Invalid argument: Object should be of class 'tsfm' or 'ffm'.") # UseMethod("repRisk") -# } -# output.list<- lapply(X = 1:length(object), FUN = function(X){ riskReport(object[[X]],weight, risk, +# } +# output.list<- lapply(X = 1:length(object), FUN = function(X){ riskReport(object[[X]],weight, risk, # decomp, digits,invert, -# nrowPrint, p, type, use, +# nrowPrint, p, type, use, # sliceby, isPrint, isPlot, layout, # portfolio.only)}) -# +# # } -# -# +# +# #' @rdname repRisk #' @method repRisk tsfm #' @importFrom utils head #' @export -repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), +repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), decomp = c('FPCR','FCR','FMCR' ), digits = NULL, invert = FALSE, - nrowPrint = 20, p=0.05, type=c("np","normal"), use="pairwise.complete.obs", + nrowPrint = 20, p=0.05, type=c("np","normal"), use="pairwise.complete.obs", sliceby = c('factor', 'asset'), isPrint = TRUE, isPlot = FALSE, layout =NULL, stripText.cex =1,axis.cex=1,portfolio.only = FALSE, ...) { - + # if(inherits(object, "list")) # { # output.list<- lapply(X = 1:length(object), FUN = function(X){ riskReport(object[[X]])}) @@ -194,33 +195,33 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), # { # return(object$r2) # } - + # set default for type type = type[1] sliceby = sliceby[1] - + if(!portfolio.only){ risk = risk[1] } decomp = decomp[1] - + if (!(type %in% c("np","normal"))) { stop("Invalid args: type must be 'np' or 'normal' ") } - + if (!prod(risk %in% c("Sd", "VaR", "ES"))) { stop("Invalid args: risk must be 'Sd', 'VaR' or 'ES' ") } - + if (!prod(decomp %in% c('FPCR','FCR','FMCR' ))) { stop("Invalid args: decomp must be 'FMCR', 'FCR' or 'FPCR' ") } - + if(!portfolio.only){ if(length(which(risk == "Sd"))){ port.Sd = riskDecomp(object, weights = weights,risk = "Sd", ... ) asset.Sd = riskDecomp(object,risk = "Sd", portDecomp =FALSE, ... ) - + if(decomp == "FMCR"){ port = port.Sd$mSd asset = asset.Sd$mSd @@ -230,7 +231,7 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), portRM = port.Sd$portSd assetRM = asset.Sd$Sd.fm resultRM = c(portRM, assetRM) - + port = port.Sd$cSd asset = asset.Sd$cSd result = cbind(resultRM,rbind(port, asset)) @@ -244,11 +245,11 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), result = cbind(rowSums(result), result) colnames(result)[1] = 'Total' } - + } else if(length(which(risk == "VaR"))){ port.VaR = riskDecomp(object, risk = "VaR", weights = weights, p = p, type = type, invert = invert, ... ) asset.VaR = riskDecomp(object, p = p, type = type, invert = invert, risk = "VaR", portDecomp =FALSE, ... ) - + if(decomp == "FMCR"){ port = port.VaR$mVaR asset = asset.VaR$mVaR @@ -258,7 +259,7 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), portRM = port.VaR$portVaR assetRM = asset.VaR$VaR.fm resultRM = c(portRM, assetRM) - + port = port.VaR$cVaR asset = asset.VaR$cVaR result = cbind(resultRM,rbind(port, asset)) @@ -272,11 +273,11 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), result = cbind(rowSums(result), result) colnames(result)[1] = 'Total' } - + } else if(length(which(risk == "ES"))){ port.Es = riskDecomp(object, risk = "ES", weights = weights, p = p, type = type, invert = invert, ... ) asset.Es = riskDecomp(object, p = p, type = type, invert = invert,risk = "ES", portDecomp =FALSE, ... ) - + if(decomp == "FMCR"){ port = port.Es$mES asset = asset.Es$mES @@ -286,7 +287,7 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), portRM = port.Es$portES assetRM = asset.Es$ES.fm resultRM = c(portRM, assetRM) - + port = port.Es$cES asset = asset.Es$cES result = cbind(resultRM,rbind(port, asset)) @@ -300,19 +301,19 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), result = cbind(rowSums(result), result) colnames(result)[1] = 'Total' } - + } - + if(isPlot){ if(decomp == "FCR"){ result = result[,-1] }else if(decomp == "FPCR"){ result = result[,-1] } - + if(sliceby == 'factor'){ result = head(result, nrowPrint) - + if(is.null(layout)){ n = ncol(result) l = 3 @@ -321,14 +322,14 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } layout = c(l,1) } - + print(barchart(result[rev(rownames(result)),], groups = FALSE, main = paste(decomp,"of", risk),layout = layout, scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black", cex = stripText.cex),ylab = '', xlab = '', as.table = TRUE)) - + }else if(sliceby == 'asset'){ result = head(result, nrowPrint) result = t(result) - + if(is.null(layout)){ n = ncol(result) l = 3 @@ -337,12 +338,12 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } layout = c(l,1) } - - print(barchart(result[rev(rownames(result)),], groups = FALSE, main = paste(decomp,"of", risk),layout = layout, + + print(barchart(result[rev(rownames(result)),], groups = FALSE, main = paste(decomp,"of", risk),layout = layout, scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black", cex = stripText.cex),ylab = '', xlab = '', as.table = TRUE)) } } - + if(isPrint){ if(is.null(digits)){ if(decomp == 'FPCR'){ @@ -353,17 +354,17 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } result = head(result, nrowPrint) result = round(result, digits) - + output = list(decomp = result) names(output) = paste(risk,decomp,sep = '') - + return(output) } } else{ port.Sd = riskDecomp(object, risk = "Sd", weights = weights, ... ) port.VaR = riskDecomp(object, risk = "VaR", weights = weights, p = p, type = type, invert = invert, ... ) port.Es = riskDecomp(object, risk = "ES", weights = weights, p = p, type = type, invert = invert, ... ) - + if(decomp == "FMCR"){ Sd = port.Sd$mSd VaR = port.VaR$mVaR @@ -377,7 +378,7 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), EsRM = port.Es$portES resultRM = c(SdRM, VaRRM, EsRM) names(resultRM) = c('Sd','VaR','ES') - + Sd = port.Sd$cSd VaR = port.VaR$cVaR Es = port.Es$cES @@ -396,7 +397,7 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), colnames(result)[1] = 'Total' result = result[risk,] } - + if(isPrint){ if(is.null(digits)){ if(decomp == 'FPCR'){ @@ -406,7 +407,7 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } } result = round(result, digits) - + if(type=="normal"){ Type = 'Parametric Normal' }else{ @@ -414,10 +415,10 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } output = list(decomp = result) names(output) = paste('Portfolio',decomp, Type, sep = ' ') - + return(output) } - + } } @@ -428,39 +429,39 @@ repRisk.tsfm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), decomp = c('FMCR', 'FCR', 'FPCR'), digits = NULL, invert = FALSE, - nrowPrint = 20, p=0.05, type=c("np","normal"), + nrowPrint = 20, p=0.05, type=c("np","normal"), sliceby = c('factor', 'asset', 'riskType'), isPrint = TRUE, isPlot = FALSE, layout =NULL, stripText.cex =1,axis.cex=1,portfolio.only = FALSE, ...) { riskReport = function(object,X,mul.port) { - + if(mul.port) weights = weights[[X]] # set default for type type = type[1] sliceby = sliceby[1] - + if(!portfolio.only){ risk = risk[1] } decomp = decomp[1] - + if (!(type %in% c("np","normal"))) { stop("Invalid args: type must be 'np' or 'normal' ") } - + if (!prod(risk %in% c("Sd", "VaR", "ES"))) { stop("Invalid args: risk must be 'Sd', 'VaR' or 'ES' ") } - + if (!prod(decomp %in% c( 'FMCR', 'FCR', 'FPCR'))) { stop("Invalid args: decomp must be 'FMCR', 'FCR' or 'FPCR' ") } - + if(!portfolio.only){ if(length(which(risk == "Sd"))){ port.Sd = riskDecomp(object,risk = "Sd",weights = weights, ... ) asset.Sd = riskDecomp(object,risk = "Sd", portDecomp =FALSE, ... ) - + if(decomp == "FMCR"){ port = port.Sd$mSd asset = asset.Sd$mSd @@ -470,7 +471,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), portRM = port.Sd$portSd assetRM = asset.Sd$Sd.fm resultRM = c(portRM, assetRM) - + port = port.Sd$cSd asset = asset.Sd$cSd result = cbind(resultRM,rbind(port, asset)) @@ -484,11 +485,11 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), result = cbind(rowSums(result), result) colnames(result)[1] = 'Total' } - + } else if(length(which(risk == "VaR"))){ port.VaR = riskDecomp(object, risk = "VaR", weights = weights, p = p, type = type, invert = invert, ... ) asset.VaR = riskDecomp(object,risk = "VaR", portDecomp =FALSE, p = p, type = type, invert = invert, ... ) - + if(decomp == "FMCR"){ port = port.VaR$mVaR asset = asset.VaR$mVaR @@ -498,7 +499,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), portRM = port.VaR$portVaR assetRM = asset.VaR$VaR.fm resultRM = c(portRM, assetRM) - + port = port.VaR$cVaR asset = asset.VaR$cVaR result = cbind(resultRM,rbind(port, asset)) @@ -512,11 +513,11 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), result = cbind(rowSums(result), result) colnames(result)[1] = 'Total' } - + } else if(length(which(risk == "ES"))){ port.Es = riskDecomp(object, risk = "ES", weights = weights, p = p, type = type, invert = invert, ... ) asset.Es = riskDecomp(object,risk = "ES", portDecomp =FALSE, p = p, type = type, invert = invert, ... ) - + if(decomp == "FMCR"){ port = port.Es$mES asset = asset.Es$mES @@ -526,7 +527,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), portRM = port.Es$portES assetRM = asset.Es$ES.fm resultRM = c(portRM, assetRM) - + port = port.Es$cES asset = asset.Es$cES result = cbind(resultRM,rbind(port, asset)) @@ -540,19 +541,19 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), result = cbind(rowSums(result), result) colnames(result)[1] = 'Total' } - + } - + if(isPlot){ if(decomp == "FCR"){ result = result[,-1] }else if(decomp == "FPCR"){ result = result[,-1] } - + if(sliceby == 'factor'){ result = head(result, nrowPrint) - + if(is.null(layout)){ n = ncol(result) l = 3 @@ -561,14 +562,14 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } layout = c(l,1) } - + print(barchart(result[rev(rownames(result)),], groups = FALSE, main = paste(decomp,"of", risk, switch(mul.port, "1" = paste("for port", X), "")),layout = layout, scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black", cex = stripText.cex),ylab = '', xlab = '', as.table = TRUE)) - + }else if(sliceby == 'asset'){ result = head(result, nrowPrint) result = t(result) - + if(is.null(layout)){ n = ncol(result) l = 3 @@ -577,12 +578,12 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } layout = c(l,1) } - - print(barchart(result[rev(rownames(result)),], groups = FALSE, main = paste(decomp,"of", risk, switch(mul.port, "1" = paste("for port", X), "")),layout = layout, + + print(barchart(result[rev(rownames(result)),], groups = FALSE, main = paste(decomp,"of", risk, switch(mul.port, "1" = paste("for port", X), "")),layout = layout, scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black", cex = stripText.cex),ylab = '', xlab = '', as.table = TRUE)) } } - + if(isPrint){ if(is.null(digits)){ if(decomp == 'FPCR'){ @@ -593,17 +594,17 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } result = head(result, nrowPrint) result = round(result, digits) - + output = list(decomp = result) names(output) = paste(risk,decomp,sep = '') - + return(output) } } else{ port.Sd = riskDecomp(object, risk = "Sd", weights = weights, ... ) port.VaR = riskDecomp(object, risk ="VaR", weights = weights, p = p, type = type, invert = invert, ... ) port.Es = riskDecomp(object,risk ="ES", weights = weights, p = p, type = type, invert = invert, ... ) - + if(decomp == "FMCR"){ Sd = port.Sd$mSd VaR = port.VaR$mVaR @@ -617,7 +618,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), EsRM = port.Es$portES resultRM = c(SdRM, VaRRM, EsRM) names(resultRM) = c('Sd','VaR','ES') - + Sd = port.Sd$cSd VaR = port.VaR$cVaR Es = port.Es$cES @@ -636,7 +637,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), colnames(result)[1] = 'Total' result = result[risk,] } - + if(isPrint){ if(is.null(digits)){ if(decomp == 'FPCR'){ @@ -646,7 +647,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } } result = round(result, digits) - + if(type=="normal"){ Type = 'Parametric Normal' }else{ @@ -654,12 +655,12 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), } output = list(decomp = result) names(output) = paste('Portfolio',decomp, Type, sep = ' ') - + } if(isPlot & !mul.port){ - + # single portfolio with multiple risks - if(class(result) == "matrix") + if(is(result) == "matrix") { result = output[[1]] result.mat = result[,-1] @@ -672,7 +673,7 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black",font=2, cex = stripText.cex),ylab = '', xlab = '', as.table = TRUE)) } } - else + else { result = result[-1] result.mat = matrix(result, ncol =1) @@ -680,13 +681,13 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), colnames(result.mat) = risk print(barchart(result.mat,stack = TRUE,groups = FALSE, main = list(paste("Portfolio", risk, "Decomposition- ",decomp ), cex = axis.cex),layout = layout, horizontal = FALSE, scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black",font=2, cex = stripText.cex),ylab = '', xlab = '', as.table = T)) - + } - + } return(output) } - + } if(inherits(object, "list")) { @@ -707,17 +708,17 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), risk.type = rep(risk, 0.5*nrow(result.mat)) #result.mat = cbind(result.mat, Risk = factor(risk.type)) result.mat = result.mat[-c(1:length(risk)),] - newdata = data.table::melt(data.table::as.data.table(t(result.mat)), + newdata = data.table::melt(data.table::as.data.table(t(result.mat)), id.vars = as.factor(colnames(result.mat))) - + newdata$risk = factor(rep(risk, )) - - print(barchart(value~Var1|Var2*risk, data = newdata, stack = TRUE, - origin = 0, - main = list(paste("Portfolio Risk Comparison- ", decomp), - cex = axis.cex), + + print(barchart(value~Var1|Var2*risk, data = newdata, stack = TRUE, + origin = 0, + main = list(paste("Portfolio Risk Comparison- ", decomp), + cex = axis.cex), layout = layout, - scales=list(y=list(cex=axis.cex), + scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)), par.strip.text=list(col="black", font=2, cex = stripText.cex), ylab = '', xlab = '', as.table = TRUE)) @@ -728,18 +729,18 @@ repRisk.ffm <- function(object, weights = NULL, risk = c("Sd", "VaR", "ES"), rownames(result.mat) = names(output.list[[1]][[1]]) #Remove Total result.mat = result.mat[-1,] - - newdata = data.table::melt(data.table::as.data.table(t(result.mat)), + + newdata = data.table::melt(data.table::as.data.table(t(result.mat)), id.vars = as.factor(colnames(result.mat))) - + print(barchart(value~Var1|Var2, data = newdata,stack = TRUE, origin =0, main = list(paste("Portfolio Risk Comparison- ",risk,decomp), cex = axis.cex),layout = layout, scales=list(y=list(cex=axis.cex), x=list(cex=axis.cex)),par.strip.text=list(col="black",font=2, cex = stripText.cex),ylab = '', xlab = '', as.table = TRUE)) # barchart(value~Var1|Var2, data = newdata, stack = TRUE, origin =0, scales = list(y = list(cex = axis.cex)),par.settings = my.settings, # par.strip.text=list(col="black", cex = stripText.cex), group = Var1,auto.key=list(space="right",points=FALSE, rectangles=TRUE,title="", cex.title=stripText.cex)) }} - } + } else output.list<- riskReport(object,1, mul.port = FALSE) return(output.list) - + } diff --git a/man/paFm.Rd b/man/paFm.Rd index e396bcc..3265bdd 100644 --- a/man/paFm.Rd +++ b/man/paFm.Rd @@ -20,37 +20,37 @@ factors.} portfolio.} } \description{ -Decompose total returns into returns attributed to factors and -specific returns. An object of class \code{"pafm"} is generated, with +Decompose total returns into returns attributed to factors and +specific returns. An object of class \code{"pafm"} is generated, with methods for generic functions \code{plot}, \code{summary} and \code{print}. } \details{ -Total returns can be decomposed into returns attributed to factors +Total returns can be decomposed into returns attributed to factors and specific returns. \cr \eqn{R_t = \sum b_k * f_kt + u_t, t=1...T} \cr -\code{b_k} is exposure to factor k and \code{f_kt} is factor k's return at -time t. The return attributed to factor k is \code{b_k * f_kt} and specific +\code{b_k} is exposure to factor k and \code{f_kt} is factor k's return at +time t. The return attributed to factor k is \code{b_k * f_kt} and specific return is \code{u_t}. } \examples{ data(managers, package = 'PerformanceAnalytics') -fit <- fitTsfm(asset.names=colnames(managers[, (1:6)]), - factor.names=c("EDHEC LS EQ","SP500 TR"), +fit <- fitTsfm(asset.names=colnames(managers[, (1:6)]), + factor.names=c("EDHEC LS EQ","SP500 TR"), data=managers) # without benchmark paFm(fit) } \references{ -Grinold, R. and Kahn, R. (1999) Active Portfolio Management: A -Quantitative Approach for Producing Superior Returns and Controlling Risk. +Grinold, R. and Kahn, R. (1999) Active Portfolio Management: A +Quantitative Approach for Producing Superior Returns and Controlling Risk. McGraw-Hill. } \seealso{ -\code{\link{fitTsfm}}, \code{\link{fitFfm}} +\code{\link{fitTsfm}}, \code{\link{fitFfm}} for the factor model fitting functions. -The \code{pafm} methods for generic functions: -\code{\link{plot.pafm}}, \code{\link{print.pafm}} and +The \code{pafm} methods for generic functions: +\code{\link{plot.pafm}}, \code{\link{print.pafm}} and \code{\link{summary.pafm}}. } \author{ diff --git a/man/repRisk.Rd b/man/repRisk.Rd index 04846b2..0ad587e 100644 --- a/man/repRisk.Rd +++ b/man/repRisk.Rd @@ -52,21 +52,21 @@ repRisk(object, ...) \arguments{ \item{object}{fit object of class \code{tsfm}, or \code{ffm}.} -\item{...}{other optional arguments passed to \code{\link[stats]{quantile}} and +\item{...}{other optional arguments passed to \code{\link[stats]{quantile}} and optional arguments passed to \code{\link[stats]{cov}}} -\item{weights}{a vector of weights of the assets in the portfolio, names of -the vector should match with asset names. Default is NULL, in which case an +\item{weights}{a vector of weights of the assets in the portfolio, names of +the vector should match with asset names. Default is NULL, in which case an equal weights will be used.} -\item{risk}{one of 'Sd' (standard deviation), 'VaR' (Value-at-Risk) or 'ES' (Expected Tail +\item{risk}{one of 'Sd' (standard deviation), 'VaR' (Value-at-Risk) or 'ES' (Expected Tail Loss or Expected Shortfall for calculating risk decompositon. Default is 'Sd'} -\item{decomp}{one of 'FMCR' (factor marginal contribution to risk), +\item{decomp}{one of 'FMCR' (factor marginal contribution to risk), 'FCR' 'factor contribution to risk' or 'FPCR' (factor percent contribution to risk).} \item{digits}{digits of number in the resulting table. Default is NULL, in which case digtis = 3 will be -used for decomp = ( 'FMCR', 'FCR'), digits = 1 will be used for decomp = 'FPCR'. Used only when +used for decomp = ( 'FMCR', 'FCR'), digits = 1 will be used for decomp = 'FPCR'. Used only when isPrint = 'TRUE'} \item{invert}{a logical variable to change VaR/ES to positive number, default @@ -77,13 +77,13 @@ or plot} \item{p}{tail probability for calculation. Default is 0.05.} -\item{type}{one of "np" (non-parametric) or "normal" for calculating VaR & Es. +\item{type}{one of "np" (non-parametric) or "normal" for calculating VaR & Es. Default is "np".} \item{use}{an optional character string giving a method for computing factor -covariances in the presence of missing values. This must be (an -abbreviation of) one of the strings "everything", "all.obs", -"complete.obs", "na.or.complete", or "pairwise.complete.obs". Default is +covariances in the presence of missing values. This must be (an +abbreviation of) one of the strings "everything", "all.obs", +"complete.obs", "na.or.complete", or "pairwise.complete.obs". Default is "pairwise.complete.obs".} \item{sliceby}{one of 'factor' (slice/condition by factor) or 'asset' (slice/condition by asset) or 'riskType' @@ -99,28 +99,28 @@ Used only when isPlot = 'TRUE'} \item{axis.cex}{a number indicating the amount by which axis in the plot(s) should be scaled relative to the default. 1=default, 1.5 is 50\% larger, 0.5 is 50\% smaller, etc.} -\item{portfolio.only}{logical variable to choose if to calculate portfolio only decomposition, in which case multiple risk measures are +\item{portfolio.only}{logical variable to choose if to calculate portfolio only decomposition, in which case multiple risk measures are allowed.} } \value{ -A table containing -\item{decomp = 'FMCR'}{(N + 1) * (K + 1) matrix of marginal contributions to risk of portfolio -return as well assets return, with first row of values for the portfolio and the remaining rows for +A table containing +\item{decomp = 'FMCR'}{(N + 1) * (K + 1) matrix of marginal contributions to risk of portfolio +return as well assets return, with first row of values for the portfolio and the remaining rows for the assets in the portfolio, with (K + 1) columns containing values for the K risk factors and the residual respectively} -\item{decomp = 'FCR'}{(N + 1) * (K + 2) matrix of component contributions to risk of portfolio -return as well assets return, with first row of values for the portfolio and the remaining rows for +\item{decomp = 'FCR'}{(N + 1) * (K + 2) matrix of component contributions to risk of portfolio +return as well assets return, with first row of values for the portfolio and the remaining rows for the assets in the portfolio, with first column containing portfolio and asset risk values and remaining (K + 1) columns containing values for the K risk factors and the residual respectively} -\item{decomp = 'FPCR'}{(N + 1) * (K + 1) matrix of percentage component contributions to risk -of portfolio return as well assets return, with first row of values for the portfolio and the remaining rows for +\item{decomp = 'FPCR'}{(N + 1) * (K + 1) matrix of percentage component contributions to risk +of portfolio return as well assets return, with first row of values for the portfolio and the remaining rows for the assets in the portfolio, with (K + 1) columns containing values for the K risk factors and the residual respectively} Where, K is the number of factors, N is the number of assets. } \description{ -Compute the factor contributions to standard deviation (SD), Value-at-Risk (VaR), -Expected Tail Loss or Expected Shortfall (ES) of the return of individual asset within a portfolio +Compute the factor contributions to standard deviation (SD), Value-at-Risk (VaR), +Expected Tail Loss or Expected Shortfall (ES) of the return of individual asset within a portfolio return of a portfolio based on Euler's theorem, given the fitted factor model. } \examples{ @@ -130,15 +130,15 @@ data(managers, package = 'PerformanceAnalytics') fit.macro <- fitTsfm(asset.names = colnames(managers[,(1:6)]), factor.names = colnames(managers[,(7:9)]), - rf.name = colnames(managers[,10]), + rf.name = colnames(managers[,10]), data = managers) - -report <- repRisk(fit.macro, risk = "ES", decomp = 'FPCR', + +report <- repRisk(fit.macro, risk = "ES", decomp = 'FPCR', nrowPrint = 10) -report +report # plot -repRisk(fit.macro, risk = "ES", decomp = 'FPCR', isPrint = FALSE, +repRisk(fit.macro, risk = "ES", decomp = 'FPCR', isPrint = FALSE, isPlot = TRUE) # Fundamental Factor Model @@ -150,32 +150,32 @@ dat = dat[dat$DATE >=zoo::as.yearmon("2008-01-01") & dat$DATE <= zoo::as.yearmon # Load long-only GMV weights for the return data data("wtsStocks145GmvLo") -wtsStocks145GmvLo = round(wtsStocks145GmvLo,5) - +wtsStocks145GmvLo = round(wtsStocks145GmvLo,5) + # fit a fundamental factor model exposure.vars = c("SECTOR","ROE","BP","PM12M1M","SIZE","ANNVOL1M", "EP") -fit.cross <- fitFfm(data = dat, +fit.cross <- fitFfm(data = dat, exposure.vars = exposure.vars, - date.var = "DATE", - ret.var = "RETURN", - asset.var = "TICKER", - fit.method="WLS", + date.var = "DATE", + ret.var = "RETURN", + asset.var = "TICKER", + fit.method="WLS", z.score = "crossSection") - + repRisk(fit.cross, risk = "Sd", decomp = 'FCR', nrowPrint = 10, - digits = 4) - -# get the factor contributions of risk -repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', - nrowPrint = 10) - + digits = 4) + +# get the factor contributions of risk +repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', + nrowPrint = 10) + # portfolio only decomposition -repRisk(fit.cross, wtsStocks145GmvLo, risk = c("VaR", "ES"), decomp = 'FPCR', - portfolio.only = TRUE) - +repRisk(fit.cross, wtsStocks145GmvLo, risk = c("VaR", "ES"), decomp = 'FPCR', + portfolio.only = TRUE) + # plot -repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', - isPrint = FALSE, nrowPrint = 15, isPlot = TRUE, layout = c(4,2)) +repRisk(fit.cross, wtsStocks145GmvLo, risk = "Sd", decomp = 'FPCR', + isPrint = FALSE, nrowPrint = 15, isPlot = TRUE, layout = c(4,2)) } \seealso{ \code{\link{fitTsfm}}, \code{\link{fitFfm}}