├── data └── attrib.rda ├── inst └── doc │ ├── PortfolioAttribution.pdf │ ├── References.bib │ └── PortfolioAttribution.tex ├── NAMESPACE ├── man ├── HierarchyQuintiles.Rd ├── Weight.transform.Rd ├── Weight.level.Rd ├── Return.level.Rd ├── attrib.Rd ├── Conv.option.Rd ├── Frongello.Rd ├── Grap.Rd ├── DaviesLaker.Rd ├── Menchero.Rd ├── Carino.Rd ├── Attribution.levels.Rd ├── Attribution.geometric.Rd ├── AttributionFixedIncome.Rd └── Attribution.Rd ├── DESCRIPTION ├── R ├── HierarchyQuintiles.R ├── Weight.level.R ├── Weight.transform.R ├── Conv.option.R ├── Return.level.R ├── Frongello.R ├── Grap.R ├── Menchero.R ├── Carino.R ├── DaviesLaker.R ├── Attribution.geometric.R ├── AttributionFixedIncome.R ├── attribution.levels.R └── attribution.R └── test_suite.R /data/attrib.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Finance/PortfolioAttribution/HEAD/data/attrib.rda -------------------------------------------------------------------------------- /inst/doc/PortfolioAttribution.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Finance/PortfolioAttribution/HEAD/inst/doc/PortfolioAttribution.pdf -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | export(Attribution) 2 | export(AttributionFixedIncome) 3 | export(Attribution.geometric) 4 | export(Attribution.levels) 5 | export(Carino) 6 | export(Conv.option) 7 | export(DaviesLaker) 8 | export(Frongello) 9 | export(Grap) 10 | export(HierarchyQuintiles) 11 | export(Menchero) 12 | export(Return.level) 13 | export(Weight.level) 14 | export(Weight.transform) 15 | -------------------------------------------------------------------------------- /man/HierarchyQuintiles.Rd: -------------------------------------------------------------------------------- 1 | \name{HierarchyQuintiles} 2 | \alias{HierarchyQuintiles} 3 | \title{replaces numeric values in the hierarchy by quintiles} 4 | \usage{ 5 | HierarchyQuintiles(h, level) 6 | } 7 | \arguments{ 8 | \item{h}{data.frame with portfolio hierarchy} 9 | 10 | \item{level}{level from the hierarchy for which there are 11 | numeric values} 12 | } 13 | \description{ 14 | Replaces numeric values in the hierarchy by text with 15 | corresponding quintiles 16 | } 17 | \examples{ 18 | data(attrib) 19 | HierarchyQuintiles(h = attrib.hierarchy, "MarketCap") 20 | } 21 | \author{ 22 | Andrii Babii 23 | } 24 | \seealso{ 25 | \code{buildHierarchy} 26 | } 27 | \keyword{attribution,} 28 | \keyword{hierarchy} 29 | 30 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: PortfolioAttribution 2 | Type: Package 3 | Title: Performance attribution tools used for identifying sources of portfolio return and risk. 4 | Version: 0.3 5 | Date: $Date$ 6 | Author: Andrii Babii 7 | Maintainer: Andrii Babii 8 | Description: This package provides functions for the ex-post portfolio attribution methods described in Christopherson, Carino and Ferson (2009), Bacon (2008), and several other sources. The package was initially created as a part of the Google Summer of Code (GSoC) 2012 project. 9 | Depends: 10 | R (>= 2.15.0), 11 | zoo, 12 | xts (>= 0.8), 13 | PerformanceAnalytics(>= 1.0.4.3) 14 | Suggests: 15 | plyr, 16 | FinancialInstrument 17 | License: GPL 18 | URL: http://r-forge.r-project.org/projects/returnanalytics/ 19 | Contributors: David Carino, Doug Martin, Brian Peterson, Peter Carl 20 | Copyright: (c) 2004-2013 21 | -------------------------------------------------------------------------------- /man/Weight.transform.Rd: -------------------------------------------------------------------------------- 1 | \name{Weight.transform} 2 | \alias{Weight.transform} 3 | \title{transforms weights for the attribution functions} 4 | \usage{ 5 | Weight.transform(wp, Rp) 6 | } 7 | \arguments{ 8 | \item{Rp}{xts, data frame or matrix of portfolio returns} 9 | 10 | \item{wp}{vector, xts, data frame or matrix of portfolio 11 | weights} 12 | } 13 | \description{ 14 | Makes transformation of weights to the xts object 15 | conformable with returns and to be taken by the 16 | attribution functions 17 | } 18 | \examples{ 19 | data(attrib) 20 | Weight.transform(wp = attrib.weights[1, ], Rp = attrib.returns[, 1:10]) 21 | } 22 | \author{ 23 | Andrii Babii 24 | } 25 | \references{ 26 | Christopherson, Jon A., Carino, David R., Ferson, Wayne 27 | E. \emph{Portfolio Performance Measurement and 28 | Benchmarking}. McGraw-Hill. 2009. Chapter 17 29 | } 30 | \seealso{ 31 | \code{buildHierarchy} \cr \code{\link{Attribution}} \cr 32 | \code{\link{Weight.level}} 33 | } 34 | \keyword{attribution} 35 | 36 | -------------------------------------------------------------------------------- /man/Weight.level.Rd: -------------------------------------------------------------------------------- 1 | \name{Weight.level} 2 | \alias{Weight.level} 3 | \title{aggregates portfolio weights up to the chosen level from the hierarchy} 4 | \usage{ 5 | Weight.level(wp, Rp, h, level = "Sector") 6 | } 7 | \arguments{ 8 | \item{Rp}{xts, data frame or matrix of portfolio returns} 9 | 10 | \item{wp}{vector, xts, data frame or matrix of portfolio 11 | weights} 12 | 13 | \item{h}{data.frame with portfolio hierarchy} 14 | 15 | \item{level}{level from the hierarchy to which returns 16 | and weights will be aggregated} 17 | } 18 | \description{ 19 | Aggregates weights up to the chosen level from the 20 | hierarchy. Hierarchy can be used from the 21 | \code{buildHierarchy} function or defined manually in the 22 | same way as the \code{buildHierarchy}'s output. If for 23 | the selected level the values in the hierarchy are 24 | numeric, the aggregation of returns or weights is 25 | performed by quintiles. 26 | } 27 | \examples{ 28 | data(attrib) 29 | Weight.level(wp = attrib.weights[1, ], Rp = attrib.returns[, 1:10], attrib.hierarchy, level = "Sector") 30 | } 31 | \author{ 32 | Andrii Babii 33 | } 34 | \references{ 35 | Christopherson, Jon A., Carino, David R., Ferson, Wayne 36 | E. \emph{Portfolio Performance Measurement and 37 | Benchmarking}. McGraw-Hill. 2009. Chapter 17 38 | } 39 | \seealso{ 40 | \code{buildHierarchy} \cr \code{\link{Attribution}} \cr 41 | \code{\link{Return.level}} 42 | } 43 | \keyword{attribution} 44 | 45 | -------------------------------------------------------------------------------- /man/Return.level.Rd: -------------------------------------------------------------------------------- 1 | \name{Return.level} 2 | \alias{Return.level} 3 | \title{aggregates portfolio returns up to the chosen level from the hierarchy} 4 | \usage{ 5 | Return.level(Rp, wp, h, level = "Sector") 6 | } 7 | \arguments{ 8 | \item{Rp}{xts, data frame or matrix of portfolio returns} 9 | 10 | \item{wp}{vector, xts, data frame or matrix of portfolio 11 | weights} 12 | 13 | \item{h}{data.frame with portfolio hierarchy} 14 | 15 | \item{level}{level from the hierarchy to which returns 16 | and weights will be aggregated} 17 | } 18 | \description{ 19 | Aggregates returns and weights up to the chosen level 20 | from the hierarchy. Hierarchy can be used from the 21 | \code{buildHierarchy} function or defined manually in the 22 | same way as the \code{buildHierarchy}'s output. If for 23 | the selected level the values in the hierarchy are 24 | numeric, the aggregation of returns or weights is 25 | performed by quintiles. \code{Weight.transform} makes 26 | transformation of weights to the xts object conformable 27 | with returns. 28 | } 29 | \examples{ 30 | data(attrib) 31 | Return.level(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], h = attrib.hierarchy, level = "MarketCap") 32 | } 33 | \author{ 34 | Andrii Babii 35 | } 36 | \references{ 37 | Christopherson, Jon A., Carino, David R., Ferson, Wayne 38 | E. \emph{Portfolio Performance Measurement and 39 | Benchmarking}. McGraw-Hill. 2009. Chapter 17 40 | } 41 | \seealso{ 42 | \code{buildHierarchy} \cr \code{\link{Attribution}} \cr 43 | \code{\link{Weight.level}} 44 | } 45 | \keyword{attribution} 46 | 47 | -------------------------------------------------------------------------------- /R/HierarchyQuintiles.R: -------------------------------------------------------------------------------- 1 | #' replaces numeric values in the hierarchy by quintiles 2 | #' 3 | #' Replaces numeric values in the hierarchy by text with corresponding 4 | #' quintiles 5 | #' 6 | #' @aliases HierarchyQuintiles 7 | #' @param h data.frame with portfolio hierarchy 8 | #' @param level level from the hierarchy for which there are numeric values 9 | #' @author Andrii Babii 10 | #' @seealso \code{buildHierarchy} 11 | #' @keywords attribution, hierarchy 12 | #' @examples 13 | #' 14 | #' data(attrib) 15 | #' HierarchyQuintiles(h = attrib.hierarchy, "MarketCap") 16 | #' 17 | #' @export 18 | HierarchyQuintiles <- 19 | function(h, level) 20 | { # @author Andrii Babii 21 | h = na.omit(h) 22 | hnew = h[[level]] 23 | quintiles = quantile(h[[level]], c(0, 0.2, 0.4, 0.6, 0.8, 1), na.rm = TRUE) 24 | for (i in 1:length(h[[level]])){ 25 | if (h[[level]][i] >= quintiles[1] & h[[level]][i] < quintiles[2] 26 | & !is.na(h[[level]][i])){ 27 | hnew[i] = "Quintile 1" 28 | } 29 | if (h[[level]][i] >= quintiles[2] & h[[level]][i] < quintiles[3] 30 | & !is.na(h[[level]][i])){ 31 | hnew[i] = "Quintile 2" 32 | } 33 | if (h[[level]][i] >= quintiles[3] & h[[level]][i] < quintiles[4] 34 | & !is.na(h[[level]][i])){ 35 | hnew[i] = "Quintile 3" 36 | } 37 | if (h[[level]][i] >= quintiles[4] & h[[level]][i] < quintiles[5] 38 | & !is.na(h[[level]][i])){ 39 | hnew[i] = "Quintile 4" 40 | } 41 | if (h[[level]][i] >= quintiles[5] & h[[level]][i] <= quintiles[6] 42 | & !is.na(h[[level]][i])){ 43 | hnew[i] = "Quintile 5" 44 | } 45 | } 46 | h[[level]] = hnew 47 | return(h) 48 | } 49 | -------------------------------------------------------------------------------- /man/attrib.Rd: -------------------------------------------------------------------------------- 1 | \name{attrib} 2 | \docType{data} 3 | \alias{attrib} 4 | \alias{attrib.hierarchy} 5 | \alias{attrib.returns} 6 | \alias{attrib.weights} 7 | \alias{attrib.allocation} 8 | \alias{attrib.currency} 9 | \title{Hypothetical Portfolio Data with Returns, Weights, Hierarchy, Currency 10 | Contracts and Allocation effects} 11 | \description{ 12 | A dataset for examples in the attribution functions. 13 | } 14 | \usage{attrib} 15 | \details{ 16 | Contains 3 xts objects, a data frame and a matrix. 17 | \itemize{\item 'attrib.returns' - xts object with portfolio returns (9 stocks 18 | and one bond), benchmark returns (S\&P 500 total returns and 3-month treasury 19 | bills), total portfolio returns and total benchmark returns, risk-free rates, 20 | portfolio and benchmark returns in the local currency, benchmark returns hedged 21 | into the corresponding currency; portfolio and benchmark duration for the 22 | portfolio with bonds. Quarterly returns for all series end in the fourth 23 | quarter of 2008 and begin in the second quarter of 2007 24 | \item 'attrib.weights' - matrix with portfolio weights, benchmark weights, 25 | portfolio weights of currency forward contract in the corresponding currencies 26 | and benchmark weights of currenccy forward contract in the corresponding 27 | currencies \item 'attrib.hierarchy' - data frame with portfolio hierarchy 28 | \item 'attrib.currency' - xts object with forward and spot rates for currency 29 | contracts. Contains data for one more period than returns in order to compute 30 | corresponding currency returns and currency surprises 31 | \item 'attrib.allocation' - xts with allocation effects for the above mentioned 32 | portfolio and benchmark of the same length as portfolio returns} 33 | } 34 | \examples{ 35 | data(attrib) 36 | } 37 | \keyword{datasets} 38 | \keyword{ ts } -------------------------------------------------------------------------------- /man/Conv.option.Rd: -------------------------------------------------------------------------------- 1 | \name{Conv.option} 2 | \alias{Conv.option} 3 | \title{convert information about options, warrants or convertible bonds to the 4 | equivalent of returns} 5 | \usage{ 6 | Conv.option(option) 7 | } 8 | \arguments{ 9 | \item{option}{\emph{nx8} matrix containing option ID (as 10 | rownames), and columns corresponding to (in particular 11 | order): strike price, number of options, current option 12 | price, end option price, option's delta, returns on the 13 | underlying} 14 | } 15 | \value{ 16 | This function returns the equivalent of returns for 17 | options, warrants or convertible bonds 18 | } 19 | \description{ 20 | The performance of option contracts is measured in 21 | esactly the same way as any other asset but they also 22 | generate economic exposures. The key to attribution 23 | analysis with options is to inclue the appropriate 24 | economic exposure for which we can use the option's 25 | delta. The option itself will provide part of the 26 | valuation. The remaindeer of the option's economic value 27 | must be achieved again by using notional assets: 28 | \emph{option economic exposure = Delta x number of 29 | options x strike price = option valuation + notional 30 | exposure} 31 | } 32 | \examples{ 33 | option = matrix(c(1000, 1000, 1000, 300, 400, 10, 20, 30, 40, 50, 10, 11, 34 | 12, 13, 14, 12, 13, 14, 15, 16, 0.1, 0.2, 0.3, 0.4, 0.5, 0.1, 0.1, 0.2, 35 | 0.2, 0.3), 5, 6) 36 | colnames(option) = c("Strike", "Number", "Current option", "End option", 37 | "delta", "returns") 38 | rownames(option) = c("CVX", "XOM", "GE", "WMT", "FB") 39 | Conv.option(option) 40 | } 41 | \author{ 42 | Andrii Babii 43 | } 44 | \references{ 45 | Bacon, C. \emph{Practical Portfolio Performance 46 | Measurement and Attribution}. Wiley. 2004. p. 237-241 47 | } 48 | \seealso{ 49 | \code{\link{Attribution}} 50 | } 51 | \keyword{attribution} 52 | \keyword{attribution,} 53 | \keyword{derivatives} 54 | \keyword{option} 55 | 56 | -------------------------------------------------------------------------------- /man/Frongello.Rd: -------------------------------------------------------------------------------- 1 | \name{Frongello} 2 | \alias{Frongello} 3 | \title{calculates total attribution effects using Frongello smoothing} 4 | \usage{ 5 | Frongello(rp, rb, attributions, adjusted) 6 | } 7 | \arguments{ 8 | \item{rp}{xts of portfolio returns} 9 | 10 | \item{rb}{xts of benchmark returns} 11 | 12 | \item{attributions}{xts with attribution effects} 13 | 14 | \item{adjusted}{TRUE/FALSE, whether to show original or 15 | smoothed attribution effects for each period} 16 | } 17 | \value{ 18 | returns a data frame with original attribution effects 19 | and total attribution effects over multiple periods 20 | } 21 | \description{ 22 | Calculates total attribution effects over multiple 23 | periods using Frongello linking method. Used internally 24 | by the \code{\link{Attribution}} function. Arithmetic 25 | attribution effects do not naturally link over time. This 26 | function uses Frongello smoothing algorithm to adjust 27 | attribution effects so that they can be summed up over 28 | multiple periods Adjusted attribution effect at period t 29 | are: \deqn{A_{t}' = 30 | A_{t}\times\prod^{t-1}_{i=1}(1+r_{pi})+R_{bt} 31 | \times\sum^{t-1}_{i=1}A_{i}'} \eqn{A_{t}'}{At'} - 32 | adjusted attribution effects at period \eqn{t}, 33 | \eqn{A_{t}}{At} - unadjusted attribution effects at 34 | period \eqn{t}, \eqn{R_{pi}}{Rpi} - portfolio returns at 35 | period \eqn{i}, \eqn{R_{bi}}{Rbi} - benchmark returns at 36 | period, \eqn{R_{p}}{Rp} - total portfolio returns, 37 | \eqn{R_{b}}{Rb} - total benchmark returns, \eqn{n} - 38 | number of periods 39 | } 40 | \examples{ 41 | data(attrib) 42 | Frongello(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 43 | } 44 | \author{ 45 | Andrii Babii 46 | } 47 | \references{ 48 | Bacon, C. \emph{Practical Portfolio Performance 49 | Measurement and Attribution}. Wiley. 2004. p. 199-201 \cr 50 | Frongello, A. (2002) \emph{Linking single period 51 | attribution results}. Journal of Performance Measurement. 52 | Spring, p. 10-22. \cr 53 | } 54 | \seealso{ 55 | \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 56 | \code{\link{Grap}} \cr \code{\link{Carino}} \cr 57 | \code{\link{Attribution.geometric}} 58 | } 59 | \keyword{arithmetic} 60 | \keyword{attribution,} 61 | \keyword{Frongello} 62 | \keyword{linking} 63 | 64 | -------------------------------------------------------------------------------- /R/Weight.level.R: -------------------------------------------------------------------------------- 1 | #' aggregates portfolio weights up to the chosen level from the hierarchy 2 | #' 3 | #' Aggregates weights up to the chosen level from the hierarchy. 4 | #' Hierarchy can be used from the \code{buildHierarchy} function or 5 | #' defined manually in the same way as the \code{buildHierarchy}'s 6 | #' output. If for the selected level the values in the hierarchy are numeric, 7 | #' the aggregation of returns or weights is performed by quintiles. 8 | #' 9 | #' @aliases Weight.level 10 | #' @param Rp xts, data frame or matrix of portfolio returns 11 | #' @param wp vector, xts, data frame or matrix of portfolio weights 12 | #' @param h data.frame with portfolio hierarchy 13 | #' @param level level from the hierarchy to which returns and weights will be 14 | #' aggregated 15 | #' @author Andrii Babii 16 | #' @seealso \code{buildHierarchy} \cr \code{\link{Attribution}} \cr 17 | #' \code{\link{Return.level}} 18 | #' @references Christopherson, Jon A., Carino, David R., Ferson, Wayne E. 19 | #' \emph{Portfolio Performance Measurement and Benchmarking}. McGraw-Hill. 20 | #' 2009. Chapter 17 21 | #' @keywords attribution 22 | #' @examples 23 | #' 24 | #' data(attrib) 25 | #' Weight.level(wp = attrib.weights[1, ], Rp = attrib.returns[, 1:10], attrib.hierarchy, level = "Sector") 26 | #' 27 | #' @export 28 | Weight.level <- 29 | function(wp, Rp, h, level = "Sector") 30 | { # @author Andrii Babii 31 | 32 | # DESCRIPTION: 33 | # Function to aggregate weights up to the chosen level from the hierarchy 34 | 35 | # Inputs: 36 | # wp vector, xts, data frame or matrix of portfolio weights 37 | # h data.frame with portfolio hierarchy 38 | # level level from the hierarchy to which the aggregation will be done 39 | 40 | # Outputs: 41 | # This function returns portfolio weights at the chosen level 42 | 43 | # FUNCTION: 44 | # Transform data to the xts objects 45 | wp = Weight.transform(wp, Rp) 46 | 47 | # If level has numeric values we replace numeric values by quintiles 48 | if (is.numeric(h[[level]])){ 49 | h = HierarchyQuintiles(h, level) 50 | } 51 | h = split(h$primary_id, h[level]) 52 | weights = wp[, 1:length(h)] 53 | for(i in 1:length(h)){ 54 | weights[, i] = rowSums(wp[, h[[i]]]) 55 | } 56 | colnames(weights) = names(h) 57 | return(weights) 58 | } -------------------------------------------------------------------------------- /R/Weight.transform.R: -------------------------------------------------------------------------------- 1 | #' transforms weights for the attribution functions 2 | #' 3 | #' Makes transformation of weights to the xts object conformable with returns 4 | #' and to be taken by the attribution functions 5 | #' 6 | #' @aliases Weight.transform 7 | #' @param Rp xts, data frame or matrix of portfolio returns 8 | #' @param wp vector, xts, data frame or matrix of portfolio weights 9 | #' @author Andrii Babii 10 | #' @seealso \code{buildHierarchy} \cr \code{\link{Attribution}} \cr 11 | #' \code{\link{Weight.level}} 12 | #' @references Christopherson, Jon A., Carino, David R., Ferson, Wayne E. 13 | #' \emph{Portfolio Performance Measurement and Benchmarking}. McGraw-Hill. 14 | #' 2009. Chapter 17 15 | #' @keywords attribution 16 | #' @examples 17 | #' 18 | #' data(attrib) 19 | #' Weight.transform(wp = attrib.weights[1, ], Rp = attrib.returns[, 1:10]) 20 | #' 21 | #' @export 22 | Weight.transform <- 23 | function(wp, Rp) 24 | { # @author Andrii Babii 25 | 26 | # DESCRIPTION: 27 | # Function to transform weights to the xts object conformable with returns 28 | # used by aggregation and attribution functions 29 | 30 | # Inputs: 31 | # wp vector, xts, data frame or matrix of portfolio weights 32 | # Rp xts, data frame or matrix of portfolio returns 33 | 34 | # Outputs: 35 | # This function returns the xts object with weights conformable with 36 | # returns 37 | 38 | # FUNCTION: 39 | if (is.vector(wp)){ 40 | wp = as.xts(matrix(rep(wp, nrow(Rp)), nrow(Rp), ncol(Rp), byrow = TRUE), 41 | index(Rp)) 42 | colnames(wp) = colnames(Rp) 43 | } else{ 44 | if(as.Date(last(index(Rp))) < (as.Date(index(wp[1, ])) + 1)){ 45 | stop(paste('last date in series', as.Date(last(index(Rp))), 46 | 'occurs before beginning of first rebalancing period', 47 | as.Date(first(index(wp))) + 1)) 48 | } 49 | wp = checkData(wp, method = "xts") 50 | wp = merge(wp, xts(, index(Rp))) 51 | wp = na.locf(wp) 52 | if(as.Date(first(index(Rp))) > (as.Date(index(wp[1,]))+1)) { 53 | warning(paste('data series starts on', as.Date(first(index(Rp))), ', 54 | which is after the first rebalancing period', 55 | as.Date(first(index(wp)))+1)) 56 | wp = wp 57 | } else{ 58 | wp = wp[2:nrow(wp)] 59 | } 60 | } 61 | return(wp) 62 | } -------------------------------------------------------------------------------- /man/Grap.Rd: -------------------------------------------------------------------------------- 1 | \name{Grap} 2 | \alias{Grap} 3 | \title{calculates total attribution effects using GRAP smoothing} 4 | \usage{ 5 | Grap(rp, rb, attributions, adjusted) 6 | } 7 | \arguments{ 8 | \item{rp}{xts of portfolio returns} 9 | 10 | \item{rb}{xts of benchmark returns} 11 | 12 | \item{attributions}{xts with attribution effects} 13 | 14 | \item{adjusted}{TRUE/FALSE, whether to show original or 15 | smoothed attribution effects for each period} 16 | } 17 | \value{ 18 | returns a data frame with original attribution effects 19 | and total attribution effects over multiple periods 20 | } 21 | \description{ 22 | Calculates total attribution effects over multiple 23 | periods using GRAP linking method. Used internally by the 24 | \code{\link{Attribution}} function. Arithmetic 25 | attribution effects do not naturally link over time. This 26 | function uses GRAP smoothing algorithm to adjust 27 | attribution effects so that they can be summed up over 28 | multiple periods Attribution effect are multiplied by the 29 | adjustment factor \deqn{A_{t}' = A_{t} \times G_{t}}{At' 30 | = At * Gt} where 31 | \deqn{G_{t}=\prod^{t-1}_{i=1}(1+R_{pi})\times\prod^{n}_{t+1}(1+R_{bi})} 32 | \eqn{A_{t}'}{At'} - adjusted attribution effects at 33 | period \eqn{t}, \eqn{A_{t}}{At} - unadjusted attribution 34 | effects at period \eqn{t}, \eqn{R_{pi}}{Rpi} - portfolio 35 | returns at period \eqn{i}, \eqn{R_{bi}}{Rbi} - benchmark 36 | returns at period \eqn{i}, \eqn{R_{p}}{Rp} - total 37 | portfolio returns, \eqn{R_{b}}{Rb} - total benchmark 38 | returns, \eqn{n} - number of periods The total arithmetic 39 | excess returns can be explained in terms of the sum of 40 | adjusted attribution effects: \deqn{R_{p} - R_{b} = 41 | \sum^{n}_{t=1}\left(Allocation_{t}+Selection_{t}+ 42 | Interaction_{t}\right)} 43 | } 44 | \examples{ 45 | data(attrib) 46 | Grap(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 47 | } 48 | \author{ 49 | Andrii Babii 50 | } 51 | \references{ 52 | Bacon, C. \emph{Practical Portfolio Performance 53 | Measurement and Attribution}. Wiley. 2004. p. 196-199 \cr 54 | GRAP (Groupe de Recherche en Attribution de Performance) 55 | (1997) \emph{Synthese des modeles d'attribution de 56 | performance}. Paris, Mars.\cr 57 | } 58 | \seealso{ 59 | \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 60 | \code{\link{Carino}} \cr \code{\link{Frongello}} \cr 61 | \code{\link{Attribution.geometric}} 62 | } 63 | \keyword{arithmetic} 64 | \keyword{attribution,} 65 | \keyword{GRAP} 66 | \keyword{linking} 67 | 68 | -------------------------------------------------------------------------------- /man/DaviesLaker.Rd: -------------------------------------------------------------------------------- 1 | \name{DaviesLaker} 2 | \alias{DaviesLaker} 3 | \title{calculates total attribution effects using Davies and Laker smoothing} 4 | \usage{ 5 | DaviesLaker(Rp, wp, Rb, wb) 6 | } 7 | \arguments{ 8 | \item{Rp}{xts of portfolio returns} 9 | 10 | \item{wp}{xts of portfolio weights} 11 | 12 | \item{Rb}{xts of benchmark returns} 13 | 14 | \item{wb}{xts of benchmark weights} 15 | } 16 | \value{ 17 | This function returns the data.frame with original 18 | attribution effects and total attribution effects over 19 | multiple periods 20 | } 21 | \description{ 22 | Calculates total attribution effects over multiple 23 | periods using Davies and Laker linking method. Used 24 | internally by the \code{\link{Attribution}} function. 25 | Arithmetic attribution effects do not naturally link over 26 | time. This function uses Davies and Laker linking method 27 | to compute total attribution effects. Arithmetic excess 28 | returns are decomposed as follows: \deqn{R_{p} - R_{b} = 29 | Allocation + Selection + Interaction}{Rp - Rb = 30 | Allocation + Selection + Interaction} \deqn{Allocation = 31 | \prod^{T}_{t=1}(1+bs_{t})-\prod^{T}_{t=1}(1+R_{bt})} 32 | \deqn{Selection = 33 | \prod^{T}_{t=1}(1+rs_{t})-\prod^{T}_{t=1}(1+R_{bt})} 34 | \deqn{Interaction = 35 | \prod^{T}_{t=1}(1+R_{pt})-\prod^{T}_{t=1}(1+rs_{t})- 36 | \prod^{T}_{t=1}(1+bs_{t})+\prod^{T}_{t=1}(1+R_{bt})} 37 | \eqn{R_{pi}}{Rpi} - portfolio returns at period \eqn{i}, 38 | \eqn{R_{bi}}{Rbi} - benchmark returns at period \eqn{i}, 39 | \eqn{rs_{i}}{rsi} - selection notional fund returns at 40 | period \eqn{i}, \eqn{bs_{i}}{bsi} - allocation notional 41 | fund returns at period \eqn{i}, \eqn{T} - number of 42 | periods 43 | } 44 | \examples{ 45 | data(attrib) 46 | DaviesLaker(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], wb = attrib.weights[2, ]) 47 | } 48 | \author{ 49 | Andrii Babii 50 | } 51 | \references{ 52 | Bacon, C. \emph{Practical Portfolio Performance 53 | Measurement and Attribution}. Wiley. 2004. p. 201-204 \cr 54 | Davies, O. and Laker, D. (2001) \emph{Multiple-period 55 | performance attribution using the Brinson model}. Journal 56 | of Performance Measurement. Fall. p. 12-22 \cr 57 | } 58 | \seealso{ 59 | \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 60 | \code{\link{Grap}} \cr \code{\link{Carino}} \cr 61 | \code{\link{Attribution.geometric}} \cr 62 | \code{\link{Frongello}} 63 | } 64 | \keyword{and} 65 | \keyword{arithmetic} 66 | \keyword{attribution,} 67 | \keyword{Davies} 68 | \keyword{Laker} 69 | \keyword{linking} 70 | 71 | -------------------------------------------------------------------------------- /R/Conv.option.R: -------------------------------------------------------------------------------- 1 | #' convert information about options, warrants or convertible bonds to the 2 | #' equivalent of returns 3 | #' 4 | #' The performance of option contracts is measured in esactly the same way as 5 | #' any other asset but they also generate economic exposures. The key to 6 | #' attribution analysis with options is to inclue the appropriate economic 7 | #' exposure for which we can use the option's delta. The option itself will 8 | #' provide part of the valuation. The remaindeer of the option's economic value 9 | #' must be achieved again by using notional assets: \emph{option economic 10 | #' exposure = Delta x number of options x strike price = option valuation + 11 | #' notional exposure} 12 | #' @aliases Conv.option 13 | #' @param option \emph{nx8} matrix containing option ID (as rownames), and columns 14 | #' corresponding to (in particular order): strike price, number of options, 15 | #' current option price, end option price, option's delta, returns on the 16 | #' underlying 17 | #' @return This function returns the equivalent of returns for options, 18 | #' warrants or convertible bonds 19 | #' @author Andrii Babii 20 | #' @seealso \code{\link{Attribution}} 21 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and 22 | #' Attribution}. Wiley. 2004. p. 237-241 23 | #' @keywords derivatives attribution, option attribution 24 | #' @examples 25 | #' 26 | #' option = matrix(c(1000, 1000, 1000, 300, 400, 10, 20, 30, 40, 50, 10, 11, 27 | #' 12, 13, 14, 12, 13, 14, 15, 16, 0.1, 0.2, 0.3, 0.4, 0.5, 0.1, 0.1, 0.2, 28 | #' 0.2, 0.3), 5, 6) 29 | #' colnames(option) = c("Strike", "Number", "Current option", "End option", 30 | #' "delta", "returns") 31 | #' rownames(option) = c("CVX", "XOM", "GE", "WMT", "FB") 32 | #' Conv.option(option) 33 | #' 34 | #' @export 35 | Conv.option <- 36 | function (option) 37 | { # @author Andrii Babii 38 | 39 | # DESCRIPTION: 40 | # Function to compute option returns 41 | 42 | # Inputs: 43 | # option n x 6 matrix containing option IDs (as rownames), and columns 44 | # corresponding to (in the particular order): strike price, number of 45 | # options, current option price, end option price, option's delta, returns 46 | # on the underlying 47 | 48 | # Outputs: 49 | # This function returns the equivalent of returns for options, warrants or 50 | # convertible bonds 51 | 52 | # FUNCTION: 53 | 54 | ecvalue = option[, 1] * option[, 2] * option[, 5] 55 | notionalexp = ecvalue - option[, 2] * option[, 3] 56 | returns = (notionalexp * option[, 6] + option[, 2] * option[, 4]) / ecvalue 57 | return(returns) 58 | } -------------------------------------------------------------------------------- /R/Return.level.R: -------------------------------------------------------------------------------- 1 | #' aggregates portfolio returns up to the chosen level from the hierarchy 2 | #' 3 | #' Aggregates returns and weights up to the chosen level from the hierarchy. 4 | #' Hierarchy can be used from the \code{buildHierarchy} function or 5 | #' defined manually in the same way as the \code{buildHierarchy}'s 6 | #' output. If for the selected level the values in the hierarchy are numeric, 7 | #' the aggregation of returns or weights is performed by quintiles. 8 | #' \code{Weight.transform} makes transformation of weights to the xts object 9 | #' conformable with returns. 10 | #' 11 | #' @aliases Return.level 12 | #' @param Rp xts, data frame or matrix of portfolio returns 13 | #' @param wp vector, xts, data frame or matrix of portfolio weights 14 | #' @param h data.frame with portfolio hierarchy 15 | #' @param level level from the hierarchy to which returns and weights will be 16 | #' aggregated 17 | #' @author Andrii Babii 18 | #' @seealso \code{buildHierarchy} \cr \code{\link{Attribution}} \cr 19 | #' \code{\link{Weight.level}} 20 | #' @references Christopherson, Jon A., Carino, David R., Ferson, Wayne E. 21 | #' \emph{Portfolio Performance Measurement and Benchmarking}. McGraw-Hill. 22 | #' 2009. Chapter 17 23 | #' @keywords attribution 24 | #' @examples 25 | #' 26 | #' data(attrib) 27 | #' Return.level(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], h = attrib.hierarchy, level = "MarketCap") 28 | #' 29 | #' @export 30 | Return.level <- 31 | function(Rp, wp, h, level = "Sector") 32 | { # @author Andrii Babii 33 | 34 | # DESCRIPTION: 35 | # Function to aggregate returns up to the chosen level from the hierarchy 36 | 37 | # Inputs: 38 | # Rp xts, data frame or matrix of portfolio returns 39 | # wp vector, xts, data frame or matrix of portfolio weights 40 | # h data.frame with portfolio hierarchy 41 | # level level from the hierarchy to which the aggregation will be done 42 | 43 | # Outputs: 44 | # This function returns portfolio returns at the chosen level 45 | 46 | # FUNCTION: 47 | # Transform data to the xts objects 48 | Rp = checkData(Rp, method = "xts") 49 | wp = Weight.transform(wp, Rp) 50 | 51 | # If level has numeric values we replace numeric values by quintiles 52 | if (is.numeric(h[[level]])){ 53 | h = HierarchyQuintiles(h, level) 54 | } 55 | h = split(h$primary_id, h[level]) 56 | returns = as.xts(matrix(NA, ncol = length(h), nrow = nrow(Rp)), index(Rp)) 57 | for(i in 1:length(h)){ 58 | returns[, i] = rowSums(Rp[, h[[i]]] * coredata(wp[, h[[i]]])) 59 | } 60 | colnames(returns) = names(h) 61 | return(returns) 62 | } -------------------------------------------------------------------------------- /man/Menchero.Rd: -------------------------------------------------------------------------------- 1 | \name{Menchero} 2 | \alias{Menchero} 3 | \title{calculates total attribution effects using Menchero smoothing} 4 | \usage{ 5 | Menchero(rp, rb, attributions, adjusted) 6 | } 7 | \arguments{ 8 | \item{rp}{xts of portfolio returns} 9 | 10 | \item{rb}{xts of benchmark returns} 11 | 12 | \item{attributions}{xts with attribution effects} 13 | 14 | \item{adjusted}{TRUE/FALSE, whether to show original or 15 | smoothed attribution effects for each period} 16 | } 17 | \value{ 18 | returns a data frame with original attribution effects 19 | and total attribution effects over multiple periods 20 | } 21 | \description{ 22 | Calculates total attribution effects over multiple 23 | periods using Menchero linking method. Used internally by 24 | the \code{\link{Attribution}} function. Arithmetic 25 | attribution effects do not naturally link over time. This 26 | function uses Menchero smoothing algorithm to adjust 27 | attribution effects so that they can be summed up over 28 | multiple periods Attribution effect are multiplied by the 29 | adjustment factor \deqn{A_{t}' = A_{t} \times (M 30 | +a_{t})}{At' = At * (M + at)} where 31 | \deqn{M=\frac{\frac{1}{n}(R_{p}-R_{b})}{(1+R_{p})^{\frac{1}{n}}- 32 | (1+R_{b})^{\frac{1}{n}}}} \deqn{a_{t} = 33 | \left(\frac{R_{p}-R_{b}-M\times\sum^{n}_{t=1}(R_{pt}- 34 | R_{bt})}{\sum^{n}_{t=1}(R_{pt}-R_{bt})^{2}}\right)\times(R_{pt}-R_{bt})} 35 | In case if portfolio and benchmark returns are equal the 36 | limit of the above value is used: \deqn{M = (1 + 37 | r_{p})^\frac{n-1}{n}}{M = (1 + rp)^((n - 1) / n)} 38 | \eqn{A_{t}'}{At'} - adjusted attribution effects at 39 | period \eqn{t}, \eqn{A_{t}}{At} - unadjusted attribution 40 | effects at period \eqn{t}, \eqn{R_{pt}}{Rpt} - portfolio 41 | returns at period \eqn{t}, \eqn{R_{bt}}{Rbt} - benchmark 42 | returns at period \eqn{t}, \eqn{R_{p}}{Rp} - total 43 | portfolio returns, \eqn{R_{b}}{Rb} - total benchmark 44 | returns, \eqn{n} - number of periods 45 | } 46 | \details{ 47 | The total arithmetic excess returns can be explained in 48 | terms of the sum of adjusted attribution effects: 49 | \deqn{R_{p} - R_{b} = 50 | \sum^{n}_{t=1}\left(Allocation_{t}+Selection_{t}+ 51 | Interaction_{t}\right)} 52 | } 53 | \examples{ 54 | data(attrib) 55 | Menchero(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 56 | } 57 | \author{ 58 | Andrii Babii 59 | } 60 | \references{ 61 | Bacon, C. \emph{Practical Portfolio Performance 62 | Measurement and Attribution}. Wiley. 2004. p. 194-196 \cr 63 | Menchero, J. (2000) \emph{An optimized approach to 64 | linking attribution effects over time}. Journal of 65 | Performance Measurement. Fall. p. 36-42 \cr 66 | } 67 | \seealso{ 68 | \code{\link{Attribution}} \cr \code{\link{Carino}} \cr 69 | \code{\link{Grap}} \cr \code{\link{Frongello}} \cr 70 | \code{\link{Attribution.geometric}} 71 | } 72 | \keyword{arithmetic} 73 | \keyword{attribution,} 74 | \keyword{linking} 75 | \keyword{Menchero} 76 | 77 | -------------------------------------------------------------------------------- /man/Carino.Rd: -------------------------------------------------------------------------------- 1 | \name{Carino} 2 | \alias{Carino} 3 | \title{calculates total attribution effects using logarithmic smoothing} 4 | \usage{ 5 | Carino(rp, rb, attributions, adjusted) 6 | } 7 | \arguments{ 8 | \item{rp}{xts of portfolio returns} 9 | 10 | \item{rb}{xts of benchmark returns} 11 | 12 | \item{attributions}{xts with attribution effects} 13 | 14 | \item{adjusted}{TRUE/FALSE, whether to show original or 15 | smoothed attribution effects for each period} 16 | } 17 | \value{ 18 | returns a data frame with original attribution effects 19 | and total attribution effects over multiple periods 20 | } 21 | \description{ 22 | Calculates total attribution effects over multiple 23 | periods using logarithmic linking method. Used internally 24 | by the \code{\link{Attribution}} function. Arithmetic 25 | attribution effects do not naturally link over time. This 26 | function uses logarithmic smoothing to adjust attribution 27 | effects so that they can be summed up over multiple 28 | periods. Attribution effect are multiplied by the 29 | adjustment factor: \deqn{A_{t}' = A_{t} \times 30 | \frac{k_{t}}{k}}{At' = At * kt / k} where \deqn{k_{t} = 31 | \frac{log(1 + R_{pt}) - log(1 + R_{bt})}{R_{pt} - 32 | R_{bt}}} \deqn{k = \frac{log(1 + R_{p}) - log(1 + 33 | R_{b})}{R_{p} - R_{b}}} In case if portfolio and 34 | benchmark returns are equal: \deqn{k_{t} = \frac{1}{1 + 35 | R_{pt}}}{kt = 1 / (1 + Rpt)} where \eqn{A_{t}'}{At'} - 36 | adjusted attribution effects at period \eqn{t}, 37 | \eqn{A_{t}}{At} - unadjusted attribution effects at 38 | period \eqn{t}, \eqn{R_{pt}}{Rpt} - portfolio returns at 39 | period \eqn{t}, \eqn{R_{bt}}{Rbt} - benchmark returns at 40 | period \eqn{t}, \eqn{R_{p}}{Rp} - total portfolio 41 | returns, \eqn{R_{b}}{Rb} - total benchmark returns, 42 | \eqn{n} - number of periods The total arithmetic excess 43 | returns can be explained in terms of the sum of adjusted 44 | attribution effects: \deqn{R_{p} - R_{b} = 45 | \sum^{n}_{t=1}\left(Allocation_{t}+Selection_{t}+ 46 | Interaction_{t}\right)} 47 | } 48 | \examples{ 49 | data(attrib) 50 | Carino(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 51 | } 52 | \author{ 53 | Andrii Babii 54 | } 55 | \references{ 56 | Christopherson, Jon A., Carino, David R., Ferson, Wayne 57 | E. \emph{Portfolio Performance Measurement and 58 | Benchmarking}. McGraw-Hill. 2009. Chapter 19 \cr Bacon, 59 | C. \emph{Practical Portfolio Performance Measurement and 60 | Attribution}. Wiley. 2004. p. 191-193 \cr Carino, D. 61 | (1999) \emph{Combining attribution effects over time}. 62 | The Journal of Performance Measurement. Summer. p. 5-14 63 | \cr 64 | } 65 | \seealso{ 66 | \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 67 | \code{\link{Grap}} \cr \code{\link{Frongello}} \cr 68 | \code{\link{Attribution.geometric}} 69 | } 70 | \keyword{arithmetic} 71 | \keyword{attribution,} 72 | \keyword{Carino} 73 | \keyword{linking} 74 | \keyword{linking,} 75 | \keyword{logarithmic} 76 | 77 | -------------------------------------------------------------------------------- /man/Attribution.levels.Rd: -------------------------------------------------------------------------------- 1 | \name{Attribution.levels} 2 | \alias{Attribution.levels} 3 | \title{provides multi-level sector-based geometric attribution} 4 | \usage{ 5 | Attribution.levels(Rp, wp, Rb, wb, h, ...) 6 | } 7 | \arguments{ 8 | \item{Rp}{xts, data frame or matrix of portfolio returns} 9 | 10 | \item{wp}{vector, xts, data frame or matrix of portfolio 11 | weights} 12 | 13 | \item{Rb}{xts, data frame or matrix of benchmark returns} 14 | 15 | \item{wb}{vector, xts, data frame or matrix of benchmark 16 | weights} 17 | 18 | \item{h}{data.frame with the hierarchy obtained from the 19 | buildHierarchy function or defined manually in the same 20 | style as buildHierarchy's output} 21 | 22 | \item{\dots}{any other passthrough parameters} 23 | } 24 | \value{ 25 | returns the list with geometric excess returns including 26 | annualized geometric excess returns, total attribution 27 | effects (allocation, selection and total) including total 28 | multi-period attribution effects, attribution effects at 29 | each level and security selection 30 | } 31 | \description{ 32 | Provides multi-level sector-based geometric attribution. 33 | The Brinson model attributes excess returns at one level. 34 | This function works with more complex decision processes. 35 | For instance, the 3-level decision process may have the 36 | following levels: type of asset - country - sector. The 37 | levels should be specified in the vector with elements in 38 | the particular order: from the highest level to the 39 | lowest. Returns and weighs for portfolio and benchmark 40 | should be at the lowest level (e.g. individual 41 | instruments). Benchmark should have the same number of 42 | columns as portfolio. That is there should be a benchmark 43 | for each instrument in the portfolio (possibly 0). The 44 | contribution to the allocation in the \eqn{i^{th}} 45 | category for the \eqn{d^{th}} level is: 46 | \deqn{\left(^{d}w_{pi}-^{d}w_{bi}\right)\times 47 | \left(\frac{1+^{d}R_{bi}}{1+^{d-1}R_{bi}}-1\right) 48 | \times\frac{1+^{d-1}R_{bi}}{1+bs^{d-1}}} The total 49 | attribution for each asset allocation step in the 50 | decision process is: \deqn{\frac{1+^{d}bs}{1+^{d-1}bs}-1} 51 | The final step, stock selection, is measured by: 52 | \deqn{^{d}w_{pi}\times\left(\frac{1+R_{pi}}{1+^{d}R_{bi}}-1\right) 53 | \times\frac{1+^{d}R_{bi}}{1+^{d}bs}} 54 | } 55 | \examples{ 56 | data(attrib) 57 | Attribution.levels(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 58 | wb = attrib.weights[2, ], h = attrib.hierarchy, c("type", "MarketCap", "Sector")) 59 | Attribution.levels(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 60 | wb = attrib.weights[2, ], h = attrib.hierarchy, c("type", "Sector")) 61 | } 62 | \author{ 63 | Andrii Babii 64 | } 65 | \references{ 66 | Bacon, C. \emph{Practical Portfolio Performance 67 | Measurement and Attribution}. Wiley. 2004. p. 215-220 68 | } 69 | \seealso{ 70 | \code{\link{Attribution.geometric}} 71 | } 72 | \keyword{attribution} 73 | \keyword{attribution,} 74 | \keyword{geometric} 75 | \keyword{multi-level} 76 | 77 | -------------------------------------------------------------------------------- /R/Frongello.R: -------------------------------------------------------------------------------- 1 | #' calculates total attribution effects using Frongello smoothing 2 | #' 3 | #' Calculates total attribution effects over multiple periods using 4 | #' Frongello linking method. Used internally by the \code{\link{Attribution}} 5 | #' function. Arithmetic attribution effects do not naturally link over time. 6 | #' This function uses Frongello smoothing algorithm to adjust 7 | #' attribution effects so that they can be summed up over multiple periods 8 | #' Adjusted attribution effect at period t are: 9 | #' \deqn{A_{t}' = A_{t}\times\prod^{t-1}_{i=1}(1+r_{pi})+R_{bt} 10 | #' \times\sum^{t-1}_{i=1}A_{i}'} 11 | #' \eqn{A_{t}'}{At'} - adjusted attribution effects at period \eqn{t}, 12 | #' \eqn{A_{t}}{At} - unadjusted attribution effects at period \eqn{t}, 13 | #' \eqn{R_{pi}}{Rpi} - portfolio returns at period \eqn{i}, 14 | #' \eqn{R_{bi}}{Rbi} - benchmark returns at period, 15 | #' \eqn{R_{p}}{Rp} - total portfolio returns, 16 | #' \eqn{R_{b}}{Rb} - total benchmark returns, 17 | #' \eqn{n} - number of periods 18 | #' 19 | #' @aliases Frongello 20 | #' @param rp xts of portfolio returns 21 | #' @param rb xts of benchmark returns 22 | #' @param attributions xts with attribution effects 23 | #' @param adjusted TRUE/FALSE, whether to show original or smoothed attribution 24 | #' effects for each period 25 | #' @return returns a data frame with original attribution effects and total 26 | #' attribution effects over multiple periods 27 | #' @author Andrii Babii 28 | #' @seealso \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 29 | #' \code{\link{Grap}} \cr \code{\link{Carino}} \cr 30 | #' \code{\link{Attribution.geometric}} 31 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and 32 | #' Attribution}. Wiley. 2004. p. 199-201 \cr Frongello, A. (2002) \emph{Linking 33 | #' single period attribution results}. Journal of Performance Measurement. 34 | #' Spring, p. 10-22. \cr 35 | #' @keywords arithmetic attribution, Frongello linking 36 | #' @examples 37 | #' 38 | #' data(attrib) 39 | #' Frongello(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 40 | #' 41 | #' @export 42 | Frongello <- 43 | function(rp, rb, attributions, adjusted) 44 | { # @author Andrii Babii 45 | 46 | # DESCRIPTION: 47 | # Function to provide multi-period summary of attribution effects using 48 | # Frongello linking. Used internally by the Attribution function 49 | 50 | # Inputs: 51 | # rp xts of portfolio returns 52 | # rb xts of benchmark returns 53 | # attributions attribution effects (e.g. allocation, selection, interaction) 54 | 55 | # Outputs: 56 | # This function returns the data.frame with original attribution effects 57 | # and total attribution effects over multiple periods 58 | 59 | # FUNCTION: 60 | adj = attributions 61 | if (nrow(rp) > 1){ 62 | adj[2, ] = coredata(adj[2, ]) * drop((1 + rp[1, 1])) + drop(rb[2, 1]) * 63 | coredata(adj[1, ]) 64 | } 65 | if (nrow(rp) > 2){ 66 | for(i in 3:nrow(rp)){ 67 | adj[i, ] = coredata(adj[i, ]) * drop(prod(1 + rp[1:(i-1), 1])) + 68 | drop(rb[i, ]) * coredata(colSums(adj[1:(i-1), ])) 69 | } 70 | } 71 | total = colSums(adj) 72 | if (adjusted == FALSE){ 73 | attributions = rbind(as.data.frame(attributions), total) 74 | } else{ 75 | attributions = rbind(as.data.frame(adj), total) 76 | } 77 | rownames(attributions)[nrow(attributions)] = "Total" 78 | return(attributions) 79 | } 80 | -------------------------------------------------------------------------------- /R/Grap.R: -------------------------------------------------------------------------------- 1 | #' calculates total attribution effects using GRAP smoothing 2 | #' 3 | #' Calculates total attribution effects over multiple periods using 4 | #' GRAP linking method. Used internally by the \code{\link{Attribution}} 5 | #' function. Arithmetic attribution effects do not naturally link over time. 6 | #' This function uses GRAP smoothing algorithm to adjust attribution effects 7 | #' so that they can be summed up over multiple periods 8 | #' Attribution effect are multiplied by the adjustment factor 9 | #' \deqn{A_{t}' = A_{t} \times G_{t}}{At' = At * Gt} where 10 | #' \deqn{G_{t}=\prod^{t-1}_{i=1}(1+R_{pi})\times\prod^{n}_{t+1}(1+R_{bi})} 11 | #' \eqn{A_{t}'}{At'} - adjusted attribution effects at period \eqn{t}, 12 | #' \eqn{A_{t}}{At} - unadjusted attribution effects at period \eqn{t}, 13 | #' \eqn{R_{pi}}{Rpi} - portfolio returns at period \eqn{i}, 14 | #' \eqn{R_{bi}}{Rbi} - benchmark returns at period \eqn{i}, 15 | #' \eqn{R_{p}}{Rp} - total portfolio returns, 16 | #' \eqn{R_{b}}{Rb} - total benchmark returns, 17 | #' \eqn{n} - number of periods 18 | #' The total arithmetic excess returns can be explained in terms of the sum 19 | #' of adjusted attribution effects: 20 | #' \deqn{R_{p} - R_{b} = \sum^{n}_{t=1}\left(Allocation_{t}+Selection_{t}+ 21 | #' Interaction_{t}\right)} 22 | #' 23 | #' @aliases Grap 24 | #' @param rp xts of portfolio returns 25 | #' @param rb xts of benchmark returns 26 | #' @param attributions xts with attribution effects 27 | #' @param adjusted TRUE/FALSE, whether to show original or smoothed attribution 28 | #' effects for each period 29 | #' @return returns a data frame with original attribution effects and total 30 | #' attribution effects over multiple periods 31 | #' @author Andrii Babii 32 | #' @seealso \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 33 | #' \code{\link{Carino}} \cr \code{\link{Frongello}} \cr 34 | #' \code{\link{Attribution.geometric}} 35 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement 36 | #' and Attribution}. Wiley. 2004. p. 196-199 \cr GRAP (Groupe de Recherche en 37 | #' Attribution de Performance) (1997) \emph{Synthese des modeles d'attribution 38 | #' de performance}. Paris, Mars.\cr 39 | #' @keywords arithmetic attribution, GRAP linking 40 | #' @examples 41 | #' 42 | #' data(attrib) 43 | #' Grap(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 44 | #' 45 | #' @export 46 | Grap <- 47 | function(rp, rb, attributions, adjusted) 48 | { # @author Andrii Babii 49 | 50 | 51 | # DESCRIPTION: 52 | # Function to provide multi-period summary of attribution effects using 53 | # GRAP linking. Used internally by the Attribution function 54 | 55 | # Inputs: 56 | # rp xts of portfolio returns 57 | # rb xts of benchmark returns 58 | # attributions attribution effects (allocation, selection, interaction) 59 | 60 | # Outputs: 61 | # This function returns the data.frame with original attribution effects 62 | # and total attribution effects over multiple periods 63 | 64 | # FUNCTION: 65 | G = rp 66 | T = nrow(rp) 67 | G[1] = prod(1 + rb[2:T]) #GRAP factor for the first period 68 | if (T == 2){ 69 | G[2] = (1 + rp[1]) 70 | } 71 | if (T > 2){ 72 | G[T] = prod(1 + rp[1:(T - 1)]) #GRAP factor for the last period 73 | } 74 | if (T > 3){ 75 | for(i in 2:(T - 1)){ 76 | r = 1 + rp[1:(i-1)] 77 | b = 1 + rb[(i+1):T] 78 | G[i] = apply(r, 2, prod) * apply(b, 2, prod) 79 | } 80 | } 81 | g = matrix(rep(G, ncol(attributions)), nrow(attributions), 82 | ncol(attributions), byrow = FALSE) 83 | adj = attributions * g 84 | total = colSums(adj) 85 | if (adjusted == FALSE){ 86 | attributions = rbind(as.data.frame(attributions), total) 87 | } else{ 88 | attributions = rbind(as.data.frame(adj), total) 89 | } 90 | rownames(attributions)[nrow(attributions)] = "Total" 91 | return(attributions) 92 | } -------------------------------------------------------------------------------- /man/Attribution.geometric.Rd: -------------------------------------------------------------------------------- 1 | \name{Attribution.geometric} 2 | \alias{Attribution.geometric} 3 | \title{performs sector-based geometric attribution} 4 | \usage{ 5 | Attribution.geometric(Rp, wp, Rb, wb, Rpl = NA, Rbl = NA, 6 | Rbh = NA) 7 | } 8 | \arguments{ 9 | \item{Rp}{xts of portfolio returns} 10 | 11 | \item{wp}{xts of portfolio weights} 12 | 13 | \item{Rb}{xts of benchmark returns} 14 | 15 | \item{wb}{xts of benchmark weights} 16 | 17 | \item{Rpl}{xts, data frame or matrix of portfolio returns 18 | in local currency} 19 | 20 | \item{Rbl}{xts, data frame or matrix of benchmark returns 21 | in local currency} 22 | 23 | \item{Rbh}{xts, data frame or matrix of benchmark returns 24 | hedged into the base currency} 25 | } 26 | \value{ 27 | This function returns the list with attribution effects 28 | (allocation or selection effect) including total 29 | multi-period attribution effects 30 | } 31 | \description{ 32 | Performs sector-based geometric attribution of excess 33 | return. Calculates total geometric attribution effects 34 | over multiple periods. Used internally by the 35 | \code{\link{Attribution}} function. Geometric attribution 36 | effects in the contrast with arithmetic do naturally link 37 | over time multiplicatively: 38 | \deqn{\frac{(1+R_{p})}{1+R_{b}}-1=\prod^{n}_{t=1}(1+A_{t}^{G})\times 39 | \prod^{n}_{t=1}(1+S{}_{t}^{G})-1} Total allocation effect 40 | at time \eqn{t}: 41 | \deqn{A_{t}^{G}=\frac{1+b_{S}}{1+R_{bt}}-1} Total 42 | selection effect at time \eqn{t}: 43 | \deqn{S_{t}^{G}=\frac{1+R_{pt}}{1+b_{S}}-1} Semi-notional 44 | fund: \deqn{b_{S}=\sum^{n}_{i=1}w_{pi}\times R_{bi}} 45 | \eqn{w_{pt}}{wpt} - portfolio weights at time \eqn{t}, 46 | \eqn{w_{bt}}{wbt} - benchmark weights at time \eqn{t}, 47 | \eqn{r_{t}}{rt} - portfolio returns at time \eqn{t}, 48 | \eqn{b_{t}}{bt} - benchmark returns at time \eqn{t}, 49 | \eqn{r} - total portfolio returns \eqn{b} - total 50 | benchmark returns \eqn{n} - number of periods 51 | } 52 | \details{ 53 | The multi-currency geometric attribution is handled 54 | following the Appendix A (Bacon, 2004). 55 | 56 | The individual selection effects are computed using: 57 | \deqn{w_{pi}\times\left(\frac{1+R_{pLi}}{1+R_{bLi}}-1\right)\times 58 | \left(\frac{1+R_{bLi}}{1+b_{SL}}\right)} 59 | 60 | The individual allocation effects are computed using: 61 | \deqn{(w_{pi}-w_{bi})\times\left(\frac{1+R_{bHi}}{1+b_{L}}-1\right)} 62 | 63 | Where the total semi-notional returns hedged into the 64 | base currency were used: \deqn{b_{SH} = 65 | \sum_{i}w_{pi}\times R_{bi}((w_{pi} - w_{bi})R_{bHi} + 66 | w_{bi}R_{bLi})} Total semi-notional returns in the local 67 | currency: \deqn{b_{SL} = \sum_{i}w_{pi}R_{bLi}} 68 | \eqn{R_{pLi}}{RpLi} - portfolio returns in the local 69 | currency \eqn{R_{bLi}}{RbLi} - benchmark returns in the 70 | local currency \eqn{R_{bHi}}{RbHi} - benchmark returns 71 | hedged into the base currency \eqn{b_{L}}{bL} - total 72 | benchmark returns in the local currency \eqn{r_{L}}{rL} - 73 | total portfolio returns in the local currency The total 74 | excess returns are decomposed into: 75 | \deqn{\frac{(1+R_{p})}{1+R_{b}}-1=\frac{1+r_{L}}{1+b_{SL}}\times\frac{1+ 76 | b_{SH}}{1+b_{L}}\times\frac{1+b_{SL}}{1+b_{SH}}\times\frac{1+R_{p}}{1+r_{L}} 77 | \times\frac{1+b_{L}}{1+R_{b}}-1} 78 | 79 | where the first term corresponds to the selection, second 80 | to the allocation, third to the hedging cost transferred 81 | and the last two to the naive currency attribution 82 | } 83 | \examples{ 84 | data(attrib) 85 | Attribution.geometric(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], 86 | Rb = attrib.returns[, 11:20], wb = attrib.weights[2, ]) 87 | } 88 | \author{ 89 | Andrii Babii 90 | } 91 | \references{ 92 | Christopherson, Jon A., Carino, David R., Ferson, Wayne 93 | E. \emph{Portfolio Performance Measurement and 94 | Benchmarking}. McGraw-Hill. 2009. Chapter 18-19 \cr 95 | Bacon, C. \emph{Practical Portfolio Performance 96 | Measurement and Attribution}. Wiley. 2004. Chapter 5, 8, 97 | Appendix A \cr 98 | } 99 | \seealso{ 100 | \code{\link{Attribution}} 101 | } 102 | \keyword{attribution,} 103 | \keyword{geometric} 104 | \keyword{linking} 105 | 106 | -------------------------------------------------------------------------------- /R/Menchero.R: -------------------------------------------------------------------------------- 1 | #' calculates total attribution effects using Menchero smoothing 2 | #' 3 | #' Calculates total attribution effects over multiple periods using 4 | #' Menchero linking method. Used internally by the \code{\link{Attribution}} 5 | #' function. Arithmetic attribution effects do not naturally link over time. 6 | #' This function uses Menchero smoothing algorithm to adjust 7 | #' attribution effects so that they can be summed up over multiple periods 8 | #' Attribution effect are multiplied by the adjustment factor 9 | #' \deqn{A_{t}' = A_{t} \times (M +a_{t})}{At' = At * (M + at)} 10 | #' where \deqn{M=\frac{\frac{1}{n}(R_{p}-R_{b})}{(1+R_{p})^{\frac{1}{n}}- 11 | #' (1+R_{b})^{\frac{1}{n}}}} 12 | #' \deqn{a_{t} = \left(\frac{R_{p}-R_{b}-M\times\sum^{n}_{t=1}(R_{pt}- 13 | #' R_{bt})}{\sum^{n}_{t=1}(R_{pt}-R_{bt})^{2}}\right)\times(R_{pt}-R_{bt})} 14 | #' In case if portfolio and benchmark returns are equal the limit of the 15 | #' above value is used: 16 | #' \deqn{M = (1 + r_{p})^\frac{n-1}{n}}{M = (1 + rp)^((n - 1) / n)} 17 | #' \eqn{A_{t}'}{At'} - adjusted attribution effects at period \eqn{t}, 18 | #' \eqn{A_{t}}{At} - unadjusted attribution effects at period \eqn{t}, 19 | #' \eqn{R_{pt}}{Rpt} - portfolio returns at period \eqn{t}, 20 | #' \eqn{R_{bt}}{Rbt} - benchmark returns at period \eqn{t}, 21 | #' \eqn{R_{p}}{Rp} - total portfolio returns, 22 | #' \eqn{R_{b}}{Rb} - total benchmark returns, 23 | #' \eqn{n} - number of periods 24 | #' 25 | #' The total arithmetic excess returns can be explained in terms of the sum 26 | #' of adjusted attribution effects: 27 | #' \deqn{R_{p} - R_{b} = \sum^{n}_{t=1}\left(Allocation_{t}+Selection_{t}+ 28 | #' Interaction_{t}\right)} 29 | #' 30 | #' @aliases Menchero 31 | #' @param rp xts of portfolio returns 32 | #' @param rb xts of benchmark returns 33 | #' @param attributions xts with attribution effects 34 | #' @param adjusted TRUE/FALSE, whether to show original or smoothed attribution 35 | #' effects for each period 36 | #' @return returns a data frame with original attribution effects and total 37 | #' attribution effects over multiple periods 38 | #' @author Andrii Babii 39 | #' @seealso \code{\link{Attribution}} \cr \code{\link{Carino}} \cr 40 | #' \code{\link{Grap}} \cr \code{\link{Frongello}} \cr 41 | #' \code{\link{Attribution.geometric}} 42 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and 43 | #' Attribution}. Wiley. 2004. p. 194-196 \cr Menchero, J. (2000) \emph{An 44 | #' optimized approach to linking attribution effects over time}. Journal of 45 | #' Performance Measurement. Fall. p. 36-42 \cr 46 | #' @keywords arithmetic attribution, Menchero linking 47 | #' @examples 48 | #' 49 | #' data(attrib) 50 | #' Menchero(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 51 | #' 52 | #' @export 53 | Menchero <- 54 | function(rp, rb, attributions, adjusted) 55 | { # @author Andrii Babii 56 | 57 | # DESCRIPTION: 58 | # Function to provide multi-period summary of attribution effects using 59 | # Menchero linking. Used internally by the Attribution function 60 | 61 | # Inputs: 62 | # rp xts of portfolio returns 63 | # rb xts of benchmark returns 64 | # attributions attribution effects (allocation, selection, interaction) 65 | 66 | # Outputs: 67 | # This function returns the data.frame with original attribution effects 68 | # and total attribution effects over multiple periods 69 | 70 | # FUNCTION: 71 | rpc = prod(1 + rp) - 1 # Cumulative returns 72 | rbc = prod(1 + rb) - 1 73 | T = nrow(rp) 74 | if (rpc == rbc){ 75 | M = (1 + rbc)^((T - 1) / T) 76 | at = 0 77 | } else{ 78 | M = ((rpc - rbc) / T) / ((1 + rpc)^(1 / T) - (1 + rbc)^(1 / T)) 79 | at = (rpc - rbc - M * sum(rp - rb)) * (rp - coredata(rb)) / sum((rp - 80 | coredata(rb))^2) 81 | } 82 | m = matrix(rep(M + at, ncol(attributions)), nrow(attributions), 83 | ncol(attributions), byrow = FALSE) 84 | adj = attributions * m 85 | total = colSums(adj) 86 | if (adjusted == FALSE){ 87 | attributions = rbind(as.data.frame(attributions), total) 88 | } else{ 89 | attributions = rbind(as.data.frame(adj), total) 90 | } 91 | rownames(attributions)[nrow(attributions)] = "Total" 92 | return(attributions) 93 | } -------------------------------------------------------------------------------- /R/Carino.R: -------------------------------------------------------------------------------- 1 | #' calculates total attribution effects using logarithmic smoothing 2 | #' 3 | #' Calculates total attribution effects over multiple periods using 4 | #' logarithmic linking method. Used internally by the \code{\link{Attribution}} 5 | #' function. Arithmetic attribution effects do not naturally link over time. 6 | #' This function uses logarithmic smoothing to adjust attribution effects 7 | #' so that they can be summed up over multiple periods. Attribution effect 8 | #' are multiplied by the adjustment factor: 9 | #' \deqn{A_{t}' = A_{t} \times \frac{k_{t}}{k}}{At' = At * kt / k} 10 | #' where \deqn{k_{t} = \frac{log(1 + R_{pt}) - 11 | #' log(1 + R_{bt})}{R_{pt} - R_{bt}}} 12 | #' \deqn{k = \frac{log(1 + R_{p}) - log(1 + R_{b})}{R_{p} - R_{b}}} 13 | #' In case if portfolio and benchmark returns are equal: 14 | #' \deqn{k_{t} = \frac{1}{1 + R_{pt}}}{kt = 1 / (1 + Rpt)} 15 | #' where \eqn{A_{t}'}{At'} - adjusted attribution effects at period \eqn{t}, 16 | #' \eqn{A_{t}}{At} - unadjusted attribution effects at period \eqn{t}, 17 | #' \eqn{R_{pt}}{Rpt} - portfolio returns at period \eqn{t}, 18 | #' \eqn{R_{bt}}{Rbt} - benchmark returns at period \eqn{t}, 19 | #' \eqn{R_{p}}{Rp} - total portfolio returns, 20 | #' \eqn{R_{b}}{Rb} - total benchmark returns, 21 | #' \eqn{n} - number of periods 22 | #' The total arithmetic excess returns can be explained in terms of the sum 23 | #' of adjusted attribution effects: 24 | #' \deqn{R_{p} - R_{b} = \sum^{n}_{t=1}\left(Allocation_{t}+Selection_{t}+ 25 | #' Interaction_{t}\right)} 26 | #' 27 | #' @aliases Carino 28 | #' @param rp xts of portfolio returns 29 | #' @param rb xts of benchmark returns 30 | #' @param attributions xts with attribution effects 31 | #' @return returns a data frame with original attribution effects and total 32 | #' attribution effects over multiple periods 33 | #' @param adjusted TRUE/FALSE, whether to show original or smoothed attribution 34 | #' effects for each period 35 | #' @author Andrii Babii 36 | #' @seealso \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 37 | #' \code{\link{Grap}} \cr \code{\link{Frongello}} \cr 38 | #' \code{\link{Attribution.geometric}} 39 | #' @references Christopherson, Jon A., Carino, David R., Ferson, Wayne E. 40 | #' \emph{Portfolio Performance Measurement and Benchmarking}. McGraw-Hill. 41 | #' 2009. Chapter 19 \cr Bacon, C. \emph{Practical Portfolio Performance 42 | #' Measurement and Attribution}. Wiley. 2004. p. 191-193 \cr Carino, D. (1999) 43 | #' \emph{Combining attribution effects over time}. The Journal of Performance 44 | #' Measurement. Summer. p. 5-14 \cr 45 | #' @keywords arithmetic attribution, Carino linking, logarithmic linking 46 | #' @examples 47 | #' 48 | #' data(attrib) 49 | #' Carino(rp = attrib.returns[, 21], rb = attrib.returns[, 22], attributions = attrib.allocation, adjusted = FALSE) 50 | #' 51 | #' @export 52 | Carino <- 53 | function(rp, rb, attributions, adjusted) 54 | { # @author Andrii Babii 55 | 56 | # DESCRIPTION: 57 | # Function to provide multi-period summary of attribution effects using 58 | # logarithmic linking. Used internally by the Attribution function 59 | 60 | # Inputs: 61 | # rp xts of portfolio returns 62 | # rb xts of benchmark returns 63 | # attributions attribution effects (allocation, selection, interaction) 64 | 65 | # Outputs: 66 | # This function returns the data.frame with original attribution effects 67 | # and total attribution effects over multiple periods 68 | 69 | # FUNCTION: 70 | rpc = prod(1 + rp) - 1 # Cumulative returns 71 | rbc = prod(1 + rb) - 1 72 | k = (log(1 + rpc) - log(1 + rbc)) / (rpc - rbc) 73 | kt = rp 74 | for (t in 1:nrow(kt)){ 75 | if (rp[[t]] == rb[[t]]){ 76 | # Carino factors if portfolio and benchmarkreturns are equal 77 | kt[[t]] = 1 / (1 + rp[[t]]) 78 | } else{ 79 | # if different 80 | kt[[t]] = (log(1 + rp[[t]]) - log(1 + rb[[t]])) / (rp[[t]] - rb[[t]]) 81 | } 82 | } 83 | kt = matrix(rep(kt, ncol(attributions)), nrow(attributions), 84 | ncol(attributions), byrow = FALSE) 85 | adj = attributions * kt / k 86 | total = colSums(adj) 87 | if (adjusted == FALSE){ 88 | attributions = rbind(as.data.frame(attributions), total) 89 | } else{ 90 | attributions = rbind(as.data.frame(adj), total) 91 | } 92 | rownames(attributions)[nrow(attributions)] = "Total" 93 | 94 | return(attributions) 95 | } -------------------------------------------------------------------------------- /man/AttributionFixedIncome.Rd: -------------------------------------------------------------------------------- 1 | \name{AttributionFixedIncome} 2 | \alias{AttributionFixedIncome} 3 | \title{fixed income attribution} 4 | \usage{ 5 | AttributionFixedIncome(Rp, wp, Rb, wb, Rf, Dp, Db, S, 6 | wbf, geometric = FALSE) 7 | } 8 | \arguments{ 9 | \item{Rp}{T x n xts, data frame or matrix of portfolio 10 | returns} 11 | 12 | \item{wp}{vector, xts, data frame or matrix of portfolio 13 | weights} 14 | 15 | \item{Rb}{T x n xts, data frame or matrix of benchmark 16 | returns} 17 | 18 | \item{wb}{vector, xts, data frame or matrix of benchmark 19 | weights} 20 | 21 | \item{Rf}{T x n xts, data frame or matrix with risk free 22 | rates} 23 | 24 | \item{Dp}{T x n xts, data frame or matrix with portfolio 25 | modified duration} 26 | 27 | \item{Db}{T x n xts, data frame or matrix with benchmark 28 | modified duration} 29 | 30 | \item{wbf}{vector, xts, data frame or matrix with 31 | benchmark weights of currency forward contracts} 32 | 33 | \item{S}{(T + 1) x n xts, data frame or matrix with spot 34 | rates. The first date should coincide with the first date 35 | of portfolio returns} 36 | 37 | \item{geometric}{- TRUE/FALSE for geometric/arithmetic 38 | attribution} 39 | } 40 | \value{ 41 | list with total excess returns decomposed into 42 | allocation, selection (and currency effects) 43 | } 44 | \description{ 45 | Performs fixed income attribution. The investment 46 | decision process for bond managers is very different from 47 | that of equity managers, therefore for most fixed income 48 | investment strategies the standard Brinson model is not 49 | suitable. Bonds are simply a series of defined future 50 | cash flows which are relatively easy to price. Fixed 51 | income performance is therefore driven by changes in the 52 | shape of the yield curve. Systematic risk in the form of 53 | duration is a key part of the investment process. Fixed 54 | income attribution is, in fact, a specialist form of 55 | risk-adjusted attribution. The arithmetic attribution is 56 | handled using weighted duration approach (Van Breukelen, 57 | 2000). The allocation, selection and currency allocation 58 | effects for category \eqn{i} are: \deqn{A_{i} = 59 | (D_{pi}\times w_{pi}-D_{\beta}\times D_{bi}\times w_{pi}) 60 | \times (-\Delta y_{bi} + \Delta y_{b})} \deqn{S_{i} = 61 | D_{i}\times w_{pi}\times (-\Delta y_{ri} + \Delta 62 | y_{bi})} \deqn{C_{i} = (w_{pi} - w_{bi})\times (c_{i} + 63 | R_{fi} - c')}{Ci = (wpi - wbi) * (ci + Rfi - c')} where 64 | \eqn{w_{pi}}{wpi} - portfolio weights, \eqn{w_{bi}}{wbi} 65 | - benchmark weights, \eqn{D_{i}}{Di} - modified duration 66 | in bond category \eqn{i}. Duration beta: 67 | \deqn{D_{\beta}=\frac{D_{r}}{D_{b}}}{Dbeta = Dr / Db} 68 | \eqn{D_{r}}{Dr} - portfolio duration, \eqn{D_{b}}{Db} - 69 | benchmark duration, \eqn{D_{bi}}{Dbi} - benchmark 70 | duration for category \eqn{i}, \eqn{D_{pi}}{Dpi} - 71 | portfolio duration for category \eqn{i}, \eqn{\Delta 72 | y_{ri}}{Delta yri} - change in portfolio yield for 73 | category \eqn{i}, \eqn{\Delta y_{bi}}{Delta ybi} - change 74 | in benchmark yield for category \eqn{i}, \eqn{\Delta 75 | y_{b}}{Delta yb} - change in benchmark yield, 76 | \eqn{R_{ci}}{Rci} - currency returns for category 77 | \eqn{i}, \eqn{R_{fi}}{Rfi} - risk-free rate in currency 78 | of asset \eqn{i}, \deqn{c'= 79 | \sum_{i}w_{bi}\times(R_{ci}+R_{fi})} The geometric 80 | attribution is adapted using Van Breukelen (2000) 81 | approach for the arithmetic attribution. The individual 82 | allocation and selection effects are computed as follows: 83 | \deqn{A_{i}=D_{i}w_{pi}-D_{\beta}D_{bi}w_{bi}}{Ai = Di * 84 | wpi - Dbeta * Dbi * wbi} 85 | \deqn{S_{i}=\frac{D_{pi}}{D_{bi}}\times (R_{bi} - R_{fi}) 86 | + R_{fi}}{Si = Dpi / Dbi * (Rbi - Rfi) + Rfi} 87 | } 88 | \examples{ 89 | data(attrib) 90 | AttributionFixedIncome(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 91 | wb = attrib.weights[2, ], Rf = attrib.returns[, 23:32], Dp = attrib.returns[, 63:72], Db = attrib.returns[, 73:82], 92 | S = attrib.currency[, 11:20], wbf = attrib.weights[4, ], geometric = FALSE) 93 | } 94 | \author{ 95 | Andrii Babii 96 | } 97 | \references{ 98 | Bacon, C. \emph{Practical Portfolio Performance 99 | Measurement and Attribution}. Wiley. 2004. Chapter 7 \cr 100 | Van Breukelen, G. \emph{Fixed income attribution}. 101 | Journal of Performance Measurement. Sumer. p. 61-68. 2000 102 | \cr 103 | } 104 | \seealso{ 105 | \code{\link{Attribution.levels}}, 106 | \code{\link{Attribution.geometric}} 107 | } 108 | \keyword{attribution} 109 | 110 | -------------------------------------------------------------------------------- /inst/doc/References.bib: -------------------------------------------------------------------------------- 1 | @book{bacon2008practical, 2 | title={Practical Portfolio Performance Measurement and Attribution, with CD-ROM}, 3 | author={Bacon, Carl R}, 4 | volume={546}, 5 | year={2008}, 6 | publisher={Wiley} 7 | } 8 | @book{christopherson2009portfolio, 9 | title={Portfolio Performance Measurement and Benchmarking}, 10 | author={Christopherson, Jon A and Cari{\~n}o, David Runge and Ferson, Wayne E}, 11 | year={2009}, 12 | publisher={McGraw-Hill New York, NY} 13 | } @article{brinson1985measuring, 14 | title={Measuring non-US. equity portfolio performance}, 15 | author={Brinson, Gary P and Fachler, Nimrod}, 16 | journal={The Journal of Portfolio Management}, 17 | volume={11}, 18 | number={3}, 19 | pages={73--76}, 20 | year={1985}, 21 | publisher={Institutional Investor Journals} 22 | } 23 | @article{brinson1986determinants, 24 | title={Determinants of portfolio performance}, 25 | author={Brinson, Gary P and Hood, L Randolph and Beebower, Gilbert L}, 26 | journal={Financial Analysts Journal}, 27 | pages={39--44}, 28 | year={1986}, 29 | publisher={JSTOR} 30 | } 31 | @article{fama1972components, 32 | title={COMPONENTS OF INVESTMENT PERFORMANCE*}, 33 | author={Fama, Eugene F}, 34 | journal={The Journal of Finance}, 35 | volume={27}, 36 | number={3}, 37 | pages={551--568}, 38 | year={1972}, 39 | publisher={Wiley Online Library} 40 | } 41 | @article{carino1999combining, 42 | title={Combining attribution effects over time}, 43 | author={Carino, David}, 44 | journal={Journal of Performance Measurement}, 45 | volume={3}, 46 | number={4}, 47 | pages={5--14}, 48 | year={1999} 49 | } 50 | @article{grap1997, 51 | title={Synthese des modeles d’attribution de performance}, 52 | author={GRAP, (Groupe de Recherche en Attribution de Performance)}, 53 | journal={Journal of Performance Measurement}, 54 | year={1997}, 55 | publisher={Paris, Mars.} 56 | } 57 | @article{menchero2000optimized, 58 | title={An optimized approach to linking attribution effects over time}, 59 | author={Menchero, Jose G}, 60 | journal={Journal of Performance Measurement}, 61 | volume={5}, 62 | number={1}, 63 | pages={36--42}, 64 | year={2000} 65 | } 66 | @article{frongello2002linking, 67 | title={Linking single period attribution results}, 68 | author={Frongello, Andrew Scott Bay}, 69 | journal={Journal of Performance Measurement}, 70 | volume={6}, 71 | number={3}, 72 | pages={10--22}, 73 | year={2002}, 74 | publisher={TGS Publishing} 75 | } 76 | @article{davies2001multiple, 77 | title={Multiple-period performance attribution using the Brinson model}, 78 | author={Davies, Owen and Laker, Damien}, 79 | journal={Journal of Performance Measurement}, 80 | volume={6}, 81 | number={1}, 82 | pages={12--22}, 83 | year={2001} 84 | } 85 | @article{van2000fixed, 86 | title={Fixed income attribution}, 87 | author={Van Breukelen, G}, 88 | journal={Journal of Performance Measurement}, 89 | volume={4}, 90 | number={4}, 91 | pages={61--68}, 92 | year={2000} 93 | } 94 | @article{ankrim1994multicurrency, 95 | title={Multicurrency performance attribution}, 96 | author={Ankrim, Ernest M and Hensel, Chris R}, 97 | journal={Financial Analysts Journal}, 98 | pages={29--35}, 99 | year={1994}, 100 | publisher={JSTOR} 101 | } 102 | @article{treynor1966can, 103 | title={Can mutual funds outguess the market}, 104 | author={Treynor, Jack and Mazuy, Kay}, 105 | journal={Harvard Business Review}, 106 | volume={44}, 107 | number={4}, 108 | pages={131--136}, 109 | year={1966} 110 | } 111 | @article{henriksson1981market, 112 | title={On market timing and investment performance. II. Statistical procedures for evaluating forecasting skills}, 113 | author={Henriksson, Roy D and Merton, Robert C}, 114 | journal={Journal of Business}, 115 | pages={513--533}, 116 | year={1981}, 117 | publisher={JSTOR} 118 | } 119 | @article{modigliani1997risk, 120 | title={Risk-adjusted performance}, 121 | author={Modigliani, Franco and Modigliani, Leah}, 122 | journal={The Journal of Portfolio Management}, 123 | volume={23}, 124 | number={2}, 125 | pages={45--54}, 126 | year={1997}, 127 | publisher={Institutional Investor Journals} 128 | } 129 | @article{ferson1996measuring, 130 | title={Measuring fund strategy and performance in changing economic conditions}, 131 | author={Ferson, Wayne E and Schadt, Rudi W}, 132 | journal={The Journal of Finance}, 133 | volume={51}, 134 | number={2}, 135 | pages={425--461}, 136 | year={1996}, 137 | publisher={Wiley Online Library} 138 | } 139 | @article{christopherson1999performance, 140 | title={Performance evaluation using conditional alphas and betas}, 141 | author={Christopherson, Jon A and Ferson, Wayne E and Turner, Andrew L}, 142 | journal={The Journal of Portfolio Management}, 143 | volume={26}, 144 | number={1}, 145 | pages={59--72}, 146 | year={1999}, 147 | publisher={Institutional Investor Journals} 148 | } -------------------------------------------------------------------------------- /R/DaviesLaker.R: -------------------------------------------------------------------------------- 1 | #' calculates total attribution effects using Davies and Laker smoothing 2 | #' 3 | #' Calculates total attribution effects over multiple periods using 4 | #' Davies and Laker linking method. Used internally by the 5 | #' \code{\link{Attribution}} function. Arithmetic attribution effects do not 6 | #' naturally link over time. This function uses Davies and Laker linking method 7 | #' to compute total attribution effects. 8 | #' Arithmetic excess returns are decomposed as follows: 9 | #' \deqn{R_{p} - R_{b} = Allocation + Selection + Interaction}{Rp - Rb = 10 | #' Allocation + Selection + Interaction} 11 | #' \deqn{Allocation = \prod^{T}_{t=1}(1+bs_{t})-\prod^{T}_{t=1}(1+R_{bt})} 12 | #' \deqn{Selection = \prod^{T}_{t=1}(1+rs_{t})-\prod^{T}_{t=1}(1+R_{bt})} 13 | #' \deqn{Interaction = \prod^{T}_{t=1}(1+R_{pt})-\prod^{T}_{t=1}(1+rs_{t})- 14 | #' \prod^{T}_{t=1}(1+bs_{t})+\prod^{T}_{t=1}(1+R_{bt})} 15 | #' \eqn{R_{pi}}{Rpi} - portfolio returns at period \eqn{i}, 16 | #' \eqn{R_{bi}}{Rbi} - benchmark returns at period \eqn{i}, 17 | #' \eqn{rs_{i}}{rsi} - selection notional fund returns at period \eqn{i}, 18 | #' \eqn{bs_{i}}{bsi} - allocation notional fund returns at period \eqn{i}, 19 | #' \eqn{T} - number of periods 20 | #' 21 | #' @aliases DaviesLaker 22 | #' @param Rp xts of portfolio returns 23 | #' @param wp xts of portfolio weights 24 | #' @param Rb xts of benchmark returns 25 | #' @param wb xts of benchmark weights 26 | #' @return This function returns the data.frame with original attribution 27 | #' effects and total attribution effects over multiple periods 28 | #' @author Andrii Babii 29 | #' @seealso \code{\link{Attribution}} \cr \code{\link{Menchero}} \cr 30 | #' \code{\link{Grap}} \cr \code{\link{Carino}} \cr 31 | #' \code{\link{Attribution.geometric}} \cr \code{\link{Frongello}} 32 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and 33 | #' Attribution}. Wiley. 2004. p. 201-204 \cr Davies, O. and Laker, D. (2001) 34 | #' \emph{Multiple-period performance attribution using the Brinson model}. 35 | #' Journal of Performance Measurement. Fall. p. 12-22 \cr 36 | #' @keywords arithmetic attribution, Davies and Laker linking 37 | #' @examples 38 | #' 39 | #' data(attrib) 40 | #' DaviesLaker(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], wb = attrib.weights[2, ]) 41 | #' 42 | #' @export 43 | DaviesLaker <- 44 | function(Rp, wp, Rb, wb) 45 | { # @author Andrii Babii 46 | 47 | # DESCRIPTION: 48 | # Function to provide multi-period summary of attribution effects using 49 | # Davies and Laker linking. Used internally by the Attribution function 50 | 51 | # Inputs: 52 | # Rp xts, data frame or matrix of portfolio returns 53 | # wp vector, xts, data frame or matrix of portfolio weights 54 | # Rb xts, data frame or matrix of benchmark returns 55 | # wb vector, xts, data frame or matrix of benchmark weights 56 | 57 | # Outputs: 58 | # This function returns the data.frame with original attribution effects 59 | # and total attribution effects over multiple periods 60 | 61 | # FUNCTION: 62 | WP = wp 63 | WB = wb 64 | wp = Weight.transform(wp, Rp) 65 | wb = Weight.transform(wb, Rb) 66 | if (is.vector(WP) & is.vector(WB)){ 67 | rp = Return.portfolio(Rp, WP, geometric = FALSE) 68 | rb = Return.portfolio(Rb, WB, geometric = FALSE) 69 | } else{ 70 | rp = Return.rebalancing(Rp, WP, geometric = FALSE) 71 | rb = Return.rebalancing(Rb, WB, geometric = FALSE) 72 | } 73 | colnames(rp) = "Total" 74 | colnames(rb) = "Total" 75 | # Allocation notional fund returns 76 | bs = reclass(rowSums((wp * coredata(Rb[, 1:ncol(wp)]))), Rp) 77 | # Selection notional fund returns 78 | rs = reclass(rowSums((wb * coredata(Rp[, 1:ncol(wb)]))), Rp) 79 | a = apply(1 + bs, 2, prod) - apply(1 + rb, 2, prod) 80 | s = apply(1 + rs, 2, prod) - apply(1 + rb, 2, prod) 81 | i = apply(1 + rp, 2, prod) - apply(1 + rs, 2, prod) - 82 | apply(1 + bs, 2, prod) + apply(1 + rb, 2, prod) 83 | 84 | # Compute attribution effects (Brinson, Hood and Beebower model) 85 | allocation = (wp - wb) * coredata(Rb) 86 | selection = wb * (Rp - coredata(Rb)) 87 | interaction = (wp - wb) * (Rp - coredata(Rb)) 88 | n = ncol(allocation) # number of segments 89 | allocation = cbind(allocation, rowSums(allocation)) 90 | names(allocation)[n + 1] = "Total" 91 | selection = cbind(selection, rowSums(selection)) 92 | names(selection)[n + 1] = "Total" 93 | interaction = cbind(interaction, rowSums(interaction)) 94 | names(interaction)[n + 1] = "Total" 95 | 96 | allocation = rbind(as.data.frame(allocation), 97 | c(rep(NA, ncol(allocation) - 1), a)) 98 | selection = rbind(as.data.frame(selection), 99 | c(rep(NA, ncol(selection) - 1), s)) 100 | interaction = rbind(as.data.frame(interaction), 101 | c(rep(NA, ncol(interaction) - 1), i)) 102 | rownames(allocation)[nrow(allocation)] = "Total" 103 | rownames(selection)[nrow(selection)] = "Total" 104 | rownames(interaction)[nrow(allocation)] = "Total" 105 | 106 | # Arithmetic excess returns + annualized arithmetic excess returns 107 | excess.returns = rp - coredata(rb) 108 | if (nrow(rp) > 1){ 109 | er = Return.annualized.excess(rp, rb, geometric = FALSE) 110 | excess.returns = rbind(as.matrix(excess.returns), er) 111 | } 112 | colnames(excess.returns) = "Arithmetic" 113 | 114 | result = list() 115 | result[[1]] = excess.returns 116 | result[[2]] = allocation 117 | result[[3]] = selection 118 | result[[4]] = interaction 119 | names(result) = c("Excess returns", "Allocation", "Selection", 120 | "Interaction") 121 | return(result) 122 | } 123 | -------------------------------------------------------------------------------- /test_suite.R: -------------------------------------------------------------------------------- 1 | # Load the data 2 | data(attrib) 3 | Rp = attrib.returns[, 1:10] 4 | Rb = attrib.returns[, 11:20] 5 | rp = attrib.returns[, 21] 6 | rb = attrib.returns[, 22] 7 | Rf = attrib.returns[, 23:32] 8 | Rpl = attrib.returns[, 33:42] 9 | Rbl = attrib.returns[, 43:52] 10 | Rbh = attrib.returns[, 53:62] 11 | 12 | Dp = attrib.returns[, 63:72] 13 | Db = attrib.returns[, 73:82] 14 | wp = attrib.weights[1, ] 15 | wb = attrib.weights[2, ] 16 | wpf = attrib.weights[3, ] 17 | wbf = attrib.weights[4, ] 18 | h = attrib.hierarchy 19 | allocation = attrib.allocation 20 | F = attrib.currency[, 1:10] 21 | S = attrib.currency[, 11:20] 22 | 23 | # I. Check different options 24 | 25 | Attribution(Rp, wp, Rb, wb, method = "top.down", linking = "carino") 26 | Attribution(Rp, wp, Rb, wb, method = "bottom.up", linking = "menchero") 27 | Attribution(Rp, wp, Rb, wb, method = "none", linking = "grap") 28 | Attribution(Rp, wp, Rb, wb, method = "none", linking = "frongello") 29 | Attribution(Rp, wp, Rb, wb, method = "none", linking = "davies.laker") 30 | Attribution(Rp, wp, Rb, wb, method = "none", linking = "none", geometric = TRUE) 31 | 32 | AttributionFixedIncome(Rp, wp, Rb, wb, Rf, Dp, Db, S, wbf, geometric = FALSE) 33 | AttributionFixedIncome(Rp, wp, Rb, wb, Rf, Dp, Db, S, wbf, geometric = TRUE) 34 | 35 | Attribution(Rp, wp, Rb, wb, wpf, wbf, S, F, Rpl, Rbl, Rbh, method = "none", linking = "carino") 36 | 37 | Weight.transform(wp, Rp) 38 | Return.level(Rp, wp, h, level = "MarketCap") 39 | Weight.level(wp, Rp, h, level = "Sector") 40 | 41 | Attribution.levels(Rp, wp, Rb, wb, h, c("type", "MarketCap", "currency", "Sector")) 42 | Attribution.levels(Rp, wp, Rb, wb, h, c("type", "currency", "Sector")) 43 | Attribution.levels(Rp, wp, Rb, wb, h, c("type", "Sector")) 44 | 45 | Return.annualized.excess(rp, rb) 46 | HierarchyQuintiles(h, "MarketCap") 47 | 48 | data(managers) 49 | Modigliani(managers[,1,drop=FALSE], managers[,8,drop=FALSE], Rf=.035/12) 50 | Modigliani(managers[,1:6], managers[,8,drop=FALSE], managers[,8,drop=FALSE]) 51 | Modigliani(managers[,1:6], managers[,8:7], managers[,8,drop=FALSE]) 52 | MarketTiming(managers[,1,drop=FALSE], managers[,8,drop=FALSE], Rf=.035/12, method = "HM") 53 | MarketTiming(managers[80:120,1:6], managers[80:120,7,drop=FALSE], managers[80:120,10,drop=FALSE]) 54 | MarketTiming(managers[80:120,1:6], managers[80:120,8:7], managers[80:120,10,drop=FALSE], method = "TM") 55 | CAPM.dynamic(managers[,1,drop=FALSE], managers[,8,drop=FALSE], Rf=.035/12, Z=managers[, 9:10]) 56 | CAPM.dynamic(managers[80:120,1:6], managers[80:120,7,drop=FALSE], Rf=managers[80:120,10,drop=FALSE], Z=managers[80:120, 9:10]) 57 | CAPM.dynamic(managers[80:120,1:6], managers[80:120,8:7], managers[80:120,10,drop=FALSE], Z=managers[80:120, 9:10]) 58 | 59 | 60 | # !!! Run after amzn_test.R demo (from the blotter package) to get a dataset 61 | AcctReturns("amzn_acct", method = "timeweighted") 62 | AcctReturns("amzn_acct", method = "dietz") # NA because only 1 month in the data 63 | 64 | # II. Comparing with results in books 65 | # Data 66 | allocation <- matrix(c(0, -0.0104, -0.0016, -0.0072, -0.0086, 0.0108, 0.025, 0.0175, -0.0075, -0.003, -0.007, 0), 4, 3, TRUE) 67 | selection <- matrix(c(0.04, -0.003, -0.006, 0.014, -0.002, 0.005, 0.015, 0.015, 0.01, 0.015, -0.01, 0.03), 4, 3, TRUE) 68 | wp <- matrix(c(0.4, 0.3, 0.3, 0.7, 0.2, 0.1, 0.3, 0.5, 0.2, 0.3, 0.5, 0.2), 4, 3, TRUE) 69 | wb <- matrix(c(0.4, 0.2, 0.4, 0.4, 0.3, 0.3, 0.5, 0.4, 0.1, 0.4, 0.4, 0.2), 4, 3, TRUE) 70 | Rp <- matrix(c(0.2, -0.05, 0.06, -0.05, 0.03, -0.05, -0.2, 0.08, -0.15, 0.1, -0.07, 0.25), 4, 3, TRUE) 71 | Rb <- matrix(c(0.1, -0.04, 0.08, -0.07, 0.04, -0.1, -0.25, 0.05, -0.2, 0.05, -0.05, 0.1), 4, 3, TRUE) 72 | rownames(wp) <- c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01") 73 | colnames(wp) <- c("UK equities", "Japanese equities", "US equities") 74 | rownames(wb) <- c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01") 75 | colnames(wb) <- c("UK equities", "Japanese equities", "US equities") 76 | rownames(Rp) <- c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01") 77 | colnames(Rp) <- c("UK equities", "Japanese equities", "US equities") 78 | rownames(Rb) <- c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01") 79 | colnames(Rb) <- c("UK equities", "Japanese equities", "US equities") 80 | Rp <- checkData(Rp) 81 | Rb <- checkData(Rb) 82 | wp <- checkData(wp) 83 | wb <- checkData(wb) 84 | rownames(allocation) <- c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01") 85 | rownames(selection) <- c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01") 86 | allocation <- cbind(allocation, rowSums(allocation)) 87 | selection <- cbind(selection, rowSums(selection)) 88 | colnames(allocation) <- c("UK equities", "Japanese equities", "US equities", "Total") 89 | colnames(selection) <- c("UK equities", "Japanese equities", "US equities", "Total") 90 | rp = reclass(rowSums(Rp * wp), Rp) 91 | rb = reclass(rowSums(Rb * wb), Rb) 92 | rp = checkData(rp) 93 | rb = checkData(rb) 94 | 95 | # 1. Arithmetic attribution 96 | RP=Rp[1, ] 97 | RB=Rb[1, ] 98 | WB=as.vector(wb[1, ]) 99 | WP=as.vector(wp[1, ]) 100 | # 1.1 Brinson-Hood-Beebower. The same as in Table 5.2 (Bacon, 2008) 101 | Attribution(RP, WP, RB, WB, method = "none", linking = "none", geometric = FALSE) 102 | # 1.2 Brinson- Fachler. The same as in Table 5.3 (Bacon, 2008) 103 | Attribution(RP, WP, RB, WB, bf = TRUE, method = "none", linking = "none", geometric = FALSE) 104 | 105 | # 2. Carino linking 106 | Carino(rp, rb, allocation, TRUE) # Attribution effects are the same as in Table 8.2 (Bacon, 2008) 107 | Carino(rp, rb, selection, TRUE) # Attribution effects are the same as in Table 8.2 (Bacon, 2008) 108 | 109 | # 3. Menchero linking 110 | Menchero(rp, rb, allocation, TRUE) # Attribution effects are the same as in Table 8.3 (Bacon, 2008) 111 | Menchero(rp, rb, selection, TRUE) # Attribution effects are the same as in Table 8.3 (Bacon, 2008) 112 | 113 | # 4. GRAP linking 114 | Grap(rp, rb, allocation, TRUE) # Attribution effects are the same as in Table 8.4 (Bacon, 2008) 115 | Grap(rp, rb, selection, TRUE) # Attribution effects are the same as in Table 8.4 (Bacon, 2008) 116 | 117 | # 5. Frongello linking 118 | Frongello(rp, rb, allocation, TRUE)# Attribution effects are the same as in Table 8.5 (Bacon, 2008) 119 | Frongello(rp, rb, selection, TRUE) # Attribution effects are the same as in Table 8.5 (Bacon, 2008) 120 | 121 | # 6. Geometric attribution 122 | # 6.1 Single-period 123 | RP=Rp[1, ] 124 | RB=Rb[1, ] 125 | WB=as.vector(coredata(wb[1, ])) 126 | WP=as.vector(coredata(wp[1, ])) 127 | Attribution.geometric(RP, WP, RB, WB) # The same as in Table 5.5 128 | 129 | # 6.2 Multi-period 130 | index(wp) <- as.Date(c("2011-12-31", "2012-02-01", "2012-03-01", "2012-04-01")) 131 | index(wb) <- as.Date(c("2011-12-31", "2012-02-01", "2012-03-01", "2012-04-01")) 132 | # Total effects and total excess returns are the same as in Table 8.6 and Exhibit 8.12 (Bacon, 2008) 133 | Attribution(Rp, wp, Rb, wb, method = "none", linking = "none", geometric = TRUE) -------------------------------------------------------------------------------- /R/Attribution.geometric.R: -------------------------------------------------------------------------------- 1 | #' performs sector-based geometric attribution 2 | #' 3 | #' Performs sector-based geometric attribution of excess return. Calculates 4 | #' total geometric attribution effects over multiple periods. Used internally 5 | #' by the \code{\link{Attribution}} function. Geometric attribution effects in 6 | #' the contrast with arithmetic do naturally link over time multiplicatively: 7 | #' \deqn{\frac{(1+R_{p})}{1+R_{b}}-1=\prod^{n}_{t=1}(1+A_{t}^{G})\times 8 | #' \prod^{n}_{t=1}(1+S{}_{t}^{G})-1} 9 | #' Total allocation effect at time \eqn{t}: 10 | #' \deqn{A_{t}^{G}=\frac{1+b_{S}}{1+R_{bt}}-1} 11 | #' Total selection effect at time \eqn{t}: 12 | #' \deqn{S_{t}^{G}=\frac{1+R_{pt}}{1+b_{S}}-1} 13 | #' Semi-notional fund: 14 | #' \deqn{b_{S}=\sum^{n}_{i=1}w_{pi}\times R_{bi}} 15 | #' \eqn{w_{pt}}{wpt} - portfolio weights at time \eqn{t}, 16 | #' \eqn{w_{bt}}{wbt} - benchmark weights at time \eqn{t}, 17 | #' \eqn{r_{t}}{rt} - portfolio returns at time \eqn{t}, 18 | #' \eqn{b_{t}}{bt} - benchmark returns at time \eqn{t}, 19 | #' \eqn{r} - total portfolio returns 20 | #' \eqn{b} - total benchmark returns 21 | #' \eqn{n} - number of periods 22 | #' 23 | #' The multi-currency geometric attribution is handled following the Appendix A 24 | #' (Bacon, 2004). 25 | #' 26 | #' The individual selection effects are computed using: 27 | #' \deqn{w_{pi}\times\left(\frac{1+R_{pLi}}{1+R_{bLi}}-1\right)\times 28 | #' \left(\frac{1+R_{bLi}}{1+b_{SL}}\right)} 29 | #' 30 | #' The individual allocation effects are computed using: 31 | #' \deqn{(w_{pi}-w_{bi})\times\left(\frac{1+R_{bHi}}{1+b_{L}}-1\right)} 32 | #' 33 | #' Where the total semi-notional returns hedged into the base currency were 34 | #' used: 35 | #' \deqn{b_{SH} = \sum_{i}w_{pi}\times R_{bi}((w_{pi} - w_{bi})R_{bHi} + 36 | #' w_{bi}R_{bLi})} 37 | #' Total semi-notional returns in the local currency: 38 | #' \deqn{b_{SL} = \sum_{i}w_{pi}R_{bLi}} 39 | #' \eqn{R_{pLi}}{RpLi} - portfolio returns in the local currency 40 | #' \eqn{R_{bLi}}{RbLi} - benchmark returns in the local currency 41 | #' \eqn{R_{bHi}}{RbHi} - benchmark returns hedged into the base currency 42 | #' \eqn{b_{L}}{bL} - total benchmark returns in the local currency 43 | #' \eqn{r_{L}}{rL} - total portfolio returns in the local currency 44 | #' The total excess returns are decomposed into: 45 | #' \deqn{\frac{(1+R_{p})}{1+R_{b}}-1=\frac{1+r_{L}}{1+b_{SL}}\times\frac{1+ 46 | #' b_{SH}}{1+b_{L}}\times\frac{1+b_{SL}}{1+b_{SH}}\times\frac{1+R_{p}}{1+r_{L}} 47 | #' \times\frac{1+b_{L}}{1+R_{b}}-1} 48 | #' 49 | #' where the first term corresponds to the selection, second to the allocation, 50 | #' third to the hedging cost transferred and the last two to the naive currency 51 | #' attribution 52 | #' 53 | #' @aliases Attribution.geometric 54 | #' @param Rp xts of portfolio returns 55 | #' @param wp xts of portfolio weights 56 | #' @param Rb xts of benchmark returns 57 | #' @param wb xts of benchmark weights 58 | #' @param Rpl xts, data frame or matrix of portfolio returns in local currency 59 | #' @param Rbl xts, data frame or matrix of benchmark returns in local currency 60 | #' @param Rbh xts, data frame or matrix of benchmark returns hedged into the 61 | #' base currency 62 | #' @return This function returns the list with attribution effects (allocation 63 | #' or selection effect) including total multi-period attribution effects 64 | #' @author Andrii Babii 65 | #' @seealso \code{\link{Attribution}} 66 | #' @references Christopherson, Jon A., Carino, David R., Ferson, Wayne E. 67 | #' \emph{Portfolio Performance Measurement and Benchmarking}. McGraw-Hill. 68 | #' 2009. Chapter 18-19 \cr Bacon, C. \emph{Practical Portfolio Performance 69 | #' Measurement and Attribution}. Wiley. 2004. Chapter 5, 8, Appendix A \cr 70 | #' @keywords attribution, geometric attribution, geometric linking 71 | #' @examples 72 | #' 73 | #' data(attrib) 74 | #' Attribution.geometric(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], 75 | #' Rb = attrib.returns[, 11:20], wb = attrib.weights[2, ]) 76 | #' 77 | #' @export 78 | Attribution.geometric <- 79 | function(Rp, wp, Rb, wb, Rpl = NA, Rbl = NA, Rbh = NA) 80 | { # @author Andrii Babii 81 | 82 | # DESCRIPTION: 83 | # Function to perform the geometric attribution analysis. 84 | 85 | # Inputs: 86 | # Rp xts of portfolio returns 87 | # wp xts of portfolio weights 88 | # Rb xts of benchmark returns 89 | # wb xts of benchmark weights 90 | 91 | # Outputs: 92 | # This function returns the list with attribution effects (allocation or 93 | # selection effect) including total multi-period attribution effects 94 | 95 | # FUNCTION: 96 | WP = wp # Save original weights in order to avoid double conversion later 97 | WB = wb 98 | wp = Weight.transform(wp, Rp) 99 | wb = Weight.transform(wb, Rb) 100 | currency = !(is.null(dim(Rpl)) & is.null(dim(Rpl)) & is.null(dim(Rpl))) 101 | 102 | # Get total portfolio returns 103 | if (is.vector(WP) & is.vector(WB)){ 104 | rp = Return.portfolio(Rp, WP) 105 | rb = Return.portfolio(Rb, WB) 106 | } else{ 107 | rp = Return.rebalancing(Rp, WP) 108 | rb = Return.rebalancing(Rb, WB) 109 | } 110 | names(rp) = "Total" 111 | names(rb) = "Total" 112 | 113 | # Allocation notional fund returns 114 | bs = reclass(rowSums((wp * coredata(Rb[, 1:ncol(wp)]))), rp) 115 | if (!currency){ 116 | # Geometric attribution effects for individual categories 117 | allocation = ((1 + Rb) / (1 + rep(rb, ncol(Rp))) - 1) * coredata(wp - wb) 118 | selection = wp * (Rp - coredata(Rb)) / (1 + rep(bs, ncol(Rp))) 119 | colnames(allocation) = colnames(Rp) 120 | 121 | } else{ 122 | Rpl = checkData(Rpl) 123 | Rbl = checkData(Rbl) 124 | Rbh = checkData(Rbh) 125 | 126 | bsl = reclass(rowSums(Rbl * wp), Rpl) 127 | bsh = reclass(rowSums(((wp - wb) * Rbh + wb * Rbl)), Rpl) 128 | rpl = reclass(rowSums(Rpl * wp), Rpl) 129 | rbl = reclass(rowSums(Rbl * wp), Rpl) 130 | allocation = (wp - wb) * ((1 + Rbh) / (1 + rep(rbl, ncol(Rbh))) - 1) 131 | selection = wp * ((1 + Rpl) / (1 + Rbl) - 1) * ((1 + Rbl) / 132 | (1 + rep(bsl, ncol(Rbl)))) 133 | hedge = (1 + bsl) / (1 + bsh) - 1 134 | currency.attr = (1 + rp) * (1 + rbl) / (1 + rpl) / (1 + rb) - 1 135 | curr = cbind(hedge, currency.attr) 136 | colnames(curr) = c("Hedging", "Currency attribution") 137 | } 138 | 139 | # Total attribution effects are computed as a sum of individual effects 140 | allocation = cbind(allocation, rowSums(allocation)) 141 | selection = cbind(selection, rowSums(selection)) 142 | colnames(allocation)[ncol(allocation)] = "Total" 143 | colnames(selection)[ncol(selection)] = "Total" 144 | 145 | # Link single-period attribution effects 146 | a = (apply(1 + allocation[, ncol(allocation)], 2, prod) - 1) 147 | s = (apply(1 + selection[, ncol(selection)], 2, prod) - 1) 148 | allocation = rbind(as.data.frame(allocation), 149 | c(rep(NA, ncol(allocation) - 1), a)) 150 | selection = rbind(as.data.frame(selection), 151 | c(rep(NA, ncol(selection) - 1), s)) 152 | rownames(allocation)[nrow(allocation)] = "Total" 153 | rownames(selection)[nrow(selection)] = "Total" 154 | 155 | # Geometric excess returns + annualized geometric excess returns 156 | excess.returns = (1 + rp) / (1 + coredata(rb)) - 1 157 | if (nrow(rp) > 1){ 158 | er = Return.annualized.excess(rp, rb) 159 | excess.returns = rbind(as.matrix(excess.returns), er) 160 | } 161 | colnames(excess.returns) = "Geometric" 162 | 163 | result = list() 164 | result[[1]] = excess.returns 165 | result[[2]] = allocation 166 | result[[3]] = selection 167 | if (!currency){ 168 | names(result) = c("Excess returns", "Allocation", "Selection") 169 | } else{ 170 | result[[4]] = curr 171 | names(result) = c("Excess returns", "Allocation", "Selection", 172 | "Currency management") 173 | } 174 | 175 | return(result) 176 | } 177 | -------------------------------------------------------------------------------- /R/AttributionFixedIncome.R: -------------------------------------------------------------------------------- 1 | #' fixed income attribution 2 | #' 3 | #' Performs fixed income attribution. The investment decision process for bond 4 | #' managers is very different from that of equity managers, therefore for most 5 | #' fixed income investment strategies the standard Brinson model is not 6 | #' suitable. Bonds are simply a series of defined future cash flows which are 7 | #' relatively easy to price. Fixed income performance is therefore driven by 8 | #' changes in the shape of the yield curve. Systematic risk in the form of 9 | #' duration is a key part of the investment process. Fixed income attribution 10 | #' is, in fact, a specialist form of risk-adjusted attribution. 11 | #' The arithmetic attribution is handled using weighted duration approach 12 | #' (Van Breukelen, 2000). The allocation, selection and currency allocation 13 | #' effects for category \eqn{i} are: 14 | #' \deqn{A_{i} = (D_{pi}\times w_{pi}-D_{\beta}\times D_{bi}\times w_{pi}) 15 | #' \times (-\Delta y_{bi} + \Delta y_{b})} 16 | #' \deqn{S_{i} = D_{i}\times w_{pi}\times (-\Delta y_{ri} + \Delta y_{bi})} 17 | #' \deqn{C_{i} = (w_{pi} - w_{bi})\times (c_{i} + R_{fi} - c')}{Ci = 18 | #' (wpi - wbi) * (ci + Rfi - c')} 19 | #' where \eqn{w_{pi}}{wpi} - portfolio weights, 20 | #' \eqn{w_{bi}}{wbi} - benchmark weights, 21 | #' \eqn{D_{i}}{Di} - modified duration in bond category \eqn{i}. 22 | #' Duration beta: 23 | #' \deqn{D_{\beta}=\frac{D_{r}}{D_{b}}}{Dbeta = Dr / Db} 24 | #' \eqn{D_{r}}{Dr} - portfolio duration, 25 | #' \eqn{D_{b}}{Db} - benchmark duration, 26 | #' \eqn{D_{bi}}{Dbi} - benchmark duration for category \eqn{i}, 27 | #' \eqn{D_{pi}}{Dpi} - portfolio duration for category \eqn{i}, 28 | #' \eqn{\Delta y_{ri}}{Delta yri} - change in portfolio yield 29 | #' for category \eqn{i}, 30 | #' \eqn{\Delta y_{bi}}{Delta ybi} - change in benchmark yield 31 | #' for category \eqn{i}, 32 | #' \eqn{\Delta y_{b}}{Delta yb} - change in benchmark yield, 33 | #' \eqn{R_{ci}}{Rci} - currency returns for category \eqn{i}, 34 | #' \eqn{R_{fi}}{Rfi} - risk-free rate in currency of asset \eqn{i}, 35 | #' \deqn{c'= \sum_{i}w_{bi}\times(R_{ci}+R_{fi})} 36 | #' The geometric attribution is adapted using Van Breukelen (2000) approach for 37 | #' the arithmetic attribution. The individual allocation and selection effects 38 | #' are computed as follows: 39 | #' \deqn{A_{i}=D_{i}w_{pi}-D_{\beta}D_{bi}w_{bi}}{Ai = 40 | #' Di * wpi - Dbeta * Dbi * wbi} 41 | #' \deqn{S_{i}=\frac{D_{pi}}{D_{bi}}\times (R_{bi} - R_{fi}) + R_{fi}}{Si = 42 | #' Dpi / Dbi * (Rbi - Rfi) + Rfi} 43 | #' @aliases AttributionFixedIncome 44 | #' @param Rp T x n xts, data frame or matrix of portfolio returns 45 | #' @param wp vector, xts, data frame or matrix of portfolio weights 46 | #' @param Rb T x n xts, data frame or matrix of benchmark returns 47 | #' @param wb vector, xts, data frame or matrix of benchmark weights 48 | #' @param Rf T x n xts, data frame or matrix with risk free rates 49 | #' @param Dp T x n xts, data frame or matrix with portfolio modified duration 50 | #' @param Db T x n xts, data frame or matrix with benchmark modified duration 51 | #' @param wbf vector, xts, data frame or matrix with benchmark weights of 52 | #' currency forward contracts 53 | #' @param S (T + 1) x n xts, data frame or matrix with spot rates. The first 54 | #' date should coincide with the first date of portfolio returns 55 | #' @param geometric - TRUE/FALSE for geometric/arithmetic attribution 56 | #' @return list with total excess returns decomposed into allocation, selection 57 | #' (and currency effects) 58 | #' @author Andrii Babii 59 | #' @seealso \code{\link{Attribution.levels}}, 60 | #' \code{\link{Attribution.geometric}} 61 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement 62 | #' and Attribution}. Wiley. 2004. Chapter 7 \cr Van Breukelen, G. \emph{Fixed 63 | #' income attribution}. Journal of Performance Measurement. Sumer. 64 | #' p. 61-68. 2000 \cr 65 | #' @keywords attribution 66 | #' @examples 67 | #' 68 | #' data(attrib) 69 | #' AttributionFixedIncome(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 70 | #' wb = attrib.weights[2, ], Rf = attrib.returns[, 23:32], Dp = attrib.returns[, 63:72], Db = attrib.returns[, 73:82], 71 | #' S = attrib.currency[, 11:20], wbf = attrib.weights[4, ], geometric = FALSE) 72 | #' 73 | #' @export 74 | AttributionFixedIncome <- 75 | function (Rp, wp, Rb, wb, Rf, Dp, Db, S, wbf, geometric = FALSE) 76 | { # @author Andrii Babii 77 | 78 | # DESCRIPTION: 79 | # Function to perform fixed income attribution 80 | 81 | # Inputs: 82 | # Rp xts, data frame or matrix of portfolio returns 83 | # wp vector, xts, data frame or matrix of portfolio weights 84 | # Rb xts, data frame or matrix of benchmark returns 85 | # wb vector, xts, data frame or matrix of benchmark weights 86 | # Rf xts, data frame or matrix of risk-free rate 87 | # Dp T x n xts, data frame or matrix with portfolio modified duration 88 | # Db T x n xts, data frame or matrix with benchmark modified duration 89 | # S xts, data frame or matrix with spot rates 90 | # wbf vector, xts, data frame or matrix with benchmark weights of 91 | # currency forward contracts 92 | 93 | # Outputs: 94 | # This function returns the 95 | 96 | # FUNCTION: 97 | Rf = checkData(Rf) 98 | Rp = checkData(Rp) 99 | Rb = checkData(Rb) 100 | Dp = checkData(Dp) 101 | Db = checkData(Db) 102 | S = checkData(S) 103 | WP = wp # Save original weights in order to avoid double conversion later 104 | WB = wb 105 | WBF = wbf 106 | wp = Weight.transform(wp, Rp) 107 | wb = Weight.transform(wb, Rb) 108 | wbf = Weight.transform(wbf, Rb) 109 | if (ncol(Rb) == 1){ 110 | Rb = matrix(rep(coredata(Rb), ncol(Rp)), nrow(Rp), ncol(Rp)) 111 | } 112 | if (ncol(Rb) != ncol(Rp)){ 113 | stop("Please use benchmark xts that has columns with benchmarks for each 114 | asset or one common benchmark for all assets") 115 | } 116 | if (ncol(Db) == 1){ 117 | Db = matrix(rep(coredata(Db), ncol(Dp)), nrow(Dp), ncol(Dp)) 118 | } 119 | if (ncol(Db) != ncol(Dp)){ 120 | print("Please use benchmark xts that has columns with benchmarks for each 121 | asset or one common benchmark for all assets") 122 | } 123 | if (is.vector(WP) & is.vector(WB) & is.vector(WBF)){ 124 | rp = Return.portfolio(Rp, WP, geometric = geometric) 125 | rb = Return.portfolio(Rb, WB, geometric = geometric) 126 | rf = Return.portfolio(Rf, WP, geometric = geometric) 127 | dp = Return.portfolio(Dp, WP, geometric = geometric) # portfolio duration 128 | db = Return.portfolio(Db, WB, geometric = geometric) # benchmark duration 129 | } else{ 130 | rp = Return.rebalancing(Rp, WP, geometric = geometric) 131 | rb = Return.rebalancing(Rb, WB, geometric = geometric) 132 | rf = Return.rebalancing(Rf, WP, geometric = geometric) 133 | dp = Return.rebalancing(Dp, WP, geometric = geometric) 134 | db = Return.rebalancing(Db, WB, geometric = geometric) 135 | } 136 | names(rp) = "Total" 137 | names(rb) = "Total" 138 | Dbeta = dp / coredata(db) 139 | # Implied benchmark yield changes 140 | DeltaYb = -(Rb - coredata(Rf)) / coredata(Db) 141 | # Implied portfolio yield changes 142 | DeltaYp = -(Rp - coredata(Rf)) / coredata(Dp) 143 | # Implied total benchmark yield changes 144 | deltayb = rep(rb - coredata(rp), ncol(Dp)) / coredata(Dp) 145 | # Currency returns 146 | Rc = lag(S, -1)[1:nrow(Rp), ] / S[1:nrow(Rp), ] - 1 147 | rc = reclass(rowSums((wb + wbf) * (Rc + coredata(Rf))), Rc) 148 | if (!geometric){ 149 | allocation = (Dp * wp - rep(Dbeta, ncol(Dp)) * coredata(Db) * wb) * 150 | coredata(-DeltaYb + deltayb) 151 | selection = Dp * coredata(wp) * coredata(-DeltaYp + coredata(DeltaYb)) 152 | currency = (wp - wb) * (Rc + coredata(Rf) - rep(rc, ncol(Rc))) 153 | excess.returns = rp - coredata(rb) 154 | } else{ 155 | rcprime = rowSums(wb * (Rc + Rf)) 156 | bd = reclass(rowSums(rep(Dbeta, ncol(Db)) * Db * coredata(wb) * 157 | coredata(-DeltaYb)), Db) + rcprime # Overal duration notional fund 158 | allocation = Dp * wp - rep(Dbeta, ncol(Dp)) * coredata(Db) * wb * 159 | coredata(-DeltaYb + deltayb) / rep(bd, ncol(Db)) 160 | selection = Dp / coredata(Db) * coredata(Rb - coredata(Rf)) + Rf 161 | excess.returns = (1 + rp) / (1 + coredata(rb)) - 1 162 | } 163 | 164 | # Get total attribution effects 165 | n = ncol(allocation) # number of segments 166 | allocation = cbind(allocation, rowSums(allocation)) 167 | names(allocation)[n + 1] = "Total" 168 | selection = cbind(selection, rowSums(selection)) 169 | names(selection)[n + 1] = "Total" 170 | 171 | result = list() 172 | result[[1]] = excess.returns 173 | result[[2]] = allocation 174 | result[[3]] = selection 175 | names(result) = c("Excess returns", "Market allocation", "Issue selection") 176 | 177 | if (!geometric){ 178 | currency = cbind(currency, rowSums(currency)) 179 | names(currency)[ncol(currency)] = "Total" 180 | result[[4]] = currency 181 | names(result) = c("Excess returns", "Market allocation", 182 | "Issue selection", "Currency allocation") 183 | } 184 | return(result) 185 | } -------------------------------------------------------------------------------- /R/attribution.levels.R: -------------------------------------------------------------------------------- 1 | #' provides multi-level sector-based geometric attribution 2 | #' 3 | #' Provides multi-level sector-based geometric attribution. The Brinson model 4 | #' attributes excess returns at one level. This function works with more 5 | #' complex decision processes. For instance, the 3-level decision process 6 | #' may have the following levels: type of asset - country - sector. The 7 | #' levels should be specified in the vector with elements in the particular 8 | #' order: from the highest level to the lowest. Returns and weighs for 9 | #' portfolio and benchmark should be at the lowest level (e.g. individual 10 | #' instruments). Benchmark should have the same number of columns as portfolio. 11 | #' That is there should be a benchmark for each instrument in the portfolio 12 | #' (possibly 0). The contribution to the allocation in the \eqn{i^{th}} 13 | #' category for the \eqn{d^{th}} level is: 14 | #' \deqn{\left(^{d}w_{pi}-^{d}w_{bi}\right)\times 15 | #' \left(\frac{1+^{d}R_{bi}}{1+^{d-1}R_{bi}}-1\right) 16 | #' \times\frac{1+^{d-1}R_{bi}}{1+bs^{d-1}}} 17 | #' The total attribution for each asset allocation step in the decision process 18 | #' is: \deqn{\frac{1+^{d}bs}{1+^{d-1}bs}-1} 19 | #' The final step, stock selection, is measured by: 20 | #' \deqn{^{d}w_{pi}\times\left(\frac{1+R_{pi}}{1+^{d}R_{bi}}-1\right) 21 | #' \times\frac{1+^{d}R_{bi}}{1+^{d}bs}} 22 | #' 23 | #' @aliases Attribution.levels 24 | #' @param Rp xts, data frame or matrix of portfolio returns 25 | #' @param wp vector, xts, data frame or matrix of portfolio weights 26 | #' @param Rb xts, data frame or matrix of benchmark returns 27 | #' @param wb vector, xts, data frame or matrix of benchmark weights 28 | #' @param h data.frame with the hierarchy obtained from the buildHierarchy 29 | #' function or defined manually in the same style as buildHierarchy's 30 | #' output 31 | #' @param \dots any other passthrough parameters 32 | #' @return returns the list with geometric excess returns including annualized 33 | #' geometric excess returns, total attribution effects (allocation, selection 34 | #' and total) including total multi-period attribution effects, attribution 35 | #' effects at each level and security selection 36 | #' @author Andrii Babii 37 | #' @seealso \code{\link{Attribution.geometric}} 38 | #' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and 39 | #' Attribution}. Wiley. 2004. p. 215-220 40 | #' @keywords multi-level attribution, geometric attribution 41 | #' @examples 42 | #' 43 | #' data(attrib) 44 | #' Attribution.levels(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 45 | #' wb = attrib.weights[2, ], h = attrib.hierarchy, c("type", "MarketCap", "Sector")) 46 | #' Attribution.levels(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 47 | #' wb = attrib.weights[2, ], h = attrib.hierarchy, c("type", "Sector")) 48 | #' 49 | #' @export 50 | Attribution.levels <- 51 | function(Rp, wp, Rb, wb, h, ...) 52 | { # @author Andrii Babii 53 | 54 | # DESCRIPTION: 55 | # Function to perform the geometric attribution analysis. 56 | 57 | # Inputs: 58 | # Rp xts, data frame or matrix of portfolio returns 59 | # wp vector, xts, data frame or matrix of portfolio weights 60 | # Rb xts, data frame or matrix of benchmark returns 61 | # wb vector, xts, data frame or matrix of benchmark weights 62 | # h data.frame with the hierarchy 63 | 64 | # Outputs: 65 | # This function returns the list with total attribution effects 66 | # (allocation, selection and total) including total multi-period 67 | # attribution effects, attribution effects at each level and security 68 | # selection 69 | 70 | # FUNCTION: 71 | Rp = checkData(Rp) 72 | Rb = checkData(Rb) 73 | colnames(Rb) = colnames(Rp) 74 | WP = wp # Save original weights in order to avoid double conversion later 75 | WB = wb 76 | wp = Weight.transform(wp, Rp) 77 | wb = Weight.transform(wb, Rb) 78 | if (nrow(wp) < nrow(Rp)){ # Rebalancing occurs next day 79 | Rp = Rp[2:nrow(Rp)] 80 | Rb = Rb[2:nrow(Rb)] 81 | } 82 | if (ncol(Rb) == 1){ 83 | Rb = matrix(rep(coredata(Rb), ncol(Rp)), nrow(Rp), ncol(Rp)) 84 | } 85 | if (ncol(Rb) != ncol(Rp)){ 86 | stop("Please use benchmark xts that has columns with benchmarks for each 87 | asset or one common benchmark for all assets") 88 | } 89 | 90 | levels <- unlist(list(...)) 91 | if (!is.null(levels)) stopifnot(is.character(levels)) 92 | if (length(levels) == 1){ 93 | stop("Use Attribution function for the single level. This function is for 94 | the multi-level attribution") 95 | } 96 | 97 | # Get portfolio and benchmark returns 98 | if (is.vector(WP) & is.vector(WB)){ 99 | rp = Return.portfolio(Rp, WP) 100 | rb = Return.portfolio(Rb, WB) 101 | } else{ 102 | rp = Return.rebalancing(Rp, WP) 103 | rb = Return.rebalancing(Rb, WB) 104 | } 105 | names(rp) = "Total" 106 | names(rb) = "Total" 107 | 108 | # Geometric excess returns + annualized geometric excess returns 109 | excess.returns = (1 + rp) / (1 + coredata(rb)) - 1 110 | if (nrow(rp) > 1){ 111 | er = Return.annualized.excess(rp, rb) 112 | excess.returns = rbind(as.matrix(excess.returns), er) 113 | } 114 | colnames(excess.returns) = "Geometric" 115 | 116 | # Transform the hierarchy to the correct form 117 | for (i in 2:length(levels)){ 118 | if (is.numeric(h[[levels[i]]])){ 119 | h = HierarchyQuintiles(h, levels[i]) 120 | } 121 | h[[levels[i]]] = paste(h[[levels[i - 1]]], h[[levels[i]]], sep = "-") 122 | } 123 | 124 | # Get returns and weights at all levels 125 | returns.p = list() 126 | weights.p = list() 127 | returns.b = list() 128 | weights.b = list() 129 | bs = list() 130 | for(i in 1:length(levels)){ 131 | returns.p[[i]] = Return.level(Rp, WP, h, level = levels[i]) 132 | weights.p[[i]] = Weight.level(WP, Rp, h, level = levels[i]) 133 | returns.b[[i]] = Return.level(Rb, WB, h, level = levels[i]) 134 | weights.b[[i]] = Weight.level(WB, Rp, h, level = levels[i]) 135 | # semi-notional funds returns 136 | bs[[i]] = reclass(rowSums(returns.b[[i]] * weights.p[[i]]), rp) 137 | } 138 | names(returns.p) = levels 139 | names(weights.p) = levels 140 | names(returns.b) = levels 141 | names(weights.b) = levels 142 | 143 | # Total attribution effects 144 | allocation = matrix(rep(NA, nrow(Rp) * length(levels)), nrow(Rp), 145 | length(levels)) 146 | allocation[, 1] = (1 + bs[[1]]) / coredata(1 + rb) - 1 # Allocation 1 147 | for (i in 2:length(levels)){ 148 | allocation[, i] = (1 + bs[[i]]) / (1 + bs[[i-1]]) - 1 149 | } 150 | selection = (1 + rp) / (1 + last(bs)[[1]]) - 1 151 | total = (1 + rp) / coredata(1 + rb) - 1 # Total excess return 152 | 153 | # Transform portfolio, benchmark returns and semi-notional funds returns to 154 | # conformable matrices for multi-level attribution 155 | b = as.xts(matrix(rep(rb, ncol(returns.b[[1]])), nrow(rb), 156 | ncol(returns.b[[1]])), index(rb)) 157 | r = as.xts(matrix(rep(rp, ncol(last(returns.b)[[1]])), nrow(rp), 158 | ncol(last(returns.b)[[1]])), index(rp)) 159 | 160 | returns.b2 = list() 161 | for (j in 1:(length(levels) - 1)){ 162 | # make benchmark returns conformable at different levels 163 | r_l = Return.level(Rb, WB, h, level = levels[j]) 164 | r_h = Return.level(Rb, WB, h, level = levels[j + 1]) 165 | hierarchy = split(h[levels[j]], h[levels[j + 1]]) 166 | for (i in 1:ncol(r_h)){ 167 | r_h[, i] = r_l[, hierarchy[[i]][1, 1]] 168 | } 169 | returns.b2[[j]] = r_h 170 | } 171 | 172 | for (i in 1:(length(bs) - 1)){ 173 | bs[[i]] = as.xts(matrix(rep(bs[[i]], ncol(returns.b2[[i]])), nrow(r), 174 | ncol(returns.b2[[i]])), index(r)) 175 | } 176 | bs[length(bs)] = bs[length(bs) - 1] 177 | 178 | # Attribution at each level 179 | level = list() 180 | level[[1]] = (weights.p[[1]] - weights.b[[1]]) * ((1 + returns.b[[1]]) 181 | / (1 + b) - 1) 182 | for (i in 2:length(levels)){ 183 | level[[i]] = (weights.p[[i]] - weights.b[[i]]) * 184 | ((1 + returns.b[[i]]) / (1 + returns.b2[[i-1]]) - 1) * 185 | ((1 + returns.b2[[i-1]]) / (1 + bs[[i-1]])) 186 | } 187 | 188 | # Security/Asset selection 189 | select = reclass(weights.p[[length(weights.p)]], rp) * 190 | ((1 + r) / (1 + returns.b[[length(returns.b)]]) - 1) * 191 | ((1 + returns.b[[length(returns.b)]]) / (1 + bs[[length(bs)]])) 192 | # Get the multi-period summary 193 | general = cbind(allocation, selection) 194 | general = rbind(as.data.frame(general), (apply(1 + general, 2, prod) - 1)) 195 | for (i in 1:length(level)){ 196 | level[[i]] = rbind(as.data.frame(level[[i]]), 197 | (apply(1 + level[[i]], 2, prod) - 1)) 198 | rownames(level[[i]])[nrow(level[[i]])] = "Total" 199 | } 200 | select = rbind(as.data.frame(select), (apply(1 + select, 2, prod) - 1)) 201 | rownames(general)[nrow(general)] = "Total" 202 | rownames(select)[nrow(select)] = "Total" 203 | 204 | # Label the output 205 | result = list() 206 | labels = paste(rep("Level", length(levels)), 1:length(levels)) 207 | names(level) = labels 208 | colnames(general) = c(paste(labels, (rep("Allocation", 209 | length(levels)))), "Selection") 210 | 211 | result[[1]] = excess.returns 212 | result[[2]] = general 213 | result[[3]] = level 214 | result[[4]] = select 215 | names(result) = c("Excess returns", "Multi-level attribution", 216 | "Attribution at each level", "Security selection") 217 | return(result) 218 | } -------------------------------------------------------------------------------- /man/Attribution.Rd: -------------------------------------------------------------------------------- 1 | \name{Attribution} 2 | \alias{Attribution} 3 | \title{performs sector-based single-level attribution} 4 | \usage{ 5 | Attribution(Rp, wp, Rb, wb, wpf = NA, wbf = NA, S = NA, 6 | F = NA, Rpl = NA, Rbl = NA, Rbh = NA, bf = FALSE, 7 | method = c("none", "top.down", "bottom.up"), 8 | linking = c("carino", "menchero", "grap", "frongello", "davies.laker"), 9 | geometric = FALSE, adjusted = FALSE) 10 | } 11 | \arguments{ 12 | \item{Rp}{T x n xts, data frame or matrix of portfolio 13 | returns} 14 | 15 | \item{wp}{vector, xts, data frame or matrix of portfolio 16 | weights} 17 | 18 | \item{Rb}{T x n xts, data frame or matrix of benchmark 19 | returns} 20 | 21 | \item{wb}{vector, xts, data frame or matrix of benchmark 22 | weights} 23 | 24 | \item{method}{Used to select the priority between 25 | allocation and selection effects in arithmetic 26 | attribution. May be any of: \itemize{ \item none - 27 | present allocation, selection and interaction effects 28 | independently, \item top.down - the priority is given to 29 | the sector allocation. Interaction term is combined with 30 | the security selection effect, \item bottom.up - the 31 | priority is given to the security selection. Interaction 32 | term is combined with the sector allocation effect} By 33 | default "none" is selected} 34 | 35 | \item{wpf}{vector, xts, data frame or matrix with 36 | portfolio weights of currency forward contracts} 37 | 38 | \item{wbf}{vector, xts, data frame or matrix with 39 | benchmark weights of currency forward contracts} 40 | 41 | \item{S}{(T+1) x n xts, data frame or matrix with spot 42 | rates. The first date should coincide with the first date 43 | of portfolio returns} 44 | 45 | \item{F}{(T+1) x n xts, data frame or matrix with forward 46 | rates. The first date should coincide with the first date 47 | of portfolio returns} 48 | 49 | \item{Rpl}{xts, data frame or matrix of portfolio returns 50 | in local currency} 51 | 52 | \item{Rbl}{xts, data frame or matrix of benchmark returns 53 | in local currency} 54 | 55 | \item{Rbh}{xts, data frame or matrix of benchmark returns 56 | hedged into the base currency} 57 | 58 | \item{bf}{TRUE for Brinson and Fachler and FALSE for 59 | Brinson, Hood and Beebower arithmetic attribution. By 60 | default Brinson, Hood and Beebower attribution is 61 | selected} 62 | 63 | \item{linking}{Used to select the linking method to 64 | present the multi-period summary of arithmetic 65 | attribution effects. May be any of: \itemize{\item carino 66 | - logarithmic linking coefficient method \item menchero - 67 | Menchero's smoothing algorithm \item grap - linking 68 | approach developed by GRAP \item frongello - Frongello's 69 | linking method \item davies.laker - Davies and Laker's 70 | linking method} By default Carino linking is selected} 71 | 72 | \item{geometric}{TRUE/FALSE, whether to use geometric or 73 | arithmetic excess returns for the attribution analysis. 74 | By default arithmetic is selected} 75 | 76 | \item{adjusted}{TRUE/FALSE, whether to show original or 77 | smoothed attribution effects for each period. By default 78 | unadjusted attribution effects are returned} 79 | } 80 | \value{ 81 | returns a list with the following components: excess 82 | returns with annualized excess returns over all periods, 83 | attribution effects (allocation, selection and 84 | interaction) 85 | } 86 | \description{ 87 | Performs sector-based single-level attribution analysis. 88 | Portfolio performance measured relative to a benchmark 89 | gives an indication of the value-added by the portfolio. 90 | Equipped with weights and returns of portfolio segments, 91 | we can dissect the value-added into useful components. 92 | This function is based on the sector-based approach to 93 | the attribution. The workhorse is the Brinson model that 94 | explains the arithmetic difference between portfolio and 95 | benchmark returns. That is it breaks down the arithmetic 96 | excess returns at one level. If returns and weights are 97 | available at the lowest level (e.g. for individual 98 | instruments), the aggregation up to the chosen level from 99 | the hierarchy can be done using 100 | \code{\link{Return.level}} function. The attribution 101 | effects can be computed for several periods. The 102 | multi-period summary is obtained using one of linking 103 | methods: Carino, Menchero, GRAP, Frongello or Davies 104 | Laker. It also allows to break down the geometric excess 105 | returns, which link naturally over time. Finally, it 106 | annualizes arithmetic and geometric excess returns 107 | similarly to the portfolio and/or benchmark returns 108 | annualization. 109 | } 110 | \details{ 111 | The arithmetic excess returns are decomposed into the sum 112 | of allocation, selection and interaction effects across 113 | \eqn{n} sectors: 114 | \deqn{R_{p}-R_{b}=\sum^{n}_{i=1}\left(A_{i}+S_{i}+I_{i}\right)} 115 | The arithmetic attribution effects for the category i are 116 | computed as suggested in the Brinson, Hood and Beebower 117 | (1986): Allocation effect 118 | \deqn{A_{i}=(w_{pi}-w_{bi})\times R_{bi}}{Ai = (wpi - 119 | wbi) * Rbi} Selection effect 120 | \deqn{S_{i}=w_{pi}\times(R_{pi}-R_{bi})}{Si = wpi * (Rpi 121 | - Rbi)} Interaction effect \deqn{I_{i}=(w_{pi}-w_{bi}) 122 | \times(R_{pi}-R_{bi})}{Ii = (wpi - wbi) * Rpi - Rbi} 123 | \eqn{R_{p}}{Rp} - total portfolio returns, 124 | \eqn{R_{b}}{Rb} - total benchmark returns, 125 | \eqn{w_{pi}}{wpi} - weights of the category \eqn{i} in 126 | the portfolio, \eqn{w_{bi}}{wbi} - weights of the 127 | category \eqn{i} in the benchmark, \eqn{R_{pi}}{Rpi} - 128 | returns of the portfolio category \eqn{i}, 129 | \eqn{R_{bi}}{Rbi} - returns of the benchmark category 130 | \eqn{i}. If Brinson and Fachler (1985) is selected the 131 | allocation effect differs: \deqn{A_{i}=(w_{pi}-w_{bi}) 132 | \times (R_{bi} - R_{b})}{Ai = (wpi - wbi) * (Rbi - Rb)} 133 | Depending on goals we can give priority to the allocation 134 | or to the selection effects. If the priority is given to 135 | the sector allocation the interaction term will be 136 | combined with the security selection effect (top-down 137 | approach). If the priority is given to the security 138 | selection, the interaction term will be combined with the 139 | asset-allocation effect (bottom-up approach). Usually we 140 | have more than one period. In that case individual 141 | arithmetic attribution effects should be adjusted using 142 | linking methods. Adjusted arithmetic attribution effects 143 | can be summed up over time to provide the multi-period 144 | summary: 145 | \deqn{R_{p}-R_{b}=\sum^{T}_{t=1}\left(A_{t}'+S_{t}'+I_{t}'\right)} 146 | where \eqn{T} is the number of periods and prime stands 147 | for the adjustment. The geometric attribution effects do 148 | not suffer from the linking problem. Moreover we don't 149 | have the interaction term. For more details about the 150 | geometric attribution see the documentation to 151 | \code{\link{Attribution.geometric}}. Finally, arithmetic 152 | annualized excess returns are computed as the arithmetic 153 | difference between annualised portfolio and benchmark 154 | returns: \deqn{AAER=r_{a}-b_{a}}{AAER = ra - ba} the 155 | geometric annualized excess returns are computed as the 156 | geometric difference between annualized portfolio and 157 | benchmark returns: 158 | \deqn{GAER=\frac{1+r_{a}}{1+b_{a}}-1}{GAER = (1 + ra) / 159 | (1 + ba) - 1} In the case of multi-currency portfolio, 160 | the currency return, currency surprise and forward 161 | premium should be specified. The multi-currency 162 | arithmetic attribution is handled following Ankrim and 163 | Hensel (1992). Currency returns are decomposed into the 164 | sum of the currency surprise and the forward premium: 165 | \deqn{R_{ci} = R_{cei} + R_{fpi}}{Rci = Rcei + Rfpi} 166 | where \deqn{R_{cei} = \frac{S_{i}^{t+1} - 167 | F_{i}^{t+1}}{S_{i}^{t}}} \deqn{R_{fpi} = 168 | \frac{F_{i}^{t+1}}{S_{i}^{t}} - 1} \eqn{S_{i}^{t}}{Sit} - 169 | spot rate for asset \eqn{i} at time \eqn{t} 170 | \eqn{F_{i}^{t}}{Fit} - forward rate for asset \eqn{i} at 171 | time \eqn{t}. Excess returns are decomposed into the sum 172 | of allocation, selection and interaction effects as in 173 | the standard Brinson model: 174 | \deqn{R_{p}-R_{b}=\sum^{n}_{i=1}\left(A_{i}+S_{i}+I_{i}\right)} 175 | However the allocation effect is computed taking into 176 | account currency effects: 177 | \deqn{A_{i}=(w_{pi}-w_{bi})\times (R_{bi} - R_{ci} - 178 | R_{l})}{Ai = (wpi - wbi) * (Rbi - Rci - Rl)} Benchmark 179 | returns adjusted to the currency: \deqn{R_{l} = 180 | \sum^{n}_{i=1}w_{bi}\times(R_{bi}-R_{ci})} The 181 | contribution from the currency is analogous to asset 182 | allocation: \deqn{C_{i} = (w_{pi} - w_{bi}) \times 183 | (R_{cei} - e) + (w_{pfi} - w_{bfi}) \times (R_{fi} - e)} 184 | where \deqn{e = \sum^{n}_{i=1}w_{bi}\times R_{cei}} The 185 | final term, forward premium, is also analogous to the 186 | asset allocation: \deqn{R_{fi} = (w_{pi} - w_{bi}) \times 187 | (R_{fpi} - d)}{Rfi = (wpi - wbi) * (Rfpi - d)} where 188 | \deqn{d = \sum^{n}_{i=1}w_{bi}\times R_{fpi}} and 189 | \eqn{R_{fpi}} - forward premium In general if the intent 190 | is to estimate statistical parameters, the arithmetic 191 | excess return is preferred. However, due to the linking 192 | challenges, it may be preferable to use geometric excess 193 | return if the intent is to link and annualize excess 194 | returns. 195 | } 196 | \examples{ 197 | data(attrib) 198 | Attribution(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 199 | wb = attrib.weights[2, ], method = "top.down", linking = "carino") 200 | } 201 | \author{ 202 | Andrii Babii 203 | } 204 | \references{ 205 | Ankrim, E. and Hensel, C. \emph{Multi-currency 206 | performance attribution}. Russell Research Commentary. 207 | November 2002 \cr Bacon, C. \emph{Practical Portfolio 208 | Performance Measurement and Attribution}. Wiley. 2004. 209 | Chapter 5, 6, 8 \cr Christopherson, Jon A., Carino, David 210 | R., Ferson, Wayne E. \emph{Portfolio Performance 211 | Measurement and Benchmarking}. McGraw-Hill. 2009. Chapter 212 | 18-19 \cr Brinson, G. and Fachler, N. (1985) 213 | \emph{Measuring non-US equity portfolio performance}. 214 | Journal of Portfolio Management. Spring. p. 73 -76. \cr 215 | Gary P. Brinson, L. Randolph Hood, and Gilbert L. 216 | Beebower, \emph{Determinants of Portfolio Performance}. 217 | Financial Analysts Journal. vol. 42, no. 4, July/August 218 | 1986, p. 39-44 \cr Karnosky, D. and Singer, B. 219 | \emph{Global asset management and performance 220 | attribution. The Research Foundation of the Institute of 221 | Chartered Financial Analysts}. February 1994. \cr 222 | } 223 | \seealso{ 224 | \code{\link{Attribution.levels}}, 225 | \code{\link{Attribution.geometric}} 226 | } 227 | \keyword{attribution} 228 | 229 | -------------------------------------------------------------------------------- /R/attribution.R: -------------------------------------------------------------------------------- 1 | #' performs sector-based single-level attribution 2 | #' 3 | #' Performs sector-based single-level attribution analysis. Portfolio 4 | #' performance measured relative to a benchmark gives an indication of the 5 | #' value-added by the portfolio. Equipped with weights and returns of portfolio 6 | #' segments, we can dissect the value-added into useful components. This 7 | #' function is based on the sector-based approach to the attribution. The 8 | #' workhorse is the Brinson model that explains the arithmetic difference 9 | #' between portfolio and benchmark returns. That is it breaks down the 10 | #' arithmetic excess returns at one level. If returns and weights are available 11 | #' at the lowest level (e.g. for individual instruments), the aggregation up to 12 | #' the chosen level from the hierarchy can be done using 13 | #' \code{\link{Return.level}} function. The attribution effects can be computed 14 | #' for several periods. The multi-period summary is obtained using one of 15 | #' linking methods: Carino, Menchero, GRAP, Frongello or Davies Laker. It also 16 | #' allows to break down the geometric excess returns, which link naturally over 17 | #' time. Finally, it annualizes arithmetic and geometric excess returns 18 | #' similarly to the portfolio and/or benchmark returns annualization. 19 | #' 20 | #' The arithmetic excess returns are decomposed into the sum of allocation, 21 | #' selection and interaction effects across \eqn{n} sectors: 22 | #' \deqn{R_{p}-R_{b}=\sum^{n}_{i=1}\left(A_{i}+S_{i}+I_{i}\right)} 23 | #' The arithmetic attribution effects for the category i are computed 24 | #' as suggested in the Brinson, Hood and Beebower (1986): 25 | #' Allocation effect 26 | #' \deqn{A_{i}=(w_{pi}-w_{bi})\times R_{bi}}{Ai = (wpi - wbi) * Rbi} 27 | #' Selection effect 28 | #' \deqn{S_{i}=w_{pi}\times(R_{pi}-R_{bi})}{Si = wpi * (Rpi - Rbi)} 29 | #' Interaction effect 30 | #' \deqn{I_{i}=(w_{pi}-w_{bi}) 31 | #' \times(R_{pi}-R_{bi})}{Ii = (wpi - wbi) * Rpi - Rbi} 32 | #' \eqn{R_{p}}{Rp} - total portfolio returns, 33 | #' \eqn{R_{b}}{Rb} - total benchmark returns, 34 | #' \eqn{w_{pi}}{wpi} - weights of the category \eqn{i} in the portfolio, 35 | #' \eqn{w_{bi}}{wbi} - weights of the category \eqn{i} in the benchmark, 36 | #' \eqn{R_{pi}}{Rpi} - returns of the portfolio category \eqn{i}, 37 | #' \eqn{R_{bi}}{Rbi} - returns of the benchmark category \eqn{i}. 38 | #' If Brinson and Fachler (1985) is selected the allocation effect differs: 39 | #' \deqn{A_{i}=(w_{pi}-w_{bi}) 40 | #' \times (R_{bi} - R_{b})}{Ai = (wpi - wbi) * (Rbi - Rb)} 41 | #' Depending on goals we can give priority to the allocation or to 42 | #' the selection effects. If the priority is given to the sector allocation 43 | #' the interaction term will be combined with the security selection effect 44 | #' (top-down approach). If the priority is given to the security selection, 45 | #' the interaction term will be combined with the asset-allocation effect 46 | #' (bottom-up approach). 47 | #' Usually we have more than one period. In that case individual arithmetic 48 | #' attribution effects should be adjusted using linking methods. Adjusted 49 | #' arithmetic attribution effects can be summed up over time to provide the 50 | #' multi-period summary: 51 | #' \deqn{R_{p}-R_{b}=\sum^{T}_{t=1}\left(A_{t}'+S_{t}'+I_{t}'\right)} 52 | #' where \eqn{T} is the number of periods and prime stands for the adjustment. 53 | #' The geometric attribution effects do not suffer from the linking problem. 54 | #' Moreover we don't have the interaction term. For more details about the 55 | #' geometric attribution see the documentation to 56 | #' \code{\link{Attribution.geometric}}. Finally, arithmetic annualized excess 57 | #' returns are computed as the arithmetic difference between annualised 58 | #' portfolio and benchmark returns: 59 | #' \deqn{AAER=r_{a}-b_{a}}{AAER = ra - ba} the geometric annualized excess 60 | #' returns are computed as the geometric difference between annualized 61 | #' portfolio and benchmark returns: 62 | #' \deqn{GAER=\frac{1+r_{a}}{1+b_{a}}-1}{GAER = (1 + ra) / (1 + ba) - 1} 63 | #' In the case of multi-currency portfolio, the currency return, currency 64 | #' surprise and forward premium should be specified. The multi-currency 65 | #' arithmetic attribution is handled following Ankrim and Hensel (1992). 66 | #' Currency returns are decomposed into the sum of the currency surprise and 67 | #' the forward premium: \deqn{R_{ci} = R_{cei} + R_{fpi}}{Rci = Rcei + Rfpi} 68 | #' where 69 | #' \deqn{R_{cei} = \frac{S_{i}^{t+1} - F_{i}^{t+1}}{S_{i}^{t}}} 70 | #' \deqn{R_{fpi} = \frac{F_{i}^{t+1}}{S_{i}^{t}} - 1} 71 | #' \eqn{S_{i}^{t}}{Sit} - spot rate for asset \eqn{i} at time \eqn{t} 72 | #' \eqn{F_{i}^{t}}{Fit} - forward rate for asset \eqn{i} at time \eqn{t}. 73 | #' Excess returns are decomposed into the sum of allocation, selection and 74 | #' interaction effects as in the standard Brinson model: 75 | #' \deqn{R_{p}-R_{b}=\sum^{n}_{i=1}\left(A_{i}+S_{i}+I_{i}\right)} 76 | #' However the allocation effect is computed taking into account currency 77 | #' effects: 78 | #' \deqn{A_{i}=(w_{pi}-w_{bi})\times (R_{bi} - R_{ci} - R_{l})}{Ai = 79 | #' (wpi - wbi) * (Rbi - Rci - Rl)} 80 | #' Benchmark returns adjusted to the currency: 81 | #' \deqn{R_{l} = \sum^{n}_{i=1}w_{bi}\times(R_{bi}-R_{ci})} 82 | #' The contribution from the currency is analogous to asset allocation: 83 | #' \deqn{C_{i} = (w_{pi} - w_{bi}) \times (R_{cei} - e) + (w_{pfi} - w_{bfi}) 84 | #' \times (R_{fi} - e)} 85 | #' where \deqn{e = \sum^{n}_{i=1}w_{bi}\times R_{cei}} 86 | #' The final term, forward premium, is also analogous to the asset allocation: 87 | #' \deqn{R_{fi} = (w_{pi} - w_{bi}) \times (R_{fpi} - d)}{Rfi = (wpi - wbi) * 88 | #' (Rfpi - d)} 89 | #' where \deqn{d = \sum^{n}_{i=1}w_{bi}\times R_{fpi}} 90 | #' and \eqn{R_{fpi}} - forward premium 91 | #' In general if the intent is to estimate statistical parameters, the 92 | #' arithmetic excess return is preferred. However, due to the linking 93 | #' challenges, it may be preferable to use geometric excess return if the 94 | #' intent is to link and annualize excess returns. 95 | #' 96 | #' @aliases Attribution 97 | #' @param Rp T x n xts, data frame or matrix of portfolio returns 98 | #' @param wp vector, xts, data frame or matrix of portfolio weights 99 | #' @param Rb T x n xts, data frame or matrix of benchmark returns 100 | #' @param wb vector, xts, data frame or matrix of benchmark weights 101 | #' @param method Used to select the priority between allocation and selection 102 | #' effects in arithmetic attribution. May be any of: \itemize{ \item none - 103 | #' present allocation, selection and interaction effects independently, 104 | #' \item top.down - the priority is given to the sector allocation. Interaction 105 | #' term is combined with the security selection effect, \item bottom.up - the 106 | #' priority is given to the security selection. Interaction term is combined 107 | #' with the sector allocation effect} 108 | #' By default "none" is selected 109 | #' @param wpf vector, xts, data frame or matrix with portfolio weights of 110 | #' currency forward contracts 111 | #' @param wbf vector, xts, data frame or matrix with benchmark weights of 112 | #' currency forward contracts 113 | #' @param S (T+1) x n xts, data frame or matrix with spot rates. The first date 114 | #' should coincide with the first date of portfolio returns 115 | #' @param F (T+1) x n xts, data frame or matrix with forward rates. The first 116 | #' date should coincide with the first date of portfolio returns 117 | #' @param Rpl xts, data frame or matrix of portfolio returns in local currency 118 | #' @param Rbl xts, data frame or matrix of benchmark returns in local currency 119 | #' @param Rbh xts, data frame or matrix of benchmark returns hedged into the 120 | #' base currency 121 | #' @param bf TRUE for Brinson and Fachler and FALSE for Brinson, Hood and 122 | #' Beebower arithmetic attribution. By default Brinson, Hood and Beebower 123 | #' attribution is selected 124 | #' @param linking Used to select the linking method to present the multi-period 125 | #' summary of arithmetic attribution effects. May be any of: 126 | #' \itemize{\item carino - logarithmic linking coefficient method 127 | #' \item menchero - Menchero's smoothing algorithm 128 | #' \item grap - linking approach developed by GRAP 129 | #' \item frongello - Frongello's linking method 130 | #' \item davies.laker - Davies and Laker's linking method} 131 | #' By default Carino linking is selected 132 | #' @param geometric TRUE/FALSE, whether to use geometric or arithmetic excess 133 | #' returns for the attribution analysis. By default arithmetic is selected 134 | #' @param adjusted TRUE/FALSE, whether to show original or smoothed attribution 135 | #' effects for each period. By default unadjusted attribution effects are 136 | #' returned 137 | #' @return returns a list with the following components: excess returns with 138 | #' annualized excess returns over all periods, attribution effects (allocation, 139 | #' selection and interaction) 140 | #' @author Andrii Babii 141 | #' @seealso \code{\link{Attribution.levels}}, 142 | #' \code{\link{Attribution.geometric}} 143 | #' @references Ankrim, E. and Hensel, C. \emph{Multi-currency performance 144 | #' attribution}. Russell Research Commentary. November 2002 \cr Bacon, C. 145 | #' \emph{Practical Portfolio Performance Measurement and Attribution}. Wiley. 146 | #' 2004. Chapter 5, 6, 8 \cr Christopherson, Jon A., Carino, David R., Ferson, 147 | #' Wayne E. \emph{Portfolio Performance Measurement and Benchmarking}. 148 | #' McGraw-Hill. 2009. Chapter 18-19 \cr Brinson, G. and Fachler, N. (1985) 149 | #' \emph{Measuring non-US equity portfolio performance}. Journal of Portfolio 150 | #' Management. Spring. p. 73 -76. \cr Gary P. Brinson, L. Randolph Hood, and 151 | #' Gilbert L. Beebower, \emph{Determinants of Portfolio Performance}. Financial 152 | #' Analysts Journal. vol. 42, no. 4, July/August 1986, p. 39-44 \cr 153 | #' Karnosky, D. and Singer, B. \emph{Global asset management and performance 154 | #' attribution. The Research Foundation of the Institute of Chartered Financial 155 | #' Analysts}. February 1994. \cr 156 | #' @keywords attribution 157 | #' @examples 158 | #' 159 | #' data(attrib) 160 | #' Attribution(Rp = attrib.returns[, 1:10], wp = attrib.weights[1, ], Rb = attrib.returns[, 11:20], 161 | #' wb = attrib.weights[2, ], method = "top.down", linking = "carino") 162 | #' 163 | #' @export 164 | Attribution <- 165 | function (Rp, wp, Rb, wb, 166 | wpf = NA, wbf = NA, S = NA, F = NA, Rpl = NA, Rbl = NA, Rbh = NA, 167 | bf = FALSE, 168 | method = c("none", "top.down", "bottom.up"), 169 | linking = c("carino", 170 | "menchero", 171 | "grap", 172 | "frongello", 173 | "davies.laker"), 174 | geometric = FALSE, adjusted = FALSE) 175 | { # @author Andrii Babii 176 | 177 | # DESCRIPTION: 178 | # Function to perform the attribution analysis. 179 | 180 | # Inputs: 181 | # Rp T x n xts, data frame or matrix of portfolio returns 182 | # wp vector, xts, data frame or matrix of portfolio weights 183 | # Rb T x n xts, data frame or matrix of benchmark returns 184 | # wb vector, xts, data frame or matrix of benchmark weights 185 | # wpf vector, xts, data frame or matrix with portfolio weights of 186 | # currency forward contracts 187 | # wbf vector, xts, data frame or matrix with benchmark weights of 188 | # currency forward contracts 189 | # S (T+1) x n xts, data frame or matrix with spot rates 190 | # F (T+1) x n xts, data frame or matrix with forward rates 191 | # Rpl xts, data frame or matrix of portfolio returns in local currency 192 | # Rbl xts, data frame or matrix of benchmark returns in local currency 193 | # Rbh xts, data frame or matrix of benchmark returns hedged into the 194 | # base currency 195 | 196 | # Outputs: 197 | # This function returns the attribution effects with multi-period summary 198 | # and annualized excess returns 199 | 200 | # FUNCTION: 201 | # Transform data to the xts objects 202 | Rb = checkData(Rb) 203 | Rp = checkData(Rp) 204 | WP = wp # Save original weights in order to avoid double conversion later 205 | WB = wb 206 | wp = Weight.transform(wp, Rp) 207 | wb = Weight.transform(wb, Rb) 208 | if (nrow(wp) < nrow(Rp)){ # Rebalancing occurs next day 209 | Rp = Rp[2:nrow(Rp)] 210 | Rb = Rb[2:nrow(Rb)] 211 | } 212 | if (ncol(Rb) == 1){ 213 | Rb = matrix(rep(coredata(Rb), ncol(Rp)), nrow(Rp), ncol(Rp)) 214 | } 215 | if (ncol(Rb) != ncol(Rp)){ 216 | stop("Please use benchmark xts that has columns with benchmarks for each 217 | asset or one common benchmark for all assets") 218 | } 219 | method = method[1] 220 | linking = linking[1] 221 | 222 | currency = !(is.null(dim(wpf)) & is.null(dim(wbf)) & 223 | is.null(dim(S)) & is.null(dim(F)) & 224 | is.null(dim(Rpl)) & is.null(dim(Rpl)) & 225 | is.null(dim(Rpl))) 226 | 227 | if (geometric == FALSE & linking != "davies.laker"){ 228 | # The function makes all computations for the arithmetic attribution 229 | # case (except for Davies and Laker linking) 230 | 231 | # Compute attribution effects (Brinson, Hood and Beebower model) 232 | # If portfolio is single-currency 233 | if (!currency){ 234 | Rc = 0 235 | L = 0 236 | } else{ # If multi-currency portfolio 237 | S = checkData(S) 238 | F = checkData(F) 239 | wpf = Weight.transform(wpf, Rp) 240 | wbf = Weight.transform(wbf, Rb) 241 | 242 | Rc = lag(S, -1)[1:nrow(Rp), ] / S[1:nrow(Rp), ] - 1 243 | Rd = lag(F, -1)[1:nrow(Rp), ] / S[1:nrow(Rp), ] - 1 244 | Re = Rc - coredata(Rd) 245 | Rl = Rb - coredata(Rc) 246 | Rk = Rp - coredata(Rc) 247 | Rfp = Re / (1 + Rd) 248 | E = reclass(matrix(rep(rowSums(Re * coredata(wb)), ncol(Rb)), nrow(Rb), 249 | ncol(Rb)), Rp) 250 | L = reclass(matrix(rep(rowSums(Rl * coredata(wb)), ncol(Rb)), nrow(Rb), 251 | ncol(Rb)), Rp) 252 | D = reclass(matrix(rep(rowSums(Rd * coredata(wb)), ncol(Rb)), nrow(Rb), 253 | ncol(Rb)), Rp) 254 | # Contribution to currency 255 | Cc = (wp - wb) * (Re - E) + (wpf - wbf) * (Rfp - E) 256 | # Forward premium 257 | Df = (wp - wb) * (Rd - D) 258 | Cc = cbind(Cc, rowSums(Cc)) 259 | Df = cbind(Df, rowSums(Df)) 260 | colnames(Cc) = c(colnames(S), "Total") 261 | colnames(Df) = colnames(Cc) 262 | } 263 | 264 | # Get total portfolio returns 265 | if (is.vector(WP) & is.vector(WB)){ 266 | rp = Return.portfolio(Rp, WP, geometric = FALSE) 267 | rb = Return.portfolio(Rb, WB, geometric = FALSE) 268 | } else{ 269 | rp = Return.rebalancing(Rp, WP, geometric = FALSE) 270 | rb = Return.rebalancing(Rb, WB, geometric = FALSE) 271 | } 272 | names(rp) = "Total" 273 | names(rb) = "Total" 274 | 275 | # Get individual attribution effects 276 | if (bf == TRUE){ # Brinson and Fachler (1985) allocation effect 277 | allocation = coredata(wp - wb) * (Rb - coredata(Rc) - coredata(L) - 278 | rep(rb, ncol(Rb))) 279 | } else{ # Brinson, Hood and Beebower (1986) allocation effect 280 | allocation = coredata(wp - wb) * (Rb - coredata(Rc) - coredata(L)) 281 | } 282 | 283 | selection = (Rp - coredata(Rb)) * wb 284 | interaction = (wp - wb) * (Rp - coredata(Rb)) 285 | 286 | # Get total attribution effects 287 | n = ncol(allocation) # number of segments 288 | allocation = cbind(allocation, rowSums(allocation)) 289 | names(allocation)[n + 1] = "Total" 290 | selection = cbind(selection, rowSums(selection)) 291 | names(selection)[n + 1] = "Total" 292 | interaction = cbind(interaction, rowSums(interaction)) 293 | names(interaction)[n + 1] = "Total" 294 | 295 | # Adjust attribution effects using one of linking methods if there are 296 | # mutliple periods 297 | if (nrow(allocation) > 1){ 298 | if (linking == "carino"){ 299 | allocation = Carino(rp, rb, allocation, adjusted) 300 | selection = Carino(rp, rb, selection, adjusted) 301 | interaction = Carino(rp, rb, interaction, adjusted) 302 | } 303 | 304 | if (linking == "menchero"){ 305 | allocation = Menchero(rp, rb, allocation, adjusted) 306 | selection = Menchero(rp, rb, selection, adjusted) 307 | interaction = Menchero(rp, rb, interaction, adjusted) 308 | } 309 | 310 | if (linking == "grap"){ 311 | allocation = Grap(rp, rb, allocation, adjusted) 312 | selection = Grap(rp, rb, selection, adjusted) 313 | interaction = Grap(rp, rb, interaction, adjusted) 314 | } 315 | 316 | if (linking == "frongello"){ 317 | allocation = Frongello(rp, rb, allocation, adjusted) 318 | selection = Frongello(rp, rb, selection, adjusted) 319 | interaction = Frongello(rp, rb, interaction, adjusted) 320 | } 321 | } 322 | # Arithmetic excess returns + annualized arithmetic excess returns 323 | excess.returns = rp - coredata(rb) 324 | if (nrow(rp) > 1){ 325 | er = Return.annualized.excess(rp, rb, geometric = FALSE) 326 | excess.returns = rbind(as.matrix(excess.returns), er) 327 | } 328 | colnames(excess.returns) = "Arithmetic" 329 | 330 | # Select the appropriate result corresponding to the chosen method 331 | result = list() 332 | result[[1]] = excess.returns 333 | result[[2]] = allocation 334 | result[[3]] = selection 335 | if (method == "top.down"){ # Top-down attribution 336 | result[[3]] = result[[3]] + interaction 337 | } 338 | if (method == "bottom.up"){ # Bottom-up attribution 339 | result[[2]] = result[[2]] + interaction 340 | } 341 | if (method == "none"){ 342 | result[[4]] = interaction 343 | } 344 | } else{ # The function takes output of the corresponding function 345 | # (Attribution.geometric or DaviesLaker) 346 | if (geometric == TRUE){ 347 | attrib = Attribution.geometric(Rp, WP, Rb, WB) 348 | } 349 | 350 | if (linking == "davies.laker"){ 351 | attrib = DaviesLaker(Rp, WP, Rb, WB) 352 | } 353 | result = attrib 354 | } 355 | 356 | # Label the output 357 | if ((method == "none" & geometric == FALSE) | linking == "davies.laker"){ 358 | names(result) = c("Excess returns", "Allocation", "Selection", 359 | "Interaction") 360 | } else{ 361 | names(result) = c("Excess returns", "Allocation", "Selection") 362 | } 363 | 364 | # If multi-currency portfolio 365 | if (currency){ 366 | result[[length(result) + 1]] = Cc 367 | result[[length(result) + 1]] = Df 368 | names(result)[(length(result)-1):length(result)] = 369 | c("Currency management", "Forward Premium") 370 | } 371 | return(result) 372 | } 373 | -------------------------------------------------------------------------------- /inst/doc/PortfolioAttribution.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt,a4paper]{article} 2 | \usepackage{amssymb,amsmath,amsthm,amsxtra, amsfonts} 3 | \usepackage{booktabs} 4 | \usepackage{dcolumn} 5 | \usepackage{epsfig} 6 | \usepackage{epstopdf} 7 | \usepackage{graphicx} 8 | \usepackage{setspace} 9 | \onehalfspacing 10 | \usepackage[top=3cm, bottom=2cm, left=3cm, right=1.5cm]{geometry} 11 | \usepackage{todonotes} 12 | \reversemarginpar 13 | \marginparwidth 2cm 14 | \usepackage{color} 15 | \usepackage[round]{natbib} 16 | \definecolor{darkblue}{rgb}{0.0,0.0,0.3} 17 | \usepackage{hyperref} 18 | \hypersetup{colorlinks = true, 19 | breaklinks = true, 20 | linkcolor = darkblue, 21 | urlcolor = darkblue, 22 | anchorcolor = darkblue, 23 | citecolor = darkblue} 24 | \usepackage[all]{hypcap} 25 | \usepackage{pgfplots} 26 | \usepackage{enumitem} 27 | \setlist{noitemsep, nolistsep} 28 | 29 | 30 | \begin{document} 31 | 32 | \title{Performance Attribution in R} 33 | \author{Andrii Babii} 34 | \maketitle 35 | \begin{abstract} 36 | This paper demonstrates some Performance Attribution functionality in R. The brief overview of the performance attribution methodology is offered with illustrative practical examples. The discussion draws heavily from \cite{christopherson2009portfolio} and \cite{bacon2008practical} where more details can be found. 37 | \end{abstract} 38 | 39 | \section{Introduction} 40 | Performance attribution methodology allows us to decompose the value added by the portfolio into different components and, thus, to evaluate the quality of investment decisions. This usually boils down to the decomposition of the excess returns (relative to the benchmark). If components are different market factors, we obtain the so-called factor-based attribution. If, on the other hand, we decompose excess returns into different sectors of the portfolio we obtain the sector-based attribution. 41 | 42 | This paper discusses mainly the latter. For the factor-based attribution check \cite{fama1972components} or corresponding sections in the aforementioned books. There are many examples where the setup of the sector-based attribution could be useful, see \cite{christopherson2009portfolio} for more details: 43 | \begin{itemize} 44 | \item \textbf{The multi-asset class fund:} each asset class might be considered as a separate portfolio with a distinct benchmark. The decision process boils down to the allocation of weights for different classes and the selection of securities within each class. 45 | \item \textbf{The multicountry portfolio.} The top-level decision is the allocation of weights to different countries. The next stage is to pick up securities within each country. 46 | \item \textbf{The equity portfolio.} We can segment the equity portfolio by sectors or industries. The top-level decision is the allocation of weights to different industries and the decision on the next level is to select securities. More generally, the highest-level decision might be the allocation of weights to different portfolio managers, after which each manager makes his decision on industries and securities. 47 | \end{itemize} 48 | 49 | There are several levels of complexity in the attribution analysis: we can have multiple periods, multiple levels of the decision process, different currencies (in the case of multicountry portfolio), different financial instruments (stocks, fixed income, etc.). Another issue is the choice of returns: the decomposition can be imposed on the arithmetic or geometric excess returns. 50 | 51 | We will start with the simplest example of the single-period, single-level attribution and then proceed to more complex cases. 52 | 53 | \section{Implementation of the performance attribution} 54 | \subsection{Arithmetic attribution} 55 | In the arithmetic attribution we decompose the arithmetic excess returns into three components: allocation, interaction and selection effects across $n$ sectors 56 | \[ 57 | R_{p}-R_{b}=\sum^{n}_{i=1}\left(A_{i}+S_{i}+I_{i}\right) 58 | \] 59 | 60 | \subsubsection{\cite{brinson1985measuring} vs \cite{brinson1986determinants}} 61 | There are two ways to compute the arithmetic attribution effects for the category $i$. One is due to \cite{brinson1986determinants} 62 | \[ 63 | \begin{aligned} 64 | A_{i} & =(w_{pi}-w_{bi})\times R_{bi} \\ 65 | S_{i} & = w_{pi}\times(R_{pi}-R_{bi}) \\ 66 | I_{i} & = (w_{pi}-w_{bi})\times(R_{pi}-R_{bi}) 67 | \end{aligned} 68 | \] 69 | Another is due to \cite{brinson1985measuring}. In this approach the selection and interaction effects are the same as in \cite{brinson1986determinants} while the allocation effect is different 70 | \[ 71 | A_i = (w_{pi} - w_{bi})\times (R_{bi} - R_b) 72 | \] 73 | 74 | \subsubsection{Top-down vs Bottom-up} 75 | Usually we are interested in the allocation and selection effects only. However, by construction they don't sum up to the excess returns. That's why we combine the interaction effect either with the security selection or with the asset allocation effects which is known as "top-down" and "bottom-up" approaches respectively. 76 | 77 | \subsubsection{Multi-period linking} 78 | One problem with the multi-period attribution analysis in the case of the arithmetic returns is that the arithmetic returns do not link naturally through time. As a result, the attribution effects can't also be simply linked through time. To overcome this obstacle several methods that smooth arithmetic attribution effects were suggested. The function supports the following popular methods: 79 | \begin{itemize} 80 | \item \cite{carino1999combining}: based on the logarithmic smoothing. 81 | \item \cite{menchero2000optimized}: adjust by the multiplicative factor based on some optimized criterion. 82 | \item \cite{grap1997}: another scaling method, where adjustment factors depend on the portfolio and benchmark returns linked through multiple periods. 83 | \item \cite{frongello2002linking}: uses similar concept as GRAP, the scaling factor is computed recursively. Very intuitive and mathematically simple. 84 | \item \cite{davies2001multiple}: based on the idea of applying the Brinson model over multiple periods. 85 | \end{itemize} 86 | There are some subtleties involved with each smoothing method but the choice of one is probably a matter of personal tastes. 87 | 88 | \subsubsection{Examples} 89 | We load the data set of portfolio and benchmark returns. 90 | \begingroup 91 | \fontsize{9pt}{12pt}\selectfont 92 | \begin{verbatim} 93 | > data(attrib) 94 | > Rp = attrib.returns[, 1:10] 95 | > Rb = attrib.returns[, 11:20] 96 | \end{verbatim} 97 | \endgroup 98 | 99 | The portfolio includes 9 stocks and one 10-Year Treasury Constant Maturity (GS10) instrument. Returns are quarterly and include 7 observations though time. The benchmark for stocks is S\&P 500 index. The benchmark for fixed income instrument is 3-Month Treasury Bill. 100 | \begingroup 101 | \fontsize{9pt}{12pt}\selectfont 102 | \begin{verbatim} 103 | > Rp 104 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 105 | 2007 Q2 -0.0488 0.1301 0.1388 0.0793 0.1103 0.0860 0.0201 0.0244 0.1059 0.0469 106 | 2007 Q3 -0.0595 0.1051 -0.0553 0.0784 0.1126 0.0941 0.1219 -0.0973 0.0985 0.0500 107 | 2007 Q4 0.0813 -0.0027 -0.0033 -0.1105 -0.0859 0.0657 0.0354 0.0852 0.0121 0.0453 108 | 2008 Q1 -0.0866 -0.0893 -0.1891 -0.0016 0.0631 -0.0082 -0.0500 0.1029 -0.1023 0.0374 109 | 2008 Q2 -0.3068 0.1496 0.1417 -0.3269 0.0290 -0.1579 -0.1270 0.0647 0.0411 0.0368 110 | 2008 Q3 -0.0829 -0.1839 -0.2413 -0.0456 -0.0133 0.0172 0.1140 0.0636 -0.1265 0.0401 111 | 2008 Q4 -0.1846 -0.1089 -0.0901 -0.4537 -0.3291 -0.1554 -0.2633 -0.0661 0.0276 0.0381 112 | > Rb 113 | SP500 SP500.1 SP500.2 SP500.3 SP500.4 SP500.5 SP500.6 SP500.7 SP500.8 TB3MS 114 | 2007 Q2 0.0324 0.0324 0.0324 0.0324 0.0324 0.0324 0.0324 0.0324 0.0324 0.0487 115 | 2007 Q3 0.0645 0.0645 0.0645 0.0645 0.0645 0.0645 0.0645 0.0645 0.0645 0.0482 116 | 2007 Q4 0.0180 0.0180 0.0180 0.0180 0.0180 0.0180 0.0180 0.0180 0.0180 0.0390 117 | 2008 Q1 -0.0667 -0.0667 -0.0667 -0.0667 -0.0667 -0.0667 -0.0667 -0.0667 -0.0667 0.0275 118 | 2008 Q2 -0.0547 -0.0547 -0.0547 -0.0547 -0.0547 -0.0547 -0.0547 -0.0547 -0.0547 0.0129 119 | 2008 Q3 -0.0643 -0.0643 -0.0643 -0.0643 -0.0643 -0.0643 -0.0643 -0.0643 -0.0643 0.0163 120 | 2008 Q4 -0.1014 -0.1014 -0.1014 -0.1014 -0.1014 -0.1014 -0.1014 -0.1014 -0.1014 0.0067 121 | \end{verbatim} 122 | \endgroup 123 | 124 | Weights of assets in the portfolio and benchmark weights are 125 | \begingroup 126 | \fontsize{9pt}{12pt}\selectfont 127 | \begin{verbatim} 128 | > wp 129 | [1] 0.10 0.20 0.30 0.05 0.05 0.01 0.02 0.03 0.04 0.20 130 | > wb 131 | [1] 0.05 0.05 0.02 0.01 0.07 0.03 0.03 0.06 0.08 0.60 132 | \end{verbatim} 133 | \endgroup 134 | 135 | The starting point is the "Attribution" function which takes portfolio and benchmark weights and returns as inputs. The output is a list with several objects. 136 | \begingroup 137 | \fontsize{9pt}{12pt}\selectfont 138 | \begin{verbatim} 139 | > Attribution(Rp, wp, Rb, wb, method = "top.down", linking = "carino") 140 | $`Excess returns` 141 | Arithmetic 142 | 2007 Q2 0.0457 143 | 2007 Q3 -0.0323 144 | 2007 Q4 -0.0204 145 | 2008 Q1 -0.0646 146 | 2008 Q2 0.0478 147 | 2008 Q3 -0.0972 148 | 2008 Q4 -0.0700 149 | Annualized Return -0.1149 150 | 151 | $Allocation 152 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 153 | 2007 Q2 0.0016 0.0049 0.0091 0.0013 -0.0006 -0.0006 -0.0003 -0.0010 -0.0013 -0.0195 -0.0065 154 | 2007 Q3 0.0032 0.0097 0.0181 0.0026 -0.0013 -0.0013 -0.0006 -0.0019 -0.0026 -0.0193 0.0065 155 | 2007 Q4 0.0009 0.0027 0.0050 0.0007 -0.0004 -0.0004 -0.0002 -0.0005 -0.0007 -0.0156 -0.0084 156 | 2008 Q1 -0.0033 -0.0100 -0.0187 -0.0027 0.0013 0.0013 0.0007 0.0020 0.0027 -0.0110 -0.0377 157 | 2008 Q2 -0.0027 -0.0082 -0.0153 -0.0022 0.0011 0.0011 0.0005 0.0016 0.0022 -0.0052 -0.0270 158 | 2008 Q3 -0.0032 -0.0096 -0.0180 -0.0026 0.0013 0.0013 0.0006 0.0019 0.0026 -0.0065 -0.0322 159 | 2008 Q4 -0.0051 -0.0152 -0.0284 -0.0041 0.0020 0.0020 0.0010 0.0030 0.0041 -0.0027 -0.0432 160 | Total -0.0091 -0.0272 -0.0508 -0.0073 0.0036 0.0036 0.0018 0.0054 0.0073 -0.0744 -0.1470 161 | 162 | $Selection 163 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 164 | 2007 Q2 -0.0081 0.0195 0.0319 0.0023 0.0039 0.0005 -0.0002 -0.0002 0.0029 -0.0004 0.0522 165 | 2007 Q3 -0.0124 0.0081 -0.0359 0.0007 0.0024 0.0003 0.0011 -0.0049 0.0014 0.0004 -0.0388 166 | 2007 Q4 0.0063 -0.0041 -0.0064 -0.0064 -0.0052 0.0005 0.0003 0.0020 -0.0002 0.0013 -0.0120 167 | 2008 Q1 -0.0020 -0.0045 -0.0367 0.0033 0.0065 0.0006 0.0003 0.0051 -0.0014 0.0020 -0.0269 168 | 2008 Q2 -0.0252 0.0408 0.0589 -0.0136 0.0042 -0.0010 -0.0014 0.0036 0.0038 0.0048 0.0748 169 | 2008 Q3 -0.0019 -0.0239 -0.0531 0.0009 0.0025 0.0008 0.0036 0.0038 -0.0025 0.0048 -0.0649 170 | 2008 Q4 -0.0083 -0.0015 0.0034 -0.0176 -0.0114 -0.0005 -0.0032 0.0011 0.0052 0.0063 -0.0268 171 | Total -0.0486 0.0290 -0.0417 -0.0298 0.0021 0.0011 0.0004 0.0106 0.0086 0.0188 -0.0495 172 | \end{verbatim} 173 | \endgroup 174 | The first element of the list is the excess arithmetic returns which are the object of the decomposition. The allocation, selection and interaction effects are reported for individual assets and time periods. However, usually we are only interested in the total attribution effects in each period or in the summarized attribution effects for multiple periods. These come in the last column and the bottom row. The bottom-right element is the the total allocation effect of the portfolio. 175 | 176 | As an example we can see that in the second quarter of $2007$, the excess return of portfolio was $0.0457$. In which $-0.0065$ was due to the allocation of weights and $0.0522$ due to the selection of financial instruments. 177 | 178 | Note that in this decomposition we selected to display the "top-down" approach (the selection effect includes the interaction term) and used the Carino linking. 179 | 180 | \subsection{Geometric attribution} 181 | We can also perform the attribution analysis for the geometric excess returns. This comes with some advantages, since the geometric attribution effects in the contrast with arithmetic do naturally link over time multiplicatively: 182 | \[ 183 | \frac{(1+R_{p})}{1+R_{b}}-1 = \prod^{n}_{t=1}(1+A_{t}^{G}) \times \prod^{n}_{t=1}(1+S{}_{t}^{G})-1 184 | \] 185 | Note that another advantage of using geometric attribution is that we don't have to deal with the interaction term. 186 | 187 | \subsubsection{Examples} 188 | As was mentioned the simplicity of the geometric attribution does not require hiding the interaction term or smoothing 189 | \begingroup 190 | \fontsize{9pt}{12pt}\selectfont 191 | \begin{verbatim} 192 | > Attribution(Rp, wp, Rb, wb, geometric = TRUE) 193 | $`Excess returns` 194 | Geometric 195 | 2007 Q2 0.0438 196 | 2007 Q3 -0.0300 197 | 2007 Q4 -0.0225 198 | 2008 Q1 -0.0646 199 | 2008 Q2 0.0480 200 | 2008 Q3 -0.0991 201 | 2008 Q4 -0.0642 202 | Annualized Return -0.1084 203 | 204 | $Allocation 205 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 206 | 2007 Q2 -0.0005 -0.0014 -0.0026 -0.0004 0.0002 0.0002 1e-04 0.0003 0.0004 -0.0025 -0.0062 207 | 2007 Q3 0.0005 0.0014 0.0026 0.0004 -0.0002 -0.0002 -1e-04 -0.0003 -0.0004 0.0024 0.0062 208 | 2007 Q4 -0.0006 -0.0018 -0.0034 -0.0005 0.0002 0.0002 1e-04 0.0004 0.0005 -0.0033 -0.0081 209 | 2008 Q1 -0.0029 -0.0086 -0.0161 -0.0023 0.0012 0.0012 6e-04 0.0017 0.0023 -0.0150 -0.0381 210 | 2008 Q2 -0.0021 -0.0064 -0.0120 -0.0017 0.0009 0.0009 4e-04 0.0013 0.0017 -0.0102 -0.0274 211 | 2008 Q3 -0.0026 -0.0079 -0.0147 -0.0021 0.0011 0.0011 5e-04 0.0016 0.0021 -0.0116 -0.0326 212 | 2008 Q4 -0.0037 -0.0111 -0.0207 -0.0030 0.0015 0.0015 7e-04 0.0022 0.0030 -0.0150 -0.0445 213 | Total NA NA NA NA NA NA NA NA NA NA -0.1424 214 | 215 | $Selection 216 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 217 | 2007 Q2 -0.0078 0.0189 0.0308 0.0023 0.0038 0.0005 -0.0002 -0.0002 0.0028 -0.0003 0.0504 218 | 2007 Q3 -0.0117 0.0077 -0.0339 0.0007 0.0023 0.0003 0.0011 -0.0046 0.0013 0.0003 -0.0365 219 | 2007 Q4 0.0062 -0.0040 -0.0063 -0.0063 -0.0051 0.0005 0.0003 0.0020 -0.0002 0.0012 -0.0117 220 | 2008 Q1 -0.0021 -0.0047 -0.0385 0.0034 0.0068 0.0006 0.0004 0.0053 -0.0015 0.0021 -0.0282 221 | 2008 Q2 -0.0263 0.0426 0.0614 -0.0142 0.0044 -0.0011 -0.0015 0.0037 0.0040 0.0050 0.0780 222 | 2008 Q3 -0.0020 -0.0251 -0.0558 0.0010 0.0027 0.0009 0.0037 0.0040 -0.0026 0.0050 -0.0682 223 | 2008 Q4 -0.0090 -0.0016 0.0037 -0.0191 -0.0124 -0.0006 -0.0035 0.0011 0.0056 0.0068 -0.0291 224 | Total NA NA NA NA NA NA NA NA NA NA -0.0521 225 | 226 | \end{verbatim} 227 | \endgroup 228 | The object of interest is usually the last column with total attribution effects for each period and the multi-period attribution effects in the bottom-left of the table. The interpretation is exactly the same as in the previous case with the only difference that the attribution effects yield the excess returns mutiplicatively. 229 | 230 | \subsection{Multi-level attribution} 231 | The multi-level decision process gives another level of complexity. For the multi-level performance attribution we need to specify the portfolio hierarchy. The hierarchy object is compatible with the \textit{Blotter} package. It can be quite arbitrary including textual description as well as numeric values, e.g. market capitalization. If numeric values are used in the hierarchy, the decomposition is performed into 5 quintiles. For example we may have the following hierarchy object 232 | \begingroup 233 | \fontsize{9pt}{12pt}\selectfont 234 | \begin{verbatim} 235 | > data(attrib) 236 | > h = attrib.hierarchy 237 | > h 238 | primary_id type currency Sector MarketCap 239 | 1 CA.PA stock EUR Consumer Services 9510000000 240 | 2 CVX stock USD Energy 211860229230 241 | 3 FP.PA stock EUR Energy 82670000000 242 | 4 GE stock USD Energy 216462224160 243 | 5 IBM stock USD Technology 226002120120 244 | 6 KO stock USD Consumer Non-Durables 178581002000 245 | 7 PEP stock USD Consumer Non-Durables 110666163400 246 | 8 WMT stock USD Consumer Services 240597756250 247 | 9 XOM stock USD Energy 403445280000 248 | 10 GS10 bond USD Government NA 249 | \end{verbatim} 250 | \endgroup 251 | 252 | Besides specifying the hierarchy object we need to define levels of the decision process. This is specified as a vector with names of the corresponding columns in the hierarchy. As an example we use imaginary portfolio where on the highest level the allocation between different instruments. The next level is the allocation between specific sectors. The last stage of this decision process is the allocation between different companies by market capitalization. 253 | \begingroup 254 | \fontsize{9pt}{12pt}\selectfont 255 | \begin{verbatim} 256 | > Attribution.levels(Rp, wp, Rb, wb, h, c("type", "MarketCap", "Sector")) 257 | $`Excess returns` 258 | Geometric 259 | 2007 Q2 0.0438 260 | 2007 Q3 -0.0300 261 | 2007 Q4 -0.0225 262 | 2008 Q1 -0.0646 263 | 2008 Q2 0.0480 264 | 2008 Q3 -0.0991 265 | 2008 Q4 -0.0642 266 | Annualized Return -0.1084 267 | 268 | $`Multi-level attribution` 269 | Level 1 Allocation Level 2 Allocation Level 3 Allocation Selection 270 | 2007 Q2 -0.0305 -0.0084 -0.0008 0.0868 271 | 2007 Q3 -0.0323 -0.0166 -0.0017 0.0209 272 | 2007 Q4 -0.0241 -0.0047 -0.0005 0.0069 273 | 2008 Q1 -0.0117 0.0179 0.0017 -0.0717 274 | 2008 Q2 -0.0053 0.0146 0.0014 0.0370 275 | 2008 Q3 -0.0083 0.0172 0.0017 -0.1084 276 | 2008 Q4 -0.0027 0.0275 0.0026 -0.0891 277 | Total -0.1098 0.0476 0.0045 -0.1266 278 | 279 | $`Attribution at each level` 280 | $`Attribution at each level`$`Level 1` 281 | stock 282 | 2007 Q2 -0.0112 283 | 2007 Q3 -0.0109 284 | 2007 Q4 -0.0091 285 | 2008 Q1 -0.0069 286 | 2008 Q2 -0.0039 287 | 2008 Q3 -0.0054 288 | 2008 Q4 -0.0044 289 | Total -0.0507 290 | 291 | $`Attribution at each level`$`Level 2` 292 | stock-Quintile 1 stock-Quintile 2 stock-Quintile 3 stock-Quintile 4 stock-Quintile 5 293 | 2007 Q2 -0.0035 0.0003 -0.0017 -0.0002 0.0006 294 | 2007 Q3 -0.0069 0.0006 -0.0033 -0.0004 0.0011 295 | 2007 Q4 -0.0019 0.0002 -0.0009 -0.0001 0.0003 296 | 2008 Q1 0.0074 -0.0007 0.0036 0.0004 -0.0012 297 | 2008 Q2 0.0061 -0.0006 0.0029 0.0004 -0.0010 298 | 2008 Q3 0.0071 -0.0007 0.0034 0.0004 -0.0012 299 | 2008 Q4 0.0114 -0.0011 0.0055 0.0007 -0.0019 300 | Total 0.0197 -0.0018 0.0095 0.0012 -0.0033 301 | 302 | $`Attribution at each level`$`Level 3` 303 | stock-Quintile 1-Consumer Services stock-Quintile 1-Energy stock-Quintile 2-Consumer Non-Durables 304 | 2007 Q2 0e+00 -0.0005 0 305 | 2007 Q3 -1e-04 -0.0009 0 306 | 2007 Q4 0e+00 -0.0003 0 307 | 2008 Q1 1e-04 0.0009 0 308 | 2008 Q2 1e-04 0.0008 0 309 | 2008 Q3 1e-04 0.0009 0 310 | 2008 Q4 1e-04 0.0014 0 311 | Total 2e-04 0.0024 0 312 | stock-Quintile 3-Energy stock-Quintile 4-Energy stock-Quintile 4-Technology 313 | 2007 Q2 0 -1e-04 0 314 | 2007 Q3 0 -2e-04 0 315 | 2007 Q4 0 -1e-04 0 316 | 2008 Q1 0 2e-04 0 317 | 2008 Q2 0 2e-04 0 318 | 2008 Q3 0 2e-04 0 319 | 2008 Q4 0 3e-04 0 320 | Total 0 5e-04 0 321 | stock-Quintile 5-Consumer Services stock-Quintile 5-Energy 322 | 2007 Q2 1e-04 1e-04 323 | 2007 Q3 2e-04 2e-04 324 | 2007 Q4 0e+00 0e+00 325 | 2008 Q1 -2e-04 -2e-04 326 | 2008 Q2 -1e-04 -1e-04 327 | 2008 Q3 -2e-04 -2e-04 328 | 2008 Q4 -2e-04 -2e-04 329 | Total -4e-04 -4e-04 330 | 331 | \end{verbatim} 332 | \endgroup 333 | 334 | We are already familiar with the first object in the list which is excess return. The next object gives as the general picture about 3 allocation and selection effects. Lastly the allocation effects at each level are demonstrated. 335 | 336 | \subsection{Fixed income attribution} 337 | Previously we considered the attribution analysis for all instruments together. However, the the investment process for some financial instruments may be very different. For example, the investment decision process for bond managers is not the same as for equity managers. The standard Brinson model is simply not suitable for most fixed income investment strategies. 338 | 339 | Bonds are viewed as a series of future cash flows which are relatively easy to price. Fixed income performance is 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 suggested in \cite{van2000fixed}. Following notation of \cite{bacon2008practical}, the allocation, selection and currency allocation effects for category $i$ are: 340 | \[ 341 | \begin{aligned} 342 | A_{i} & = (D_{pi}\times w_{pi}-D_{\beta}\times D_{bi}\times w_{pi})\times (-\Delta y_{bi} + \Delta y_{b}) \\ 343 | S_{i} & = D_{i}\times w_{pi}\times (-\Delta y_{ri} + \Delta y_{bi}) \\ 344 | C_{i} & = (w_{pi} - w_{bi})\times (c_{i} + R_{fi} - c') \\ 345 | \end{aligned} 346 | \] 347 | 348 | \subsubsection{Examples} 349 | We need the following inputs for the fixed-income performance attribution: portfolio and benchmark durations, weights; benchmark weights of the currency forward contract; spot rates. 350 | \begingroup 351 | \fontsize{9pt}{12pt}\selectfont 352 | \begin{verbatim} 353 | > data(attrib) 354 | > Dp = attrib.returns[, 63:72] 355 | > Db = attrib.returns[, 73:82] 356 | > wp = attrib.weights[1, ] 357 | > wb = attrib.weights[2, ] 358 | > wbf = attrib.weights[4, ] 359 | > S = attrib.currency[, 11:20] 360 | \end{verbatim} 361 | \endgroup 362 | 363 | The output looks familiar and all items are self-described. 364 | \begingroup 365 | \fontsize{9pt}{12pt}\selectfont 366 | \begin{verbatim} 367 | > AttributionFixedIncome(Rp, wp, Rb, wb, Rf, Dp, Db, S, wbf, geometric = FALSE) 368 | $`Excess returns` 369 | Total 370 | 2007 Q2 0.0457 371 | 2007 Q3 -0.0323 372 | 2007 Q4 -0.0204 373 | 2008 Q1 -0.0646 374 | 2008 Q2 0.0478 375 | 2008 Q3 -0.0972 376 | 2008 Q4 -0.0700 377 | 378 | $`Market allocation` 379 | CA.PA.4 CVX.4 FP.PA.4 GE.4 IBM.4 KO.4 PEP.4 WMT.4 XOM.4 GS10.4 Total 380 | 2007 Q2 0.0052 -0.0262 -0.0462 -0.0067 0.0013 0.0028 0.0027 0.0067 0.0040 0.0547 -0.0015 381 | 2007 Q3 -0.0029 -0.0027 0.0053 -0.0002 0.0000 0.0001 0.0000 -0.0082 0.0001 0.0056 -0.0029 382 | 2007 Q4 -0.0094 -0.0060 -0.0089 0.0035 -0.0084 0.0009 0.0003 0.0002 0.0019 0.0132 -0.0127 383 | 2008 Q1 -0.0926 -0.0081 0.1452 -0.0221 -0.0226 -0.0024 -0.0042 -0.0366 -0.0077 -0.0012 -0.0524 384 | 2008 Q2 0.0708 -0.1137 -0.2688 0.0350 -0.0137 0.0070 0.0016 0.0005 -0.0002 0.0849 -0.1964 385 | 2008 Q3 0.0039 0.1084 0.2232 -0.0142 -0.0137 -0.0136 -0.0115 -0.0193 0.0087 -0.0056 0.2665 386 | 2008 Q4 -0.0942 -0.1229 0.1792 -0.9918 -1.8609 -0.0061 -0.0399 -0.2637 -0.1259 -0.0181 -3.3444 387 | 388 | $`Issue selection` 389 | CA.PA.4 CVX.4 FP.PA.4 GE.4 IBM.4 KO.4 PEP.4 WMT.4 XOM.4 GS10.4 Total 390 | 2007 Q2 -0.0122 0.0295 0.0467 0.0047 0.0060 0.0008 -0.0004 -0.0005 0.0047 0.0009 0.0802 391 | 2007 Q3 -0.0153 0.0107 -0.0434 0.0007 0.0028 0.0004 0.0013 -0.0058 0.0018 0.0007 -0.0461 392 | 2007 Q4 0.0127 -0.0080 -0.0151 -0.0114 -0.0089 0.0007 0.0005 0.0037 -0.0002 0.0033 -0.0226 393 | 2008 Q1 -0.0185 -0.0158 -0.2114 0.0207 0.0271 0.0033 0.0037 0.0415 -0.0073 0.0052 -0.1515 394 | 2008 Q2 -0.1052 0.1270 0.2720 -0.0565 0.0259 -0.0046 -0.0057 0.0128 0.0170 0.0093 0.2920 395 | 2008 Q3 -0.0121 -0.1466 -0.2968 0.0116 0.0122 0.0133 0.0134 0.0204 -0.0156 0.0122 -0.3880 396 | 2008 Q4 0.0712 0.0937 -0.2159 0.9673 1.8407 0.0034 0.0331 0.2588 0.1233 0.0153 3.1909 397 | 398 | $`Currency allocation` 399 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 400 | 2007 Q2 -0.0089 -0.0440 -0.0344 -0.0070 0.0039 0.0027 0.0028 0.0039 0.0090 0.0146 -0.0575 401 | 2007 Q3 -0.0038 0.0221 -0.0480 -0.0016 0.0018 0.0028 -0.0004 0.0051 0.0063 0.0291 0.0135 402 | 2007 Q4 -0.0046 -0.0212 0.0080 0.0012 -0.0016 0.0006 0.0005 0.0001 -0.0043 0.0678 0.0464 403 | 2008 Q1 -0.0022 -0.0218 -0.0936 -0.0133 0.0062 0.0067 0.0015 0.0072 0.0094 0.0230 -0.0769 404 | 2008 Q2 -0.0089 -0.0399 0.0168 -0.0111 0.0020 -0.0035 0.0027 0.0020 0.0062 0.0192 -0.0144 405 | 2008 Q3 -0.0055 0.0226 -0.0118 0.0087 0.0014 0.0041 0.0001 0.0005 0.0040 0.0491 0.0733 406 | 2008 Q4 0.0007 -0.0173 -0.0505 -0.0116 0.0014 0.0015 -0.0004 0.0059 -0.0004 0.0675 -0.0032 407 | \end{verbatim} 408 | \endgroup 409 | If we select the arithmetic attribution, the currency allocation effect would be absent. This is in parallel with the absence of the interaction effect in the equity performance attribution considered before. 410 | 411 | \subsection{Multi-currency attribution} 412 | The last extension of the performance attribution is to consider the multi-currency portfolio and to take into account currency effects in the analysis more deeply. The multi-currency arithmetic attribution is handled following \cite{ankrim1994multicurrency}. The decomposition is the same as in the standard Brinson model with the only difference that attribution effects are adjusted to currency effects. In multi-currency performance attribution we should specify: the portfolio and the benchmark weights of the currency forward contracts, portfolio and benchmark returns in local currency, benchmark returns hedged into the base currency, the forward and the spot rates. 413 | \begingroup 414 | \fontsize{9pt}{12pt}\selectfont 415 | \begin{verbatim} 416 | > data(attrib) 417 | > wpf = attrib.weights[3, ] 418 | > wbf = attrib.weights[4, ] 419 | > Rpl = attrib.returns[, 33:42] 420 | > Rbl = attrib.returns[, 43:52] 421 | > Rbh = attrib.returns[, 53:62] 422 | > F = attrib.currency[, 1:10] 423 | > S = attrib.currency[, 11:20] 424 | \end{verbatim} 425 | \endgroup 426 | 427 | The only difference is two last objects in the list: currency management and forward premium effects. 428 | \begingroup 429 | \fontsize{9pt}{12pt}\selectfont 430 | \begin{verbatim} 431 | > Attribution(Rp, wp, Rb, wb, wpf, wbf, S, F, Rpl, Rbl, Rbh, method = "none", linking = "carino") 432 | $`Excess returns` 433 | Arithmetic 434 | 2007 Q2 0.0457 435 | 2007 Q3 -0.0323 436 | 2007 Q4 -0.0204 437 | 2008 Q1 -0.0646 438 | 2008 Q2 0.0478 439 | 2008 Q3 -0.0972 440 | 2008 Q4 -0.0700 441 | Annualized Return -0.1149 442 | 443 | $Allocation 444 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 445 | 2007 Q2 0.0034 0.0273 0.0033 0.0025 -0.0017 -0.0005 -0.0017 -0.0005 -0.0046 0.0234 0.0510 446 | 2007 Q3 0.0005 -0.0320 0.0294 -0.0010 -0.0005 -0.0015 0.0011 -0.0032 -0.0037 0.0039 -0.0070 447 | 2007 Q4 -0.0011 0.0042 -0.0397 -0.0057 0.0039 0.0017 0.0007 0.0033 0.0088 -0.0308 -0.0548 448 | 2008 Q1 -0.0068 -0.0052 0.0432 0.0061 -0.0026 -0.0031 0.0003 -0.0018 -0.0022 0.0113 0.0392 449 | 2008 Q2 0.0029 0.0220 -0.0504 0.0063 0.0003 0.0059 -0.0015 0.0016 -0.0015 0.0016 -0.0126 450 | 2008 Q3 -0.0015 -0.0435 -0.0272 -0.0142 0.0013 -0.0013 0.0013 0.0037 0.0015 -0.0256 -0.1055 451 | 2008 Q4 -0.0104 -0.0119 -0.0040 0.0038 0.0025 0.0023 0.0024 -0.0001 0.0082 -0.0329 -0.0400 452 | Total -0.0136 -0.0418 -0.0432 -0.0025 0.0034 0.0032 0.0027 0.0031 0.0071 -0.0511 -0.1326 453 | 454 | $Selection 455 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 456 | 2007 Q2 -0.0041 0.0049 0.0021 0.0005 0.0055 0.0016 -0.0004 -0.0005 0.0059 -0.0011 0.0144 457 | 2007 Q3 -0.0062 0.0020 -0.0024 0.0001 0.0034 0.0009 0.0017 -0.0097 0.0027 0.0011 -0.0063 458 | 2007 Q4 0.0032 -0.0010 -0.0004 -0.0013 -0.0073 0.0014 0.0005 0.0040 -0.0005 0.0038 0.0024 459 | 2008 Q1 -0.0010 -0.0011 -0.0024 0.0007 0.0091 0.0018 0.0005 0.0102 -0.0028 0.0059 0.0207 460 | 2008 Q2 -0.0126 0.0102 0.0039 -0.0027 0.0059 -0.0031 -0.0022 0.0072 0.0077 0.0143 0.0286 461 | 2008 Q3 -0.0009 -0.0060 -0.0035 0.0002 0.0036 0.0024 0.0053 0.0077 -0.0050 0.0143 0.0181 462 | 2008 Q4 -0.0042 -0.0004 0.0002 -0.0035 -0.0159 -0.0016 -0.0049 0.0021 0.0103 0.0188 0.0010 463 | Total -0.0243 0.0073 -0.0028 -0.0060 0.0030 0.0032 0.0006 0.0212 0.0171 0.0565 0.0759 464 | 465 | $Interaction 466 | CA.PA CVX FP.PA GE IBM KO PEP WMT XOM GS10 Total 467 | 2007 Q2 -0.0041 0.0147 0.0298 0.0019 -0.0016 -0.0011 0.0001 0.0002 -0.0029 0.0007 0.0378 468 | 2007 Q3 -0.0062 0.0061 -0.0335 0.0006 -0.0010 -0.0006 -0.0006 0.0049 -0.0014 -0.0007 -0.0324 469 | 2007 Q4 0.0032 -0.0031 -0.0060 -0.0051 0.0021 -0.0010 -0.0002 -0.0020 0.0002 -0.0025 -0.0144 470 | 2008 Q1 -0.0010 -0.0034 -0.0343 0.0026 -0.0026 -0.0012 -0.0002 -0.0051 0.0014 -0.0040 -0.0476 471 | 2008 Q2 -0.0126 0.0306 0.0550 -0.0109 -0.0017 0.0021 0.0007 -0.0036 -0.0038 -0.0096 0.0463 472 | 2008 Q3 -0.0009 -0.0179 -0.0496 0.0007 -0.0010 -0.0016 -0.0018 -0.0038 0.0025 -0.0095 -0.0830 473 | 2008 Q4 -0.0042 -0.0011 0.0031 -0.0141 0.0046 0.0011 0.0016 -0.0011 -0.0052 -0.0126 -0.0278 474 | Total -0.0243 0.0218 -0.0390 -0.0238 -0.0009 -0.0021 -0.0002 -0.0106 -0.0086 -0.0377 -0.1254 475 | 476 | $`Currency management` 477 | EUR EUR EUR EUR EUR EUR EUR EUR EUR EUR Total 478 | 2007 Q2 -0.0048 -0.0178 0.0125 0.0035 -0.0029 0.0243 0.0059 -0.0029 -0.0092 0.0090 0.0177 479 | 2007 Q3 -0.0013 0.0109 -0.0389 0.0085 -0.0029 -0.0028 -0.0062 -0.0153 -0.0035 0.0135 -0.0380 480 | 2007 Q4 -0.0026 0.0076 0.0070 0.0075 -0.0042 0.0178 -0.0148 -0.0060 -0.0103 0.0159 0.0179 481 | 2008 Q1 -0.0053 0.0095 -0.0205 -0.0050 0.0020 -0.0278 -0.0027 0.0011 -0.0010 -0.0004 -0.0502 482 | 2008 Q2 0.0002 -0.0152 0.0321 -0.0116 0.0012 0.0154 0.0104 0.0090 0.0099 -0.0147 0.0369 483 | 2008 Q3 0.0018 -0.0082 -0.0036 -0.0095 0.0042 0.0126 0.0024 -0.0057 0.0197 -0.0182 -0.0043 484 | 2008 Q4 -0.0038 -0.0148 -0.0105 -0.0105 0.0008 0.0032 -0.0044 0.0249 0.0022 -0.0130 -0.0260 485 | 486 | $`Forward Premium` 487 | EUR EUR EUR EUR EUR EUR EUR EUR EUR EUR Total 488 | 2007 Q2 -0.0097 -0.0118 -0.0182 -0.0054 0.0042 0.0023 0.0004 0.0011 0.0067 -0.0340 -0.0644 489 | 2007 Q3 0.0006 0.0235 0.0118 -0.0048 0.0026 0.0007 -0.0002 0.0069 0.0039 -0.0152 0.0298 490 | 2007 Q4 0.0016 -0.0131 0.0295 -0.0001 -0.0003 -0.0009 0.0019 -0.0022 -0.0081 0.0109 0.0193 491 | 2008 Q1 -0.0030 -0.0121 -0.0388 -0.0046 0.0020 0.0016 0.0006 0.0029 0.0043 -0.0245 -0.0715 492 | 2008 Q2 -0.0042 -0.0138 0.0075 0.0009 -0.0006 -0.0042 -0.0001 -0.0037 0.0005 0.0047 -0.0130 493 | 2008 Q3 0.0043 0.0443 0.0172 0.0204 -0.0040 0.0033 -0.0014 -0.0009 -0.0049 0.0334 0.1118 494 | 2008 Q4 0.0025 0.0163 -0.0038 0.0015 -0.0019 -0.0010 -0.0010 -0.0062 -0.0069 0.0304 0.0299 495 | \end{verbatim} 496 | \endgroup 497 | 498 | \section{Return and risk metrics} 499 | \subsection{Time-Varying Conditional alpha and beta} 500 | \cite{ferson1996measuring} and \cite{christopherson1999performance} suggested to relax assumptions of the basic CAPM model allowing for time-varying alphas and betas. The modified regression is then 501 | \[ 502 | r_{pt+1}=\alpha_{0p}+\mathbf{A}_{p}'\mathbf{z}_{t}+b_{0p}r_{bt+1}+\mathbf{B}_{p}'[\mathbf{z}_{t}r_{bt+1}]+\mu_{pt+1} 503 | \] 504 | The regression allows us to estimate alphas and betas for specified number of periods (conditioning on some information set). The following example illustrates the OLS estimation of alphas and betas when one lag is selected. 505 | \begingroup 506 | \fontsize{9pt}{12pt}\selectfont 507 | \begin{verbatim} 508 | > data(managers) 509 | > round(CAPM.dynamic(managers[80:120,1:6], managers[80:120,7,drop=FALSE], 510 | Rf=managers[80:120,10,drop=FALSE], Z=managers[80:120, 9:10]), 4) 511 | Average alpha US 10Y TR alpha at t - 1 US 3m TR alpha at t - 1 512 | HAM1 to EDHEC LS EQ -0.0002 -0.2389 -0.4385 513 | HAM2 to EDHEC LS EQ -0.0028 -0.0663 -4.0177 514 | HAM3 to EDHEC LS EQ 0.0063 -0.2173 7.6805 515 | HAM4 to EDHEC LS EQ -0.0033 0.1614 -0.2092 516 | HAM5 to EDHEC LS EQ 0.0043 0.2688 3.8497 517 | HAM6 to EDHEC LS EQ -0.0054 0.0500 -3.0664 518 | Average beta US 10Y TR beta at t - 1 US 3m TR beta at t - 1 519 | HAM1 to EDHEC LS EQ 1.1793 3.8612 -51.0141 520 | HAM2 to EDHEC LS EQ 0.7067 5.6821 171.1666 521 | HAM3 to EDHEC LS EQ 0.4261 1.5079 -705.2035 522 | HAM4 to EDHEC LS EQ 1.6368 -7.6221 -565.8520 523 | HAM5 to EDHEC LS EQ 1.2225 7.0840 39.7036 524 | HAM6 to EDHEC LS EQ 1.6282 -11.0351 343.5289 525 | 526 | \end{verbatim} 527 | \endgroup 528 | 529 | \subsection{Market timing metrics: \cite{henriksson1981market} and \cite{treynor1966can} models} 530 | The Treynor-Mazuy model is a quadratic extension of the basic CAPM and is estimated with OLS 531 | \[ 532 | R_{p}-R_{f}=\alpha+\beta (R_{b} - R_{f})+\gamma (R_{b}-R_{f})^2+\varepsilon_{p} 533 | \] 534 | 535 | \begingroup 536 | \fontsize{9pt}{12pt}\selectfont 537 | \begin{verbatim} 538 | > data(managers) 539 | > round(MarketTiming(managers[80:120,1:6], managers[80:120,8:7], 540 | managers[80:120,10,drop=FALSE], method = "TM"), 4) 541 | Alpha Beta Gamma 542 | HAM1 to SP500 TR 0.0049 0.5970 -0.2802 543 | HAM2 to SP500 TR 0.0051 0.1190 -0.5000 544 | HAM3 to SP500 TR 0.0032 0.5273 -0.6646 545 | HAM4 to SP500 TR 0.0095 0.8780 -0.8155 546 | HAM5 to SP500 TR 0.0087 0.2870 -2.7728 547 | HAM6 to SP500 TR 0.0048 0.2902 0.6911 548 | HAM1 to EDHEC LS EQ -0.0006 1.3121 -0.4051 549 | HAM2 to EDHEC LS EQ -0.0004 0.4371 8.5206 550 | HAM3 to EDHEC LS EQ -0.0058 1.1898 11.9138 551 | HAM4 to EDHEC LS EQ -0.0055 2.0617 18.7973 552 | HAM5 to EDHEC LS EQ 0.0005 1.0704 -5.0779 553 | HAM6 to EDHEC LS EQ 0.0004 1.2711 -7.4434 554 | \end{verbatim} 555 | \endgroup 556 | The gamma coefficient captures convexity. In our example in most cases the estimated regression line is concave. This can be interpreted as the absence of the "market timing" ability. 557 | 558 | The Merton-Henriksson market timing model is based on the slightly modified regression 559 | \[ 560 | R_{p}-R_{f}=\alpha+\beta (R_{b}-R_{f})+\gamma\times max(0,R_{b}-R_{f})+\varepsilon_{p} 561 | \] 562 | 563 | \begingroup 564 | \fontsize{9pt}{12pt}\selectfont 565 | \begin{verbatim} 566 | > MarketTiming(managers[80:120,1:6], managers[80:120,7,drop=FALSE], 567 | managers[80:120,10,drop=FALSE], method = "HM") 568 | Alpha Beta Gamma 569 | HAM1 to EDHEC LS EQ -0.0003365399 1.3412815 -0.05212598 570 | HAM2 to EDHEC LS EQ -0.0015584145 0.2205427 0.47286655 571 | HAM3 to EDHEC LS EQ -0.0054857505 1.0945787 0.33529653 572 | HAM4 to EDHEC LS EQ -0.0066151355 1.7431499 0.79315879 573 | HAM5 to EDHEC LS EQ 0.0072167507 1.8204007 -1.25680612 574 | HAM6 to EDHEC LS EQ 0.0010991550 1.4286362 -0.36338737 575 | \end{verbatim} 576 | \endgroup 577 | 578 | \subsection{\cite{modigliani1997risk} measure} 579 | \begingroup 580 | \fontsize{9pt}{12pt}\selectfont 581 | \begin{verbatim} 582 | > data(managers) 583 | > round(Modigliani(managers[,1:6], managers[,8:7], managers[,8,drop=FALSE]), 4) 584 | HAM1 HAM2 HAM3 HAM4 HAM5 HAM6 585 | Modigliani-Modigliani measure: SP500 TR 0.0128 0.0151 0.0132 0.0106 0.0105 0.0184 586 | Modigliani-Modigliani measure: EDHEC LS EQ 0.0106 0.0117 0.0108 0.0096 0.0095 0.0133 587 | \end{verbatim} 588 | \endgroup 589 | 590 | \bibliographystyle{plainnat} 591 | \bibliography{References} 592 | \end{document} 593 | --------------------------------------------------------------------------------