Calculating Portfolio Returns from Adjusted Prices and Rebalancing
Summary
The document addresses a concern that a 50/50 portfolio of two stocks shows cumulative performance above 100 percent. The response checks the adjusted-price histories individually and finds that gains of this scale can be plausible over the sample shown. Adjusted prices can be used to calculate period returns; they do not need to be rescaled simply because cumulative return exceeds 100 percent.
The key portfolio-construction detail is that the two return series must be aligned by timestamp before combining them. Averaging their daily returns equally and compounding the result assumes the portfolio is reset to equal weights every period. That is a daily rebalanced strategy, whose performance can differ from a portfolio that buys equal dollar amounts once and then lets weights drift. The example and cited stock returns are limited to the stated historical window, and they do not establish expected future performance or validate every aspect of the data source.
Key ideas
- Cumulative portfolio returns above 100 percent are possible and do not by themselves imply a calculation error.
- Price series should be merged on their timestamps before period returns are combined.
- Averaging daily stock returns equally and compounding assumes equal-weight rebalancing each day.
- A buy-and-hold portfolio can have different returns as its asset weights drift over time.
Tags
Full text
# R: Calculating cumulative return of a portfolio
# R: Calculating cumulative return of a portfolio
I've downloaded adjusted closing prices from Yahoo using the `quantmod`-package, and used that to create a portfolio consisting of 50% `AAPL`- and 50% `FB`-stocks.
When I plot the cumulative performance of my portfolio, I get a performance that is (suspiciously) high as it is above 100%:
```
library(ggplot2)
library(quantmod)
cmp <- "AAPL"
getSymbols(Symbols = cmp)
tail(AAPL$AAPL.Adjusted)
cmp <- "FB"
getSymbols(Symbols = cmp)
tail(FB$FB.Adjusted)
df <- data.frame("AAPL" = tail(AAPL$AAPL.Adjusted, 1000),
"FB" = tail(FB$FB.Adjusted, 1000))
for(i in 2:nrow(df)){
df$AAPL.Adjusted_prc[i] <- df$AAPL.Adjusted[i]/df$AAPL.Adjusted[i-1]-1
df$FB.Adjusted_prc[i] <- df$FB.Adjusted[i]/df$FB.Adjusted[i-1]-1
}
df <- df[-1,]
df$portfolio <- (df$AAPL.Adjusted_prc + df$FB.Adjusted_prc)*0.5
df$performance <- cumprod(df$portfolio+1)-1
df$idu <- as.Date(row.names(df))
ggplot(data = df, aes(x = idu, y = performance)) + geom_line()
```
A cumulative performance above 100% seems very unrealistic to me. This lead me to think that maybe it is necessary to adjust/scale the downloaded data from `quantmod` before using it?
## Answer by Enrico Schumann (score 3)
https://quant.stackexchange.com/a/44433
Have you checked the performance of the particular stocks?
```
library("quantmod")
library("PMwR")
cmp <- "AAPL"
aapl <- getSymbols(Symbols = cmp, auto.assign = FALSE)$AAPL.Adjusted
cmp <- "FB"
fb <- getSymbols(Symbols = cmp, auto.assign = FALSE)$FB.Adjusted
returns(window(merge(aapl, fb), start = as.Date("2015-1-1")),
period = "itd")
## AAPL.Adjusted: 73.2% [02 Jan 2015 -- 04 Mar 2019]
## FB.Adjusted: 113.3% [02 Jan 2015 -- 04 Mar 2019]
```
So this seems quite realistic (and you may verify this performance via other sources as well). However, you should properly merge the time-series on their timestamps. Also, the portfolio performance you compute assumes that you rebalance to equal weights every period (i.e. day).Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.