5 Managing Portfolios in the Real World
5.1 Portfolio Backtesting
The preceding chapter explains and summarises the basic principles for doing mean-variance portfolio optimizations (e.g., using optimization constraints and objectives, etc.). Nonetheless, the respective mean-variance optimal portfolio weights relate to an ex-ante perspective. That implies that we do not know if such a weighting scheme really has been proven economically meaningful in the past. Therefore, this chapter introduces the topic of portfolio backtesting, which allows us to derive a deeper understanding of the return and risk drivers involved in the mean-variance optimization.
Now starts the fun in so far that we have a closer look at our portfolio optimization parameters. Backtesting allows us to get a better understanding of the return and risk drivers. Just optimizing an efficient portfolio is fine, but we now want to derive additional portfolio trading costs, etc. In the following, we will cover various (not all :)) thoughts that come with a portfolio management process.
Again we are utilizing our data set - obtained in chapter @(s-2Data).
stocks.returns.monthly %>% slice(1:2)
#> # A tibble: 20 x 10
#> # Groups: symbol [10]
#> symbol date adjusted return sp500 Mkt.RF SMB HML RF Mom
#> <chr> <yearmon> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 AAPL Jan 2000 0.795 -0.0731 -0.0418 -0.0474 0.0579 -0.0189 0.0041 0.0192
#> 2 AAPL Feb 2000 0.879 0.105 -0.0201 0.0245 0.215 -0.0981 0.0043 0.182
#> 3 ADBE Jan 2000 13.7 -0.160 -0.0418 -0.0474 0.0579 -0.0189 0.0041 0.0192
#> 4 ADBE Feb 2000 25.3 0.852 -0.0201 0.0245 0.215 -0.0981 0.0043 0.182
#> 5 AMZN Jan 2000 64.6 -0.278 -0.0418 -0.0474 0.0579 -0.0189 0.0041 0.0192
#> 6 AMZN Feb 2000 68.9 0.0668 -0.0201 0.0245 0.215 -0.0981 0.0043 0.182
#> # ... with 14 more rows
Subsequently, we generate an xts-object
to make return data understandable for the portfolioAnalytics
-package.
returns <- stocks.returns.monthly %>%
select(symbol,date,return) %>%
#needed that for the optimize.portfolio.rebalancing function
mutate(date = as.Date(date, format ="%")) %>%
spread(symbol,return) %>%
tk_xts(silent = TRUE) * 100
5.1.1 Backtest parameterisation
Before starting with the backtesting procedure, we need to specify the parameters (i) rebalancing period, (ii) transaction costs, and (iii) training period. Portfolio rebalancing allows maintaining optimal (in this case mean-variance optimal) portfolio weights, ensuring that a portfolio is continuously diversified over time. Commonly applied rebalancing frequencies are monthly, quarterly, semi-annual and annual. The optimize.portfolio.rebalancing()
function allows to define all of the prior frequencies - even better, it enables the user to deal with daily and intraday frequencies (see also endpoints {xts}
in the R Documentation). From a theoretical perspective, more frequent rebalancing (higher rebalancing activities) brings the advantage of enhanced “control” over the risk-return patterns of an investment portfolio. But this assumption only holds if there would be a frictionless economy without transaction costs. Due to transaction costs, however, there is a trade-off between rebalancing activities and portfolio turnover adjusted returns. In the following analysis, we specify quarterly rebalancing activities. Given the assumptions by the empirical finance literature ((Source?)), we apply 50 basis points (0.5%) as transaction costs - denoted as 0.0050
. Furthermore, the training period is defined as the prior 36 months.
5.1.2 Retrieving portfolio weights of backtesting procedure
After all, we are ready to run our backtesting procedure using the optimize.portfolio.rebalancing
function and using the above-defined input arguments. The optimize.portfolio.rebalancing
provides the respective optimal portfolio weights which are afterwards needed for the calculation portfolio returns.
5.1.3 Calculate portfolio returns of backtesting procedure
Based on the previously calculated portfolio weights, this section deals with backtesting portfolio returns. The following analysis considers two scenarios: (i) gross returns without considering the portfolio turnover rate, and (ii) net returns with consideration of portfolio turnover rate where transaction costs come into play. At the beginning, we generate a return data set (Tibble) which refers to the backtesting period between Jan 2003
and Dec 2017
. Afterwards, we transform it into an xts object.
–>