We start by loading the CRSP data set. To keep the analysis simple we work with a balanced panel and exclude tickers, that are not traded for the full period. We end up with a tradable universe of 107 stocks.
We now turn to produce the summary statistics.| N stocks | Start date | End date | Mean | SD | Min | Max |
|---|---|---|---|---|---|---|
| 731 | 1960-02-01 | 2020-12-01 | 9.4 | 28.8 | -72.9 | 151.3 |
To find the optimal weight we incorporate the ‘compute_efficient_weights’ function from chapter 11.4 in (Scheuss et. al 2022), where \(\mu\) denotes the historical mean return, sigma, \(\Sigma\) is the covariance matrix, gamma, \(\gamma\), is the coefficient of risk aversion (4 by pre-specification), lambda, \(\lambda\) is the transaction costs and w_prev is the weight before re-balancing. The function calculates the efficient portfolio weight in general form, while allowing for transaction costs. The transaction costs are conditional on the holdings before reallocation. The figure shows that if lambda (tr. cost) is zero, the portfolio allocation resembles the standard mean-variance efficient framework, where the aim is to maximize the sharpe ratio.\
The first step is to calculate the returns matrix, where the entire series of returns for each stock is obtained. From this it is possible to calculate the historical mean, \(\mu\) and covariance matrix, \(\Sigma\).
Next we perform Ledoit-Wolf shrinkage on the variance-covariance matrix. This comes in handy, as the method serves as an effective way of overcoming issues related to var-covar matrices in large dimensions. The function is rather complex, why we refer the reader to chapter 9.2 in “Exercises for Advanced Empirical Finance: Topics and Data Science” by (Scheuss et. al 2022) for a deeper explanation.
To calculate the optimal portfolio with 1/N initial we will use the hard-coded weight parameter from the function, as this provides an initially equally-weighted portfolio.
The higher the level of transaction costs, the closer will the optimal portfolio will be to the equally-weighted. Turnover penalization will make the investor reluctant towards making trades, as it is costly, and therefore choose appropriate portfolio-weights. This also makes sense as increasing transaction costs implies a higher demanded return - at some point, the costs just will not outweight the gains from the transactions, why investors will be reluctant to rebalance their portfolio.
With rolling window forecasts, we recursively re-estimate the model and store the one ahead covariance forecasts. We implement the strategy in the following way. For the backtesting, we recompute optimal weight based purely on past available data. We use a window length of 150 periods which gives us 333 periods of performance. We test three strategies: A transaction cost-adjusted portfolio (MV (TC)), a mean-variance portfolio without short-selling, but with transaction costs (MV (No SS)) and an equally weighted naive portfolio (Naive). Initial weights are set as a equally weighted portfolio and we evaluate the portfolios through the mean returns nets of transaction costs, std. deviation of returns net of transaction costs, the sharpe ratio and the portfolio turnover.
With the helper functions, we are ready to perform the rolling-window estimation. This is done using a for loop through all the periods. Lastly, the performance is evaluated through the summarized key figures.| strategy | Mean | SD | Sharpe Ratio | Turnover |
|---|---|---|---|---|
| MV (No SS) | 5.03 | 18.07 | 0.28 | 1.84 |
| MV (TC) | -16.46 | 47.07 | NA | 8.46 |
| Naive | 9.83 | 15.44 | 0.64 | 0.00 |
As presented in the above table, the best performing strategy is the naive portfolio, where we rebalance to an equally weighted portfolio in each period. Using this strategy, we are able to generate a mean return of 9.83% which is significantly better than both of the other strategies. Moreover, the sharpe ratio suggest that the naive portfolio handles risk more efficiently than both of the other portfolios. It also becomes evident that transaction costs tend to kill returns, as both the naive and the portfolio with no short-selling strongly outperforms the transaction cost-adjusted portfolio. We thus see a negative correlation between turnover and returns, which underlines the importance of accounting for transaction costs when building a trading strategy.
An argument for the out-of-sample experiment being “true” is that the observations used to estimate sigma (i.e., the training data) are not the one’s used for the prediction. Thus, the forecast is made using a set of un-used observations, which, by definition, makes it an out-of-sample experiment. However, the experiments aim of testing how transaction costs affects the performance by rebalancing ex ante is made using some relatively unrealistic assumptions on the structure of transaction costs as we use a standardized cost of 200 bps for all transactions. As this does not reflect the true cost structure in the market, one could argue that the results fail to present a real representation of the effect of transaction costs.