Today, we go back a bit to where we probably should have started in the first place, but it wouldn’t have been as much fun. In our previous work on volatility, we zipped through the steps of data import, tidy and transformation. Let’s correct that oversight and do some spade work on transforming daily asset prices to monthly portfolio log returns.
Our five-asset portfolio will consist of the following securities and weights:
+ SPY (S&amp;P500 fund) weighted 25%
+ EFA (a non-US equities fund) weighted 25%
+ IJS (a small-cap value fund) weighted 20%
+ EEM (an emerging-mkts fund) weighted 20%
+ AGG (a bond fund) weighted 10%
A brief interlude on portfolios: a portfolio is a weighted collection of assets (its etymology harkens back to the Latin for “to carry sheets of paper”, which I s’pose made its way to the world of investments because securities used to be sheets of paper). The theoretical reason that rational investors prefer a portfolio to a single asset is that a portfolio can offer a better risk/return trade-off due to low or negative covariance amongst portfolio components.
Back to the task at hand: transform a collection of daily ETF prices into an object of portfolio log returns.
Let’s load up our packages.
library(tidyverse)
library(tidyquant)
library(timetk)
First, we import daily prices for the five ETFs, using getSymbols to grab the data, map(~Ad(get(.))) to select adjusted prices only, and reduce(merge) to mash our five prices into one xts object.
# The symbols vector holds our tickers. symbols % reduce(merge) %__%
`colnames% group_by(asset) %__% mutate(returns = (log(returns) - log(lag(returns))))
Have a peek at both asset return objects.
head(asset_returns_xts)
## SPY EFA IJS EEM AGG
## 2005-02-28 0.020688126 0.037150948 0.02860922 0.09241734 -0.003721035
## 2005-03-31 -0.018461970 -0.026583514 -0.02388198 -0.08240681 -0.009790455
## 2005-04-29 -0.018913092 -0.016309073 -0.05255677 -0.01255390 0.017081857
## 2005-05-31 0.031716351 -0.008674664 0.05973603 0.03111818 0.008242118
## 2005-06-30 0.001514103 0.014225362 0.03840792 0.03892299 0.008724056
## 2005-07-29 0.037547542 0.029527397 0.05677107 0.07400825 -0.010408874
head(asset_returns_long)
## # A tibble: 6 x 3
## # Groups: asset [1]
## date asset returns
## ## 1 2005-01-31 SPY NA
## 2 2005-02-28 SPY 0.020688126
## 3 2005-03-31 SPY -0.018461970
## 4 2005-04-29 SPY -0.018913092
## 5 2005-05-31 SPY 0.031716351
## 6 2005-06-30 SPY 0.001514103
Do we notice any differences?
First, have a look at the left most part of asset_returns_xts, where the date is stored. The asset_returns_xts has a date index, not a column. It is accessed via index(asset_returns_xts). asset_returns_long has a column called “date”, accessed via the $date convention, i.e., asset_returns_long$date.
Second, notice the first date observation for January of 2005. asset_returns_long contains NA, and asset_returns_xts excludes the observation completely. Does it matter? It depends. In a few weeks when we get to the Sortino Ratio, we will see that it can matter quite a bit.
Third, asset_returns_xts is in wide format, which in this case means there is a column for each of our assets. This is the format that xts likes, and it’s the format that is easier to read as a human. However, asset_returns_long is in long, tidy format so that each variable has its own column. It’s a bit harder to read as human, but the tidyverse wants data in this format.
Now on to constructing a portfolio and calculating returns. To turn these five ETFs into a portfolio we need to assign them weights. Let’s first create a weights vector.
w