[Returnanalytics-commits] r1998 - pkg/PortfolioAnalytics/sandbox/attribution
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Jun 9 14:25:39 CEST 2012
Author: ababii
Date: 2012-06-09 14:25:38 +0200 (Sat, 09 Jun 2012)
New Revision: 1998
Modified:
pkg/PortfolioAnalytics/sandbox/attribution/Return.level.R
pkg/PortfolioAnalytics/sandbox/attribution/attrib.RData
pkg/PortfolioAnalytics/sandbox/attribution/attribution.R
pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R
Log:
- a couple of simplifications
Modified: pkg/PortfolioAnalytics/sandbox/attribution/Return.level.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/attribution/Return.level.R 2012-06-08 19:58:27 UTC (rev 1997)
+++ pkg/PortfolioAnalytics/sandbox/attribution/Return.level.R 2012-06-09 12:25:38 UTC (rev 1998)
@@ -23,7 +23,7 @@
function(Rp, wp, h, level = "Sector")
{
Rp = checkData(Rp, method = "xts")
- wp <- Weight.transform(Rp, wp)
+ wp = Weight.transform(wp, Rp)
# Aggregate returns to the chosen level from the hierarchy
h = split(h$primary_id, h[level])
@@ -44,7 +44,7 @@
Weight.transform <-
-function(Rp, wp)
+function(wp, Rp)
{
# Transform weights to the xts object used by aggregation and attribution functions
if (is.vector(wp)){
@@ -79,35 +79,16 @@
}
# Example
-
-# 1. Generate data
-list <- c("XOM", "IBM", "CVX", "WMT", "GE")
-update_instruments.TTR(list, exchange="NYSE")
-hierarchy <- buildHierarchy(ls_stocks(), c("type", "currency", "Sector"))
-getSymbols(list)
-for (i in list){
- r <- Return.calculate(to.yearly(get(i)))[2:6, 4]
- colnames(r) <- i
- if(i == "XOM"){
- Rp <- r
- } else{
- Rp <- cbind(Rp, r)
- }
-}
-
-# 2. Aggregate portfolio
-Rp
-# with vector weights
wp <- c(0.3, 0.2, 0.2, 0.1, 0.2)
-wp <- Weight.transform(Rp, wp)
+wp <- Weight.transform(wp, Rp)
Return.level(Rp, wp, hierarchy, level = "Sector")
# with xts weights
wp <- Rp[1:2, ]
wp[1, ] <- c(0.3, 0.2, 0.2, 0.1, 0.2)
wp[2, ] <- c(0.3, 0.2, 0.2, 0.1, 0.2)
-wp <- Weight.transform(Rp, wp)
+wp <- Weight.transform(wp, Rp)
Return.level(Rp, wp, hierarchy, level = "type")
-aggregate.weights(wp, hierarchy, level = "Sector")
+Weight.level(wp, hierarchy, level = "Sector")
###############################################################################
Modified: pkg/PortfolioAnalytics/sandbox/attribution/attrib.RData
===================================================================
(Binary files differ)
Modified: pkg/PortfolioAnalytics/sandbox/attribution/attribution.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/attribution/attribution.R 2012-06-08 19:58:27 UTC (rev 1997)
+++ pkg/PortfolioAnalytics/sandbox/attribution/attribution.R 2012-06-09 12:25:38 UTC (rev 1998)
@@ -1,6 +1,6 @@
#' performs arithmetic attribution
#'
-#' @aliases attribution.crithmetic
+#' @aliases attribution.arithmetic
#'
#' Performs arithmetic attribution analysis of returns. Used to uncover the sources
#' of portfolio return
@@ -155,6 +155,7 @@
}
}
+ # Aggregate adjusted multi-period attribution effects
if (linking != "geometric"){
totals <- function(x){
x = as.data.frame(x)
@@ -172,6 +173,7 @@
rownames(allocation)[nrow(allocation)] = "Total"
rownames(selection)[nrow(selection)] = "Total"
}
+
# Select the appropriate result corresponding to the chosen method
result = list()
result[[1]] = allocation
Modified: pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R 2012-06-08 19:58:27 UTC (rev 1997)
+++ pkg/PortfolioAnalytics/sandbox/attribution/attribution.levels.R 2012-06-09 12:25:38 UTC (rev 1998)
@@ -9,45 +9,50 @@
levels <- unlist(list(...))
if (!is.null(levels)) stopifnot(is.character(levels))
- # Get lists with returns and weights at all levels for the portfolio and the benchmark
+ # Get returns and weights at all levels
returns.p = list()
weights.p = list()
- for(i in 1:length(levels)){
- returns.p[[i]] = Return.level(Rp, wp, h, level = levels[i])
- weights.p[[i]] = Weight.level(wp, h, level = levels[i])
- }
- names(returns.p) = levels
- names(weights.p) = levels
-
returns.b = list()
weights.b = list()
+ bs = list()
for(i in 1:length(levels)){
+ returns.p[[i]] = Return.level(Rp, wp, h, level = levels[i])
+ weights.p[[i]] = Weight.level(wp, h, level = levels[i])
returns.b[[i]] = Return.level(Rb, wb, h, level = levels[i])
weights.b[[i]] = Weight.level(wb, h, level = levels[i])
+ bs[[i]] = Return.rebalancing(weights.p[[i]], returns.b[[i]]) # semi-notional funds returns
}
+ names(returns.p) = levels
+ names(weights.p) = levels
names(returns.b) = levels
names(weights.b) = levels
- # Get lists with semi-notional funds returns
- # (computed using portfolio weights and benchmark returns)
- bs = list()
- for(i in 1:length(levels)){
- bs[[i]] = Return.rebalancing(weights.p[[i]], returns.b[[i]])
- }
-
# Get portfolio and benchmark returns
r = Return.rebalancing(Rp, wp)
b = Return.rebalancing(Rb, wb)
+
+ # Total attribution effects
+ allocation = list()
+ allocation[[1]] = (1 + bs[[1]]) / (1 + b) - 1 # Allocation 1
+ for (i in 2:length(levels)){
+ allocation[[i]] = (1 + bs[[i]]) / (1 + bs[[i-1]]) - 1
+ }
+ allocation = as.xts(as.data.frame(allocation))
+ selection = (1 + r) / (1 + last(bs)[[1]]) - 1
+ total = (1 + r) / (1 + b) - 1 # Total excess return
+
+ #level = list()
+ #level[[1]] = (weights.p[[1]] - weights.b[[1]]) * ((1 + returns.b[[1]]) / (1 + b) - 1)
+ #for (i in 2:length(levels)){
+ # 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]]))
+ #}
- allocation.1 = (1 + bs[[1]]) / (1 + b) - 1
- allocation.2 = (1 + bs[[2]]) / (1 + bs[[1]]) - 1
- allocation.3 = (1 + bs[[3]]) / (1 + bs[[2]]) - 1
- selection = (1 + r) / (1 + bs[[3]]) - 1
- total = (1 + r) / (1 + b) - 1 #Total excess return
# Level 1 attribution
l1 = (weights.p[[1]] - weights.b[[1]]) * ((1 + returns.b[[1]]) / (1 + b) - 1)
+
# Level 2 attribution
l2 = (weights.p[[2]] - weights.b[[2]]) * ((1 + returns.b[[2]]) / (1 + returns.b[[1]]) - 1) * ((1 + returns.b[[1]]) / (1 + bs[[1]]))
+
# Level 3 attribution
w = (weights.p[[3]] - weights.b[[3]])
a1 = 1 + returns.b[[2]]
@@ -55,6 +60,7 @@
b2 = ((1 + returns.b[[2]]) / (1 + bs[[2]]))
b2 = cbind(b2, b2, b2)
l3 = w * b1 * b2
+
# Security/Asset selection
w = weights.p[[3]]
a1 = cbind((1 + r), (1 + r), (1 + r))
@@ -64,9 +70,8 @@
select = w * b1 * b2
result = list()
- general = cbind(allocation.1, allocation.2, allocation.3, selection, total)
- colnames(general) = c("L1 allocation", "L2 allocation", "L3 allocation",
- "Selection", "Total")
+ general = cbind(allocation, selection, total)
+ colnames(general) = c("L1 allocation", "L2 allocation", "L3 allocation", "Selection", "Total")
result[[1]] = general
result[[2]] = l1
result[[3]] = l2
@@ -79,12 +84,6 @@
# Example:
data(attrib) # !!! Load attrib.RData workspace
-Rb <- Rp
-wp <- c(0.3, 0.2, 0.2, 0.1, 0.2)
-wb <- c(0.1, 0.3, 0.2, 0.2, 0.2)
-wp = Weight.transform(Rp, wp) # transform weights to the xts object
-wb = Weight.transform(Rb, wb) # of the same size as returns using a function from Return.level
-
attribution.levels(Rp, wp, Rb, wb, h, c("type", "currency", "Sector"))
More information about the Returnanalytics-commits
mailing list