[Returnanalytics-commits] r2033 - pkg/PortfolioAnalytics/sandbox/attribution/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Mon Jun 18 19:11:29 CEST 2012
Author: ababii
Date: 2012-06-18 19:11:29 +0200 (Mon, 18 Jun 2012)
New Revision: 2033
Modified:
pkg/PortfolioAnalytics/sandbox/attribution/R/Attribution.geometric.R
Log:
- fixed bug with incorrect returns and total attribution effects
Modified: pkg/PortfolioAnalytics/sandbox/attribution/R/Attribution.geometric.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/attribution/R/Attribution.geometric.R 2012-06-18 16:55:18 UTC (rev 2032)
+++ pkg/PortfolioAnalytics/sandbox/attribution/R/Attribution.geometric.R 2012-06-18 17:11:29 UTC (rev 2033)
@@ -63,25 +63,35 @@
rb = reclass(rowSums(Rb * wb), Rb)
names(rp) = "Total"
names(rb) = "Total"
+ bs = reclass(rowSums((wp * Rb[, 1:ncol(wp)])), rp) # Seminotional funds returns
+ allocation = ((1 + Rb) / (1 + rep(rb, ncol(Rp))) - 1) * (wp - wb) # Geometric attribution effects for individual categories
+ selection = wp * (Rp - Rb) / (1 + rep(bs, ncol(Rp)))
+ allocation = cbind(allocation, rowSums(allocation)) # Total effects
+ selection = cbind(selection, rowSums(selection))
+ colnames(allocation)[ncol(allocation)] = "Total"
+ colnames(selection)[ncol(selection)] = "Total"
+
+ # Link single-period attribution effects
+ a = (apply(1 + allocation[, ncol(allocation)], 2, prod) - 1)
+ s = (apply(1 + selection[, ncol(selection)], 2, prod) - 1)
+ (apply(1 + selection[, ncol(selection)], 2, prod) - 1)
+ allocation = rbind(as.data.frame(allocation), c(rep(NA, ncol(allocation) - 1), a))
+ selection = rbind(as.data.frame(selection), c(rep(NA, ncol(selection) - 1), s))
+ rownames(allocation)[nrow(allocation)] = "Total"
+ rownames(selection)[nrow(selection)] = "Total"
+
+ # Get annualized geometric excess returns
+ excess.returns = (1 + rp) / (1 + rb) - 1
rp.a = prod(1 + rp) - 1
rb.a = prod(1 + rb) - 1
- Rp = cbind(Rp, rp)
- Rb = cbind(Rb, rb)
+ ger.a = as.matrix((1 + rp.a) / (1 + rb.a) - 1) # Geometric (annualized) excess returns
+ rownames(ger.a) = "Total geometric"
+ excess.returns = rbind(as.matrix(excess.returns), ger.a)
- bs = reclass(rowSums((wp * Rb[, 1:ncol(wp)])), rp) # Seminotional funds returns
- allocation = ((1 + Rb) / (1 + rb.a) - 1) * cbind((wp - wb), rep(1, nrow(wp)))
- selection = allocation
- for (i in 1:ncol(wp)){
- selection[, i] = ((Rp - Rb) * cbind(wp, rep(1, nrow(wp))))[, i] / (1 + bs)
- }
- allocation = rbind(as.data.frame(allocation), (apply(1 + allocation, 2, prod) - 1))
- selection = rbind(as.data.frame(selection), (apply(1 + selection, 2, prod) - 1))
- rownames(allocation)[nrow(allocation)] = "Total"
- rownames(selection)[nrow(selection)] = "Total"
result = list()
- result[[1]] = allocation
- result[[2]] = selection
- result[[3]] = allocation + selection
- names(result) = c("Allocation", "Selection", "Total")
+ result[[1]] = excess.returns
+ result[[2]] = allocation
+ result[[3]] = selection
+ names(result) = c("Excess returns", "Allocation", "Selection")
return(result)
}
\ No newline at end of file
More information about the Returnanalytics-commits
mailing list