[Returnanalytics-commits] r2008 - pkg/PortfolioAnalytics/sandbox/attribution
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Jun 12 14:51:25 CEST 2012
Author: ababii
Date: 2012-06-12 14:51:25 +0200 (Tue, 12 Jun 2012)
New Revision: 2008
Modified:
pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R
Log:
- fixed issue with non-conformable benchmark returns at adjacent levels
Modified: pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R 2012-06-12 11:48:51 UTC (rev 2007)
+++ pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R 2012-06-12 12:51:25 UTC (rev 2008)
@@ -1,14 +1,19 @@
# Multi-level attribution
-# TODO: find a way to make conformable returns at different levels
+# TODO: find a way to label vectors of varying length (depending on the number of attribution levels)
+# compute total effects for multiple periods once linking functions are separated from attribution.R
attribution.levels <-
-function(Rp, Rb, wp, wb, h, ...)
+function(Rp, wp, Rb, wb, h, ...)
{ # @author Andrii Babii
Rp = checkData(Rp)
Rb = checkData(Rb)
wp = Weight.transform(wp, Rp)
wb = Weight.transform(wb, Rb)
-
+ if (nrow(wp) < nrow(Rp)){ # Rebalancing occurs next day
+ Rp = Rp[2:nrow(Rp)]
+ Rb = Rb[2:nrow(Rb)]
+ }
+
levels <- unlist(list(...))
if (!is.null(levels)) stopifnot(is.character(levels))
@@ -34,6 +39,7 @@
names(returns.b) = levels
names(weights.b) = levels
+
# Total attribution effects
allocation = list()
allocation[[1]] = (1 + bs[[1]]) / (1 + b) - 1 # Allocation 1
@@ -47,35 +53,45 @@
# Transform portfolio, benchmark returns and semi-notional funds returns to conformable matrices for multi-level attribution
b = as.xts(matrix(rep(b, ncol(returns.b[[1]])), nrow(b), ncol(returns.b[[1]])), index(b))
r = as.xts(matrix(rep(r, ncol(last(returns.b)[[1]])), nrow(r), ncol(last(returns.b)[[1]])), index(r))
-
- for (i in 1:length(bs)){
- bs[[i]] = as.xts(matrix(rep(bs[[i]], ncol(returns.p[[i]])), nrow(r), ncol(returns.p[[i]])), index(r))
+
+ returns.b2 = list()
+ for (j in 1:(length(levels) - 1)){ # make benchmark returns conformable at different levels
+ r_l = Return.level(Rb, wb, h, level = levels[j])
+ r_h = Return.level(Rb, wb, h, level = levels[j+1])
+ hierarchy = split(h[levels[j]], h[levels[j+1]])
+ for (i in 1:ncol(r_h)){
+ r_h[, i] = r_l[, hierarchy[[i]][1, 1]]
+ }
+ returns.b2[[j]] = r_h
}
+ for (i in 1:(length(bs) - 1)){
+ bs[[i]] = as.xts(matrix(rep(bs[[i]], ncol(returns.b2[[i]])), nrow(r), ncol(returns.b2[[i]])), index(r))
+ }
+ bs[length(bs)] = bs[length(bs) - 1]
+
# Attribution at each level
level = list()
level[[1]] = (weights.p[[1]] - weights.b[[1]]) * ((1 + returns.b[[1]]) / (1 + b) - 1)
- for (i in 2:length(levels)){ # This does not work. Need to finish
- level[[i]] = (weights.p[[i]] - weights.b[[i]]) * ((1 + returns.b[[i]]) / (1 + returns.b[[i-1]]) - 1) * ((1 + returns.b[[i-1]]) / (1 + bs[[i-1]]))
+ for (i in 2:length(levels)){
+ level[[i]] = (weights.p[[i]] - weights.b[[i]]) * ((1 + returns.b[[i]]) / (1 + returns.b2[[i-1]]) - 1) * ((1 + returns.b2[[i-1]]) / (1 + bs[[i-1]]))
}
# Security/Asset selection
select = as.xts(as.data.frame(last(weights.p))) * ((1 + r) / (1 + as.xts(as.data.frame(last(returns.b)))) - 1) * ((1 + as.xts(as.data.frame(last(returns.b)))) / (1 + as.xts(as.data.frame(last(bs)))))
+ # Label output
result = list()
general = cbind(allocation, selection, total)
- colnames(general) = c("L1 allocation", "L2 allocation", "L3 allocation", "Selection", "Total")
+ # colnames(general) = c("L1 allocation", "L2 allocation", "L3 allocation", "Selection", "Total")
result[[1]] = general
- result[[2]] = l1
- result[[3]] = l2
- result[[4]] = l3
- result[[5]] = select
- names(result) = c("Multi-level attribution", "Level 1 attribution", "Level 2 attribution", "Level 3 attribution", "Security selection")
+ result[[2]] = level
+ result[[3]] = select
+ names(result) = c("Multi-level attribution", "Attribution at each level", "Security selection")
return(result)
}
# Example:
data(attrib)
attribution.levels(Rp, wp, Rb, wb, h, c("type", "currency", "Sector"))
-
-
+attribution.levels(Rp, wp, Rb, wb, h, c("type", "Sector"))
\ No newline at end of file
More information about the Returnanalytics-commits
mailing list