# How do Return.portfolio and Return.rebalancing work in Performance Analytics in R?

I have a question about the function Return.portfolio/Return.rebalancing from the Performance Analytics package in R.

I take the example described in the package:

> data(edhec)
> data(weights)
> Return.portfolio(edhec,weights = weights)
portfolio.returns
2000-01-31      0.0115135339
2000-02-29      0.0218963077
2000-03-31      0.0093379014
2000-04-30      0.0037485690
2000-05-31      0.0056601357
2000-06-30      0.0140301727
2000-07-31      0.0043295816
2000-08-31      0.0190997787
2000-09-30      0.0014645727
2000-10-31      0.0014264155
2000-11-30      0.0061304707
2000-12-31      0.0201417025
2001-01-31      0.0150594011
2001-02-28      0.0066011872
2001-03-31      0.0131395159
2001-04-30      0.0007491561
2001-05-31      0.0091626407
2001-06-30     -0.0000527803
2001-07-31      0.0020738201
2001-08-31      0.0102713727
2001-09-30      0.0002531717
2001-10-31      0.0142380976
2001-11-30     -0.0048429083
2001-12-31      0.0061645640
2002-01-31      0.0093372403
2002-02-28     -0.0011217258
2002-03-31      0.0063415238
2002-04-30      0.0082130861
2002-05-31      0.0058782220
2002-06-30      0.0007565192
2002-07-31     -0.0059246865
2002-08-31      0.0072696705
2002-09-30      0.0026434591
2002-10-31      0.0014298494
2002-11-30      0.0105008400
2002-12-31      0.0127186414
2003-01-31      0.0159481947
2003-02-28      0.0092381495
2003-03-31      0.0001639493
2003-04-30      0.0113937775
2003-05-31      0.0199355028
2003-06-30      0.0020659339
2003-07-31     -0.0039260851
2003-08-31      0.0035691334
2003-09-30      0.0114224214
2003-10-31      0.0116788871
2003-11-30      0.0069773935
2003-12-31      0.0117366500
2004-01-31      0.0137408298
2004-02-29      0.0086731496
2004-03-31      0.0030241495
2004-04-30     -0.0031369461
2004-05-31     -0.0006375207
2004-06-30      0.0039463036
2004-07-31      0.0010463350
2004-08-31      0.0022005523
2004-09-30      0.0065116125
2004-10-31      0.0042086646
2004-11-30      0.0164591318
2004-12-31      0.0094498415
2005-01-31      0.0030113644
2005-02-28      0.0103238498
2005-03-31      0.0008083756
2005-04-30     -0.0052241413
2005-05-31      0.0020622011
2005-06-30      0.0081079582
2005-07-31      0.0118744372
2005-08-31      0.0073621313
2005-09-30      0.0101843734
2005-10-31     -0.0012149988
2005-11-30      0.0076005987
2005-12-31      0.0089111835
2006-01-31      0.0193600000
2006-02-28      0.0050290768
2006-03-31      0.0122895863
2006-04-30      0.0161541728
2006-05-31      0.0028728086
2006-06-30      0.0008591674
2006-07-31      0.0029350825
2006-08-31      0.0061800530
2006-09-30      0.0020263120
2006-10-31      0.0128266559
2006-11-30      0.0129600658
2006-12-31      0.0126486355
2007-01-31      0.0106456451
2007-02-28      0.0105816673
2007-03-31      0.0082080685
2007-04-30      0.0120657529
2007-05-31      0.0130340469
2007-06-30      0.0054403426
2007-07-31     -0.0001698053
2007-08-31     -0.0096513313
2007-09-30      0.0156251014
2007-10-31      0.0171940678
2007-11-30     -0.0113391902
2007-12-31      0.0030447149
2008-01-31     -0.0120408215
2008-02-29      0.0045617517
2008-03-31     -0.0188804492
2008-04-30      0.0121140702
2008-05-31      0.0127356881
2008-06-30     -0.0003266534
2008-07-31     -0.0118233426
2008-08-31     -0.0064733095
2008-09-30     -0.0478450597
2008-10-31     -0.0630740252
2008-11-30     -0.0354050961
2008-12-31     -0.0046962342
2009-01-31      0.0089404911
2009-02-28     -0.0027223978
2009-03-31      0.0050820481
2009-04-30      0.0229829814
2009-05-31      0.0374323984
2009-06-30      0.0111071893
2009-07-31      0.0255805068
2009-08-31      0.0179835194
Warning message:
In Return.portfolio(edhec, weights = weights) :
number of assets in beginning_weights is less than number of columns in returns, so subsetting returns.
> sum(as.numeric(edhec[151,1:11])*as.numeric(weights[8,]))
[1] 0.02614121
>


How are these returns calculated using Return.portfolio? In weights are two column missing compared with edhec. That's the reason why I took

edhec[151,1:11]


Moreover, we see that weights is a xts object with just 8 rows. Does Return.portfolio check the dates and take the right weights for that period? Moreover, what is the difference to Return.rebalancing?

Is it correct, that if we would sum up the first 10 elements of

Return.portfolio(edhec,weights = weights)


we would get the total return at time $t=10$?

Reference: the software package in use is R programming language is used for data analysis and visualization including statistics and graphics. R is an integrated suite of software facilities for data manipulation, calculation and graphical display. The R project is Open Source, available at http://www.r-project.org/

