[Returnanalytics-commits] r4016 - in pkg/FactorAnalytics: . R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Mar 18 14:31:23 CET 2016
Author: pragnya
Date: 2016-03-18 14:31:22 +0100 (Fri, 18 Mar 2016)
New Revision: 4016
Modified:
pkg/FactorAnalytics/NAMESPACE
pkg/FactorAnalytics/R/fmVaRDecomp.R
pkg/FactorAnalytics/man/fmVaRDecomp.Rd
Log:
Adding FFM method to fmVaRDecomp
Modified: pkg/FactorAnalytics/NAMESPACE
===================================================================
--- pkg/FactorAnalytics/NAMESPACE 2016-03-17 14:33:46 UTC (rev 4015)
+++ pkg/FactorAnalytics/NAMESPACE 2016-03-18 13:31:22 UTC (rev 4016)
@@ -14,6 +14,7 @@
S3method(fmSdDecomp,ffm)
S3method(fmSdDecomp,sfm)
S3method(fmSdDecomp,tsfm)
+S3method(fmVaRDecomp,ffm)
S3method(fmVaRDecomp,sfm)
S3method(fmVaRDecomp,tsfm)
S3method(plot,pafm)
Modified: pkg/FactorAnalytics/R/fmVaRDecomp.R
===================================================================
--- pkg/FactorAnalytics/R/fmVaRDecomp.R 2016-03-17 14:33:46 UTC (rev 4015)
+++ pkg/FactorAnalytics/R/fmVaRDecomp.R 2016-03-18 13:31:22 UTC (rev 4016)
@@ -303,3 +303,107 @@
return(fm.VaR.decomp)
}
+#' @rdname fmVaRDecomp
+#' @method fmVaRDecomp ffm
+#' @export
+
+fmVaRDecomp.ffm <- function(object, p=0.95, type=c("np","normal"), ...) {
+
+ # set default for type
+ type = type[1]
+
+ if (!(type %in% c("np","normal"))) {
+ stop("Invalid args: type must be 'np' or 'normal' ")
+ }
+
+ # get beta.star
+ beta <- object$beta
+ beta[is.na(beta)] <- 0
+ beta.star <- as.matrix(cbind(beta, sqrt(object$resid.var)))
+ colnames(beta.star)[dim(beta.star)[2]] <- "residual"
+
+ # factor returns and residuals data
+ factors.xts <- object$factor.returns
+ resid.xts <- as.xts(t(t(residuals(object))/sqrt(object$resid.var)))
+ time(resid.xts) <- as.Date(time(resid.xts))
+
+ if (type=="normal") {
+ # get cov(F): K x K
+ factor.cov = object$factor.cov
+
+ # get cov(F.star): (K+1) x (K+1)
+ K <- ncol(object$beta)
+ factor.star.cov <- diag(K+1)
+ factor.star.cov[1:K, 1:K] <- factor.cov
+ colnames(factor.star.cov) <- c(colnames(factor.cov),"residuals")
+ rownames(factor.star.cov) <- c(colnames(factor.cov),"residuals")
+
+ # factor expected returns
+ MU <- c(colMeans(factors.xts, na.rm=TRUE), 0)
+
+ # SIGMA*Beta to compute normal mVaR
+ SIGB <- beta.star %*% factor.star.cov
+ }
+
+ # initialize lists and matrices
+ N <- length(object$asset.names)
+ K <- length(object$factor.names)
+ VaR.fm <- rep(NA, N)
+ idx.exceed <- list()
+ n.exceed <- rep(NA, N)
+ names(VaR.fm) = names(n.exceed) = object$asset.names
+ mVaR <- matrix(NA, N, K+1)
+ cVaR <- matrix(NA, N, K+1)
+ pcVaR <- matrix(NA, N, K+1)
+ rownames(mVaR)=rownames(cVaR)=rownames(pcVaR)=object$asset.names
+ colnames(mVaR)=colnames(cVaR)=colnames(pcVaR)=c(object$factor.names,
+ "residuals")
+ for (i in object$asset.names) {
+ # return data for asset i
+ R.xts <- object$data[,i]
+ # get VaR for asset i
+ if (type=="np") {
+ VaR.fm[i] <- quantile(R.xts, probs=1-p, na.rm=TRUE, ...)
+ }
+ else if (type=="normal") {
+ VaR.fm[i] <- mean(R.xts, na.rm=TRUE) + sd(R.xts, na.rm=TRUE)*qnorm(1-p)
+ }
+ # index of VaR exceedances
+ idx.exceed[[i]] <- which(R.xts <= VaR.fm[i])
+ # number of VaR exceedances
+ n.exceed[i] <- length(idx.exceed[[i]])
+
+ # get F.star data object
+ factor.star <- merge(factors.xts, resid.xts[,i])
+ colnames(factor.star)[dim(factor.star)[2]] <- "residual"
+
+ if (type=="np") {
+ # epsilon is apprx. using Silverman's rule of thumb (bandwidth selection)
+ # the constant 2.575 corresponds to a triangular kernel
+ eps <- 2.575*sd(R.xts, na.rm =TRUE) * (nrow(R.xts)^(-1/5))
+ # compute marginal VaR as expected value of factor returns, such that the
+ # asset return was incident in the triangular kernel region peaked at the
+ # VaR value and bandwidth = epsilon.
+ k.weight <- as.vector(1 - abs(R.xts - VaR.fm[i]) / eps)
+ k.weight[k.weight<0] <- 0
+ mVaR[i,] <- colMeans(factor.star*k.weight, na.rm =TRUE)
+ }
+ else if (type=="normal") {
+ mVaR[i,] <- t(MU) + SIGB[i,] * qnorm(1-p)/sd(R.xts, na.rm=TRUE)
+ }
+
+ # correction factor to ensure that sum(cVaR) = asset VaR
+ cf <- as.numeric( VaR.fm[i] / sum(mVaR[i,]*beta.star[i,], na.rm=TRUE) )
+
+ # compute marginal, component and percentage contributions to VaR
+ # each of these have dimensions: N x (K+1)
+ mVaR[i,] <- cf * mVaR[i,]
+ cVaR[i,] <- mVaR[i,] * beta.star[i,]
+ pcVaR[i,] <- 100* cVaR[i,] / VaR.fm[i]
+ }
+
+ fm.VaR.decomp <- list(VaR.fm=VaR.fm, n.exceed=n.exceed, idx.exceed=idx.exceed,
+ mVaR=mVaR, cVaR=cVaR, pcVaR=pcVaR)
+
+ return(fm.VaR.decomp)
+}
Modified: pkg/FactorAnalytics/man/fmVaRDecomp.Rd
===================================================================
--- pkg/FactorAnalytics/man/fmVaRDecomp.Rd 2016-03-17 14:33:46 UTC (rev 4015)
+++ pkg/FactorAnalytics/man/fmVaRDecomp.Rd 2016-03-18 13:31:22 UTC (rev 4016)
@@ -2,6 +2,7 @@
% Please edit documentation in R/fmVaRDecomp.R
\name{fmVaRDecomp}
\alias{fmVaRDecomp}
+\alias{fmVaRDecomp.ffm}
\alias{fmVaRDecomp.sfm}
\alias{fmVaRDecomp.tsfm}
\title{Decompose VaR into individual factor contributions}
@@ -13,6 +14,8 @@
\method{fmVaRDecomp}{sfm}(object, p = 0.95, type = c("np", "normal"),
use = "pairwise.complete.obs", ...)
+
+\method{fmVaRDecomp}{ffm}(object, p = 0.95, type = c("np", "normal"), ...)
}
\arguments{
\item{object}{fit object of class \code{tsfm}, \code{sfm} or \code{ffm}.}
More information about the Returnanalytics-commits
mailing list