When aggregating over both time and assets, the order of aggregation matters.
We have the weights for a portfolio and we want to use those and a matrix of returns over time to compute the (long-term) portfolio return.
“A tale of two returns” tells us that aggregation over time is easiest to do in log returns and aggregation over assets is done with simple returns.
An example of when you might do this task is in “Jackknifing portfolio decision returns”.
Some hypothetical data are used.
The prices for our example are:
A B C 2007 24 48 54 2008 30 30 31 2009 45 38 63 2010 63 37 88 2011 95 36 97
The simple returns are:
A B C 2008 0.2500000 -0.37500000 -0.4259259 2009 0.5000000 0.26666667 1.0322581 2010 0.4000000 -0.02631579 0.3968254 2011 0.5079365 -0.02702703 0.1022727
The log returns are:
A B C 2008 0.2231436 -0.47000363 -0.55499684 2009 0.4054651 0.23638878 0.70914752 2010 0.3364722 -0.02666825 0.33420209 2011 0.4107422 -0.02739897 0.09737416
The initial weights — at the end of 2007 — are:
A B C 0.25 0.50 0.25
The starting ingredients are:
- starting weights
- log return matrix
The steps are:
- sum the log returns for each asset
- transform the time-aggregated log returns to simple returns
- multiply by the weights and sum
At the end of the process we have the simple return for the portfolio over the whole time period.
This calculation gives us a simple return of 81.37%.
One easy way to get it wrong is to start with:
- starting weights
- simple returns over time
A wrong procedure is:
- use the starting weights and the simple returns to collapse to portfolio returns at each time point
- transform to log returns
- aggregate across time by summing the log returns
- transform to a simple return
The subtle error is in the first step. It implicitly assumes that the weights are constant when in fact they change through time.
This calculation gives us a simple return of 57.44%.
Weights are mythical
Ultimately the problem is that weights are figments of our imagination. The real things we have are positions and prices. Weights are derived from these and change through time as prices change.
We can create the positions with approximately these weights for a portfolio worth one million:
A B C 10417 10417 4630
The calculation using the positions is merely to find the starting and ending value of the portfolio, then compute the return from those two numbers. That gives us a simple return of 81.37%.
These calculations are easy in R.
right <- sum(wt07 * (exp(colSums(logRet)) - 1)) wrong <- exp(sum(log(simpleRet %*% wt07 + 1))) - 1
The results are:
> right  0.8136574 > wrong  0.5743759
The positions are created with:
position0 <- round(1e6 * wt07 / priceMat[1,])
They are then used like:
> sum(position0 * priceMat[5,]) / + sum(position0 * priceMat[1,]) - 1  0.8136572
Portfolio Probe calculation
Portfolio Probe thinks of portfolios as their positions.
Getting either portfolio return is a single, simple command:
require(PortfolioProbe) valuation(position0, priceMat, returns="simple") valuation(position0, priceMat, returns="log")
The weights at a single time point are found like:
> valuation(position0, priceMat[1,])$weight A B C 0.249997 0.499994 0.250009
scraping the price matrix
Here is one way of getting the price matrix into your R session under Windows.
Highlight the price matrix — including the column names — from above and copy it. Then do the command:
priceMat <- read.table(text=readClipboard(), header=TRUE)
Once you have the price matrix, you can easily calculate the two return matrices:
simpleRet <- tail(priceMat, -1) / head(priceMat, -1) - 1 logRet <- diff(log(priceMat))