1. Sharpe ratios; features and targets
How do we decide on an ideal portfolio? Here we'll learn how to choose optimal portfolios using the Sharpe ratio, and how to train a machine learning regressor to predict optimal portfolio weights.
2. Which is the best portfolio?
We have multiple choices for the "best" portfolio. We could go for lowest volatility, but the returns aren't very high. We could also go for the highest returns, but then volatility is higher. There's another option.
3. The Sharpe ratio
We could also use the Sharpe ratio. The best portfolio from the Sharpe ratio is the orange X on the plot.
4. The Sharpe ratio
The Sharpe ratio is found by taking the portfolio returns, subtracting the risk-free return rate, and dividing by portfolio volatility. Here, we'll assume a 0% risk-free rate, which means holding cash.
5. Getting our Sharpe ratios
To calculate Sharpe ratios from our data, we'll start with empty dictionaries. These will store Sharpe indices for portfolios, and indices of the best Sharpe ratio for each date.
Then we loop through our dates by using portfolio_returns keys, and calculate the Sharpe ratios. We get returns from the portfolio_returns for that date, as well as a counter, i, using Python's enumerate. Volatility is taken from the portfolio_volatility for that date and index, i. Then we use setdefault on the sharpe_ratio dictionary. This sets the value for the current date an empty list if it doesn't exist. We then append the ratio of returns and volatility to the list of Sharpe ratios for that date.
Finally, we use numpy's argmax() function to find the index where the Sharpe ratio is largest. The portfolio weights where the Sharpe ratio is highest will be our targets for machine learning.
6. Create features
Next, we need features for machine learning. We'll stay simple and use moving averages of stock prices. Here we'll use an exponentially-weighted moving average, or EWMA, meaning recent prices are given a larger weight than older prices according to an exponential curve.
We calculate the daily EWMA with a span of 30. This means the last 30 days are taken into account in the EWMA. We then resample the moving average to the business month start, or BMS, which means the first business day of the month. Finally, we shift our time index ahead by one, which lines up the previous month's EWMA with the best portfolio from the current month.
7. Calculate features and targets
We can now calculate features and targets. Our features will be the EWMA we just created, and the targets are the best portfolio according to the Sharpe index. We start with a few empty lists to store the features and targets.
Then we loop through our monthly EWMA indices and values using pandas' iterrows() method. This allows us to then get the portfolio index where we had the best Sharpe ratio using max_sharpe_idxs and append the portfolio_weights to our targets list. Then we append the EWMA to the features list. Lastly, we convert both to numpy arrays.
8. Re-plot efficient frontier
We'll replot the efficient frontier with our ideal portfolio. We grab the latest date in the data from our covariances keys, then get the returns and volatility for that date. We then scatter volatility versus returns. Next, we get the portfolio index where we have the best Sharpe ratio from max_sharpe_idxs, then create a point for that portfolio. We set the marker argument to be an x, and the color is different from the regular points so it'll stand out.
9. Efficient frontier with Sharpe
Our plot looks like this, with the orange x designating the point with the best Sharpe ratio.
10. Get Sharpe!
Now it's your turn to find ideal portfolios using the Sharpe ratio.