3
$\begingroup$

I have a matrix of returns and weights for every time period.

returns<-rbind(c(-0.05,0.04,0.37),c(0.15,0.02,-0.07))
weights<-rbind(c(0.5,0.1,0.4),c(0.4,0.2,0.4))

I would like to rebalance the weights at the end of every time period:

To do so I first calculate percent change every month in the returns:

ones <- matrix(1,ncol=ncol(returns),nrow=nrow(returns))
add <- returns
percentChange <- ones+add

then I calculate the total change:

percentChangeSums <- rowSums(percentChange*weights) 

then I calculate the weights after accounting for the returns:

WeightsBefore <- weights * percentChange

I calculate how much I should invest in the shares to have the original weights I wanted to maintain:

ShareAfter <- percentChangeSums * weights 

Just to check that I still have the original weights:

WeightsAfter <- ShareAfter/percentChangeSums


rebalanced.weights <- ShareAfter

My goal is to do this without using any built in functions (e.g. the ones in the PerformanceAnalytics package).

The problem is that I get different results from the built in functions (Return.portfolio()).

What am I missing?

Update:

Based on XY's comment I modified my code:

return <- rbind(c(-5,4,37),c(15,2,-7))

weights <- rbind(c(0.5,0.1,0.4), c(0.5,0.1,0.4),c(0.5,0.1,0.4))

N=3
add <- return/100
ones <- matrix(1,ncol=N,nrow=nrow(return))
ShareAfter <- matrix(NA,ncol=N,nrow=nrow(return))
firstPeriodReturns <- weights[1,]*add[1,]
percentChange <- ones+add


WeightsBefore <- weights[1,] * percentChange[1,]
percentChangeSums <- sum(WeightsBefore)

ShareAfter[1,] <- percentChangeSums * weights[1,] 

for (i in 2:nrow(return)){

  WeightsBefore <- ShareAfter[i-1,] * percentChange[i,]
  percentChangeSums <- sum(WeightsBefore)

  ShareAfter[i,] <- percentChangeSums * weights[i,]   

}

I still do not get the desired result. Can someone point me to whats missing?

Please note again I want to do this manually, not with a package.

$\endgroup$
2
$\begingroup$

The calculation of rebalanced portfolio returns using PerformanceAnalytics functions makes use of what the package authors call "end-of-period" weights. As described in the documentation for Return.portfolio, the rebalancing uses the weights for the last trading day of the period to rebalance the portfolio after the markets close on that day. As an example, in the code below I've added dates to your weight and return data. Here the weights for 2015-05-31 specify the weights used to rebalance the portfolio following the close of trading on that date. These become the "beginning-of-period" weights for the trading period starting on 2015-06-01 and are the proper ones to use with the returns of 2015-06-30 to calculate the portfolio returns for the month of June. For this case, where the weights and returns have the same number of data points per period, returns for a period are just the scalar product of the asset returns and the weights. The code below also performs this calculation so you can compare the two methods.

From your post, it looked as though you might also be interested in the cumulative returns. The code below includes that calculation using both PerformanceAnalytics and direct calculations.

returns<-rbind(c(-0.05,0.04,0.37),c(0.15,0.02,-0.07))
weights<-rbind(c(0.5,0.1,0.4),c(0.4,0.2,0.4))
library(PerformanceAnalytics)
ret <- xts(returns, order.by= as.Date(c("2015-06-30", "2015-07-31")))
wts <- xts(weights, order.by= as.Date(c("2015-05-31","2015-06-30")))
#  Period returns
returns_PA <- Return.portfolio(ret, wts)
returns_direct <- reclass(sapply(1:nrow(wts), function(n) ret[n,]%*%t(wts[n,])), ret)

# Cummulative returns
returns_PA_cum <- Return.cumulative(returns_PA)
returns_direct_cum <- prod(returns_direct+1) -1
$\endgroup$
  • $\begingroup$ The user might be interested in PortfolioAnalytics which is in the same family as PerformanceAnalytics as it has easy to use functions which take care of all the heavy lifting $\endgroup$ – Kyle Balkissoon Jul 31 '15 at 17:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.