[Returnanalytics-commits] r2084 - pkg/PortfolioAnalytics/sandbox/attribution/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Jun 27 18:19:30 CEST 2012
Author: ababii
Date: 2012-06-27 18:19:30 +0200 (Wed, 27 Jun 2012)
New Revision: 2084
Added:
pkg/PortfolioAnalytics/sandbox/attribution/R/AttributionFixedIncome.R
Log:
- Fixed income arithmetic and geometric attribution (incomplete)
Added: pkg/PortfolioAnalytics/sandbox/attribution/R/AttributionFixedIncome.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/attribution/R/AttributionFixedIncome.R (rev 0)
+++ pkg/PortfolioAnalytics/sandbox/attribution/R/AttributionFixedIncome.R 2012-06-27 16:19:30 UTC (rev 2084)
@@ -0,0 +1,140 @@
+#' performs fixed income attribution
+#'
+#' Performs fixed income attribution. The investment decision process for bond
+#' managers is very different from that of equity managers, therefore for most
+#' fixed income investment strategies the standard Brinson model is not
+#' suitable. Bonds are simply a series of defined future cash flows which are
+#' relatively easy to price. Fixed income performance is therefore driven by
+#' changes in the shape of the yield curve. Systematic risk in the form of
+#' duration is a key part of the investment process. Fixed income attribution
+#' is, in fact, a specialist form of risk-adjusted attribution.
+#' The arithmetic attribution is handled using weighted duration approach
+#' (Van Breukelen, 2000). The allocation, selection and currency allocation
+#' effects for category i are:
+#' \deqn{A_{i} = (D_{pi}\times w_{i}-D_{\beta}\times D_{bi}\times w_{pi})\times (-\Delta y_{bi} + \Delta y_{b})}
+#' \deqn{S_{i} = D_{i}\times w_{i}\times (-\Delta y_{ri} + \Delta y_{bi})}
+#' \deqn{C_{i} = (w_{pi} - w_{bi})\times (c_{i} + R_{fi} - c')}
+#' where
+#' \deqn{w_{pi}} - portfolio weights
+#' \deqn{w_{bi}} - benchmark weights
+#' \deqn{D_{i}} - modified duration in bond category i
+#' \deqn{D_{\beta}=\frac{D_{r}}{D_{b}}} - duration beta
+#' \deqn{D_{r}} - portfolio duration
+#' \deqn{D_{b}} - benchmark duration
+#' \deqn{D_{bi}} - benchmark duration for category i
+#' \deqn{D_{pi}} - portfolio duration for category i
+#' \deqn{\Delta y_{ri}} - change in portfolio yield for category i
+#' \deqn{\Delta y_{bi}} - change in benchmark yield for category i
+#' \deqn{\Delta y_{b}} - change in benchmark yield
+#' \deqn{R_{ci} - currency returns for category i
+#' \deqn{R_{fi}} - risk-free rate in currency of asset i
+#' \deqn{c'= \underset{i}{\sum}w_{bi}\times(R_{ci}+R_{fi})}
+#' The geometric attribution is adapted using Van Breukelen (2000) approach for
+#' the arithmetic attribution. The individual allocation and selection effects
+#' are computed as follows:
+#' \deqn{A_{i}=D_{i}w_{pi}-D_{\beta}D_{bi}w_{bi}}
+#' \deqn{S_{i}=\frac{D_{pi}}{D_{bi}}\times (R_{bi} - R_{fi}) + R_{fi}}
+#' @aliases fixed income attribution
+#' @param Rp T x n xts, data frame or matrix of portfolio returns
+#' @param wp vector, xts, data frame or matrix of portfolio weights
+#' @param Rb T x n xts, data frame or matrix of benchmark returns
+#' @param wb vector, xts, data frame or matrix of benchmark weights
+#' @param Rf T x n xts, data frame or matrix with risk free rates
+#' @param Dp T x n xts, data frame or matrix with portfolio modified duration
+#' @param Db T x n xts, data frame or matrix with benchmark modified duration
+#' @param wbf vector, xts, data frame or matrix with benchmark weights of
+#' currency forward contracts
+#' @param S (T+1) x n xts, data frame or matrix with spot rates. The first date
+#' should coincide with the first date of portfolio returns
+#' @param geometric - TRUE/FALSE for geometric/arithmetic attribution
+#' @returnlist with returns a list with total excess returns decomposed into
+#' allocation, selection and currency effects
+#' @author Andrii Babii
+#' @seealso \code{\link{Attribution.levels}}, \code{\link{Attribution.geometric}}
+#' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and
+#' Attribution}. Wiley. 2004. Chapter 7
+#'
+#' Van Breukelen, G. \emph{Fixed income attribution}.
+#' Journal of Performance MeasurementSummer, 6168. 2000
+#' @keywords attribution
+#' @examples
+#'
+#' data(attrib)
+#'
+#' @export
+AttributionFixedIncome <-
+function (Rp, wp, Rb, wp, Rf, Dp, Db, S, wbf, geometric = FALSE)
+{ # @author Andrii Babii
+
+ # DESCRIPTION:
+ # Function to perform fixed income attribution
+
+ # Inputs:
+ # Rp xts, data frame or matrix of portfolio returns
+ # wp vector, xts, data frame or matrix of portfolio weights
+ # Rb xts, data frame or matrix of benchmark returns
+ # wb vector, xts, data frame or matrix of benchmark weights
+ # Rf xts, data frame or matrix of risk-free rate
+ # Dp T x n xts, data frame or matrix with portfolio modified duration
+ # Db T x n xts, data frame or matrix with benchmark modified duration
+ # S xts, data frame or matrix with spot rates
+ # wbf vector, xts, data frame or matrix with benchmark weights of
+ # currency forward contracts
+
+ # Outputs:
+ # This function returns the
+
+ # FUNCTION:
+ Rf = checkData(Rf)
+ Rp = checkData(Rp)
+ Rb = checkData(Rb)
+ Dp = checkData(Dp)
+ Db = checkData(Db)
+ S = checkData(S)
+ wp = Weight.transform(wp, Rp)
+ wb = Weight.transform(wb, Rb)
+ wbf = Weight.transform(wbf, Rb)
+
+ rp = reclass(rowSums(Rp * wp), Rp)
+ rb = reclass(rowSums(Rb * wb), wb)
+ rf = reclass(rowSums(Rf * wp), Rf)
+ dp = reclass(rowSums(Dp * wp), Dp) # Portfolio duration
+ db = reclass(rowSums(Db * wp), Db) # Benchmark duration
+ Dbeta = dp / db
+ DeltaYb = -(Rb - Rf) / Db # Implied benchmark yield changes
+ DeltaYp = -(Rp - Rf) / Dp # Implied portfolio yield changes
+ deltayb = rep(-(rp - rb), ncol(Dp)) / Dp # Implied total benchmark yield changes
+ Rc = lag(S, -1)[1:nrow(Rp), ] / S[1:nrow(Rp), ] - 1 # Currency returns
+ rc = reclass(rowSums((wb + wbf) * (Rc + Rf)), Rc)
+ if (!geometric){
+ allocation = (Dp * wp - rep(Dbeta, ncol(Dp)) * Db * wb) * (-DeltaYb + deltayb)
+ selection = Dp * wp * (-DeltaYp + DeltaYb)
+ currency = (wp - wb) * (Rc + Rf - rep(rc, ncol(Rc)))
+ excess.returns = rp - rb
+ } else{
+ bd = # Overal duration notional fund
+ allocation = Dp * wp - rep(Dbeta, ncol(Dp)) * Db * wb * (-DeltaYb + deltayb) / bd
+ selection =
+ excess.returns =
+ }
+
+ # Get total attribution effects
+ n = ncol(allocation) # number of segments
+ allocation = cbind(allocation, rowSums(allocation))
+ names(allocation)[n + 1] = "Total"
+ selection = cbind(selection, rowSums(selection))
+ names(selection)[n + 1] = "Total"
+
+ result = list()
+ result[[1]] = excess.returns
+ result[[2]] = allocation
+ result[[3]] = selection
+ names(result) = c("Excess returns", "Market allocation", "Issue selection")
+
+ if (!geometric){
+ currency = cbind(currency, rowSums(currency))
+ names(currency)[ncol(currency)] = "Total"
+ result[[4]] = currency
+ names(result) = c("Excess returns", "Market allocation", "Issue selection", "Currency allocation")
+ }
+}
\ No newline at end of file
More information about the Returnanalytics-commits
mailing list