[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