Additionally, the R statistical program has a considerable repository of projects available to the whole community, available at https://r-forge.r-project.org/ One of the projects is ReturnAnalytics -- Performance and risk analysis of financial time series, including packages PerformanceAnalytics and PortfolioAnalytics. That project is available via anonymous access: svn checkout svn://svn.r-forge.r-project.org/svnroot/returnanalytics/

• You should include the links to the package you're using. This is really close to be a SO question, but I think it's related to concepts enough to keep it here. Let's see what the community thinks. – SRKX Sep 8 '14 at 2:11
• @SRKX Thx for your comment. I will include the link when I'm at home. Feel free to move it to SO if you thinks it fits there better. I was unsure as well – math Sep 8 '14 at 6:24
• I would like to thank User8 for the submission, and making me aware of the package. Proposed update to the original question submitted to assist others in understanding what software and packages are involved. Note: my specific interest is in using the R program to quantify and validate different investing strategies.. – zipzit Sep 8 '14 at 7:52
• I do not see your motivating example in the PerformanceAnalytics pdf. The closest comparable thing I see is round(Return.rebalancing(edhec,weights),4). You'll note that the 2007-01-01 return matches up with edhec[121,1:11]%*%t(weights[8,]), ignoring the rounding. – John Sep 9 '14 at 20:29
• When I try to replicate your example I get Error in Return.portfolio(edhec, weights = weights) : Use Return.rebalancing for multiple weighting periods. This function is for portfolios with a single set of weights. – berkorbay Sep 11 '14 at 19:37

I'm going to separate your question in two.

The key thing you're asking is that how does Return.rebalancing treat your different frequencied and number of asset return and weight objects.

## Data munging:

It subsets the first ncol(weight) columns of R (as ncol(edhec) > ncol(weights)

ncol R is now 11. Checks if the first date in R is less than the first date date in W If true it subsets R from 2000-01-02/" onwards nrow(R) is now 116 as you cannot have a return series before the initial weights.

## Data processing:

It then calls Return.portfolio.geometric, which just multiplies the returns by the weights for those two matrices.

As weights are annual and edhec is monthly.

It needs to calculate inbetween years

So it grabs the return series for the inbetween period.

Loops through all of the return subseries calculating the weights * the previous amount in the return period (essentially floating it and rebalancing on the weight matrix). It takes the total value of each period in the return series and divides it by the starting value in the period to calculate the periodic return.

A simple demonstration is as follows.

1. Take initial equity value (1)
2. Take rebalancing year initial weight
3. Calculate end of period equity (initial equity * weight * return)
4. Calculate return for period
5. Repeat two on each rebalancing date as specified in the weight matrix.

eop_value[k, ] = (1 + coredata(returns[j, ])) * bop_value[k, ] eop_value_total[k] = sum(eop_value[k, ])

ret[k] = eop_value_total[k]/end_value - 1 end_value = eop_value_total[k]

The above code calculates the new total equity for each position and sums it up.

So it is akin to your weights floating and then resetting on each date in the weights matrix.

• Thx for you answer! Could you please elaborate a little bit on "....Loops through all of the return subseries calculating the weights * the previous amount in the return period (essentially floating it and rebalancing on the weight matrix). It takes the total value of each period in the return series and divides it by the starting value in the period to calculate the periodic return." – math Sep 11 '14 at 18:54
• Especially: regarding the help, the weight date should be seen as end of period datr. Does this mean up to this date the corresponding weights are valid? – math Sep 11 '14 at 19:37
• It let's the weights float (as in moved by the market) during the periods not in the weights matrix, the weight matrix is NOT invoked on periods not in weights. – Kyle Balkissoon Sep 12 '14 at 14:31
• Thanks for your patience. I had a look at your edited answer. It seems that it uses a simple compounding, is this correct? But if the initial Returns are continuously compounded they are not aligned any more, right? Just one example to be sure: Assume we have two rebalancing dates (of weights): 1st of January and 1st of March. Returns are on a daily basis. So all returns between 2nd of January and 1st of March are multiplied by the weights given on the 1st of Jan, correct? – math Sep 14 '14 at 8:09
• and a last question before accepting your answer: As output I get an xts object with the return per period. are these returns simple or continuous, i.e. can I just sum them up to get the cumulative return over the whole period? – math Sep 14 '14 at 17:30

I found out that the upper time series is the result of a call

    > tail(Return.rebalancing(edhec,weights))
portfolio.returns
2009-03-31       0.005082048
2009-04-30       0.022982981
2009-05-31       0.037432398
2009-06-30       0.011107189
2009-07-31       0.025580507
2009-08-31       0.017983519


(by optical comparison. ;-) )

A glance into the code reveals that the outpout is a result of successive calls (for loop) to Return.portfolio(), each taking as input the return timeseries between two different dates and the weight vector corresponding to the starting date of the time interval.

In short: It creates a time series of a rebalanced portfolio where the rebalancing dates and weights are given by weights.

Thats how the returns are calculated by Return.portfolio().

Also, for the two additional columns issue I found out, that Return.portfolio() has a line where it selects the right columns, effectively doing something like edhec[,colnames(weights[1,])]