From noreply at r-forge.r-project.org Wed Oct 15 05:02:07 2014 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 15 Oct 2014 05:02:07 +0200 (CEST) Subject: [Returnanalytics-commits] r3542 - pkg/PerformanceAnalytics/sandbox Message-ID: <20141015030207.9392E18717E@r-forge.r-project.org> Author: peter_carl Date: 2014-10-15 05:02:05 +0200 (Wed, 15 Oct 2014) New Revision: 3542 Added: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R Log: - first draft of to.period for aggregating contributions Added: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R =================================================================== --- pkg/PerformanceAnalytics/sandbox/to.period.contributions.R (rev 0) +++ pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-15 03:02:05 UTC (rev 3542) @@ -0,0 +1,34 @@ +to.period.contributions <- function(C, period = c("years", "quarters", "months", "weeks"), ...){ + period = period[1] + columnnames = colnames(C) + # @TODO make sure period > frequency of C + + # Calculate period return of portfolio from contributions + pret = rowSums(C) + pret = xts(pret, order.by=index(C)) + lag.cum.ret <- na.fill(lag(cumprod(1+pret),1),1) + wgt.contrib = C * rep(lag.cum.ret, NCOL(C)) + + # Calculate aggregation periods + ep = endpoints(C, period) + dates = index(C)[endpoints(C, period)] + + # Summarize weighted contributions by period + period.wgt.contrib = apply(wgt.contrib, 2, function (x, ep) period.apply(x, INDEX=ep, FUN=sum), ep=ep) + period.wgt.contrib = as.xts(period.wgt.contrib, order.by=dates) + + # Normalize to the beginning of period value + period.contrib = NULL + for(i in 1:length(dates)) { + if(i==1){ + span = paste0("::", dates[i]) + }else{ + span = paste0(dates[i-1], "::", dates[i]) + } + period.contrib = rbind(period.contrib, colSums(wgt.contrib[span]/rep(head(lag.cum.ret[span],1),NCOL(wgt.contrib)))) + } + period.contrib = as.xts(period.contrib, order.by = dates) + period.contrib = cbind(period.contrib, rowSums(period.contrib)) + colnames(period.contrib) = c(columnnames, "Portfolio Return") + return(period.contrib) +} \ No newline at end of file From noreply at r-forge.r-project.org Wed Oct 15 13:27:35 2014 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 15 Oct 2014 13:27:35 +0200 (CEST) Subject: [Returnanalytics-commits] r3543 - pkg/PerformanceAnalytics/sandbox Message-ID: <20141015112735.90A5D1873DE@r-forge.r-project.org> Author: peter_carl Date: 2014-10-15 13:27:35 +0200 (Wed, 15 Oct 2014) New Revision: 3543 Modified: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R Log: - added check for periodicity - added reclass for result - added copyright block - added to.*.contributions functions as wrappers Modified: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R =================================================================== --- pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-15 03:02:05 UTC (rev 3542) +++ pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-15 11:27:35 UTC (rev 3543) @@ -1,7 +1,22 @@ -to.period.contributions <- function(C, period = c("years", "quarters", "months", "weeks"), ...){ +to.period.contributions <- function(Contributions, period = c("years", "quarters", "months", "weeks"), ...){ + C = checkData(Contributions) period = period[1] columnnames = colnames(C) - # @TODO make sure period > frequency of C + if(!xtsible(Contributions)) + stop("'Contributions' needs to be timeBased or xtsible." ) + # Make sure period > frequency of C + err=FALSE + freq = periodicity(C) + switch(freq$scale, + minute = {stop("Data periodicity too high")}, + hourly = {stop("Data periodicity too high")}, + daily = {ifelse(!period %in% c("years", "quarters", "months", "weeks"), err <- TRUE,NA)}, + weekly = {ifelse(!period %in% c("years", "quarters", "months"), err <- TRUE,NA)}, + monthly = {ifelse(!period %in% c("years", "quarters"), err <- TRUE,NA)}, + quarterly = {ifelse(!period %in% c("years"), err <- TRUE,NA)}, + yearly = {stop("Data periodicity too low")} + ) + if(err) stop("Period specified is higher than data periodicity. Specify a lower frequency instead.") # Calculate period return of portfolio from contributions pret = rowSums(C) @@ -30,5 +45,33 @@ period.contrib = as.xts(period.contrib, order.by = dates) period.contrib = cbind(period.contrib, rowSums(period.contrib)) colnames(period.contrib) = c(columnnames, "Portfolio Return") + period.contrib = reclass(period.contrib, x) + return(period.contrib) -} \ No newline at end of file + +} + +to.weekly.contributions <- function(contributions) { + to.period.contributions(contributions = contributions, period = "weeks") +} +to.monthly.contributions <- function(contributions) { + to.period.contributions(contributions = contributions, period = "months") +} +to.quarterly.contributions <- function(contributions) { + to.period.contributions(contributions = contributions, period = "quarters") +} +to.yearly.contributions <- function(contributions) { + to.period.contributions(contributions = contributions, period = "years") +} + +############################################################################### +# R (http://r-project.org/) Econometrics for Performance and Risk Analysis +# +# Copyright (c) 2004-2014 Peter Carl and Brian G. Peterson +# +# This R package is distributed under the terms of the GNU Public License (GPL) +# for full details see the file COPYING +# +# $Id: $ +# +############################################################################### \ No newline at end of file From noreply at r-forge.r-project.org Wed Oct 15 15:10:23 2014 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 15 Oct 2014 15:10:23 +0200 (CEST) Subject: [Returnanalytics-commits] r3544 - pkg/PerformanceAnalytics/sandbox Message-ID: <20141015131023.80BC3183E2A@r-forge.r-project.org> Author: peter_carl Date: 2014-10-15 15:10:23 +0200 (Wed, 15 Oct 2014) New Revision: 3544 Modified: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R Log: - added roxygen documentation Modified: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R =================================================================== --- pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-15 11:27:35 UTC (rev 3543) +++ pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-15 13:10:23 UTC (rev 3544) @@ -1,3 +1,34 @@ +#' aggregate contributions through time +#' +#' Higher frequency contributions provided as a time series are converted to a lower +#' frequency for a specified calendar period. +#' +#' From the portfolio contributions of individual assets, such as those of a particular asset class +#' or manager, the multiperiod contribution is neither summable from nor the geometric compounding of +#' single-period contributions. Because the weights of the individual assets change through time as +#' transactions occur, the capital base for the asset changes. +#' +#' Instead, the asset's multiperiod contribution is the sum of the asset's dollar contributions from +#' each period, as calculated from the wealth index of the total portfolio. Once contributions are +#' expressed in cumulative terms, asset contributions then sum to the returns of the total portfolio for +#' the period. +#' +#' Valid period character strings for period include: "weeks", "months", "quarters", and "years". +#' These are calculated internally via \code{\link{endpoints}}. See that function's help page for further details. +#' +#' @param Contributions a time series of the per period contribution to portfolio return of each asset +#' @param period period to convert to. See details."years", "quarters", "months", "weeks" +#' @param \dots any other passthru parameters +#' @author Peter Carl, with thanks to Paolo Cavatore +#' @seealso \code{\link{Return.portfolio}} \cr \code{\link{endpoints}} \cr +#' @references Morningstar \emph{Total Portfolio Performance Attribution Methodology} p.36. Available at http://corporate.morningstar.com/US/documents/MethodologyDocuments/MethodologyPapers/TotalPortfolioPerformanceAttributionMethodology.pdf \cr +#' @aliases to.monthly.contributions to.weekly.contributions to.quarterly.contributions to.yearly.contributions +#' @examples +#' data(managers) +#' res_qtr_rebal = Return.portfolio(managers["2002::",1:5], weights=c(.05,.1,.3,.4,.15), rebalance_on = "quarters", verbose=TRUE) +#' to.period.contributions(res_qtr_rebal$contribution, period="years") +#' to.yearly.contributions(res_qtr_rebal$contribution) +#' @export to.period.contributions <- function(Contributions, period = c("years", "quarters", "months", "weeks"), ...){ C = checkData(Contributions) period = period[1] @@ -50,16 +81,19 @@ return(period.contrib) } - +#' @export to.weekly.contributions <- function(contributions) { to.period.contributions(contributions = contributions, period = "weeks") } +#' @export to.monthly.contributions <- function(contributions) { to.period.contributions(contributions = contributions, period = "months") } +#' @export to.quarterly.contributions <- function(contributions) { to.period.contributions(contributions = contributions, period = "quarters") } +#' @export to.yearly.contributions <- function(contributions) { to.period.contributions(contributions = contributions, period = "years") } From noreply at r-forge.r-project.org Wed Oct 15 18:09:51 2014 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 15 Oct 2014 18:09:51 +0200 (CEST) Subject: [Returnanalytics-commits] r3545 - pkg/PerformanceAnalytics/sandbox Message-ID: <20141015160951.E232F183DFC@r-forge.r-project.org> Author: peter_carl Date: 2014-10-15 18:09:51 +0200 (Wed, 15 Oct 2014) New Revision: 3545 Added: pkg/PerformanceAnalytics/sandbox/to.period.returns.R Log: - first draft of to.period for returns Added: pkg/PerformanceAnalytics/sandbox/to.period.returns.R =================================================================== --- pkg/PerformanceAnalytics/sandbox/to.period.returns.R (rev 0) +++ pkg/PerformanceAnalytics/sandbox/to.period.returns.R 2014-10-15 16:09:51 UTC (rev 3545) @@ -0,0 +1,76 @@ +#' aggregate returns through time +#' +#' Higher frequency returns provided as a time series are converted to a lower +#' frequency for a specified calendar period. +#' +#' description here +#' +#' Valid period character strings for period include: "weeks", "months", "quarters", and "years". +#' These are calculated internally via \code{\link{endpoints}}. See that function's help page for further details. +#' +#' @param R a time series of the per period returns +#' @param period period to convert to. See details."years", "quarters", "months", "weeks" +#' @param geometric use geometric chaining (TRUE) or simple/arithmetic chaining (FALSE) to aggregate returns, default TRUE +#' @param \dots any other passthru parameters +#' @author Peter Carl +#' @seealso \code{\link{Return.cumulative}} \cr \code{\link{endpoints}} \cr +#' @aliases to.monthly.returns to.weekly.returns to.quarterly.returns to.yearly.returns +#' @examples +#' data(managers) +#' to.period.returns(managers[,1:5], period="years") +#' to.yearly.returns(managers["2002::",1:5], geometric=TRUE) +#' @export +to.period.returns <- function(R, period = c("years", "quarters", "months", "weeks"), geometric = TRUE, ...){ + x = checkData(R) + period = period[1] + columnnames = colnames(x) + if(!xtsible(R)) + stop("'R' needs to be timeBased or xtsible." ) + # Make sure period > frequency of R + err=FALSE + freq = periodicity(x) + switch(freq$scale, + minute = {stop("Data periodicity too high")}, + hourly = {stop("Data periodicity too high")}, + daily = {ifelse(!period %in% c("years", "quarters", "months", "weeks"), err <- TRUE,NA)}, + weekly = {ifelse(!period %in% c("years", "quarters", "months"), err <- TRUE,NA)}, + monthly = {ifelse(!period %in% c("years", "quarters"), err <- TRUE,NA)}, + quarterly = {ifelse(!period %in% c("years"), err <- TRUE,NA)}, + yearly = {stop("Data periodicity too low")} + ) + if(err) stop("Period specified is higher than data periodicity. Specify a lower frequency instead.") + + # Calculate cumulative return for aggregation periods + period.apply(x, INDEX=endpoints(x, period), FUN=Return.cumulative, geometric=geometric) + + return(period.ret) + +} +#' @export +to.weekly.returns <- function(R) { + to.period.returns(R = R, period = "weeks", geometric=TRUE) +} +#' @export +to.monthly.returns <- function(R) { + to.period.returns(R = R, period = "months", geometric=TRUE) +} +#' @export +to.quarterly.returns <- function(R) { + to.period.returns(R = R, period = "quarters", geometric=TRUE) +} +#' @export +to.yearly.returns <- function(R) { + to.period.returns(R = R, period = "years", geometric=TRUE) +} + +############################################################################### +# R (http://r-project.org/) Econometrics for Performance and Risk Analysis +# +# Copyright (c) 2004-2014 Peter Carl and Brian G. Peterson +# +# This R package is distributed under the terms of the GNU Public License (GPL) +# for full details see the file COPYING +# +# $Id: $ +# +############################################################################### \ No newline at end of file From noreply at r-forge.r-project.org Thu Oct 16 04:16:10 2014 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Thu, 16 Oct 2014 04:16:10 +0200 (CEST) Subject: [Returnanalytics-commits] r3546 - pkg/PerformanceAnalytics/sandbox Message-ID: <20141016021611.092FD184C83@r-forge.r-project.org> Author: peter_carl Date: 2014-10-16 04:16:08 +0200 (Thu, 16 Oct 2014) New Revision: 3546 Modified: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R Log: - fixed a bug in span calculation Modified: pkg/PerformanceAnalytics/sandbox/to.period.contributions.R =================================================================== --- pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-15 16:09:51 UTC (rev 3545) +++ pkg/PerformanceAnalytics/sandbox/to.period.contributions.R 2014-10-16 02:16:08 UTC (rev 3546) @@ -69,11 +69,11 @@ if(i==1){ span = paste0("::", dates[i]) }else{ - span = paste0(dates[i-1], "::", dates[i]) + span = paste0(dates[i-1]+1, "::", dates[i]) } period.contrib = rbind(period.contrib, colSums(wgt.contrib[span]/rep(head(lag.cum.ret[span],1),NCOL(wgt.contrib)))) } - period.contrib = as.xts(period.contrib, order.by = dates) + period.contrib = xts(period.contrib, order.by = dates) period.contrib = cbind(period.contrib, rowSums(period.contrib)) colnames(period.contrib) = c(columnnames, "Portfolio Return") period.contrib = reclass(period.contrib, x)