Note
Go to the end to download the full example code. or to run this example in your browser via Binder
Black & Litterman#
This tutorial shows how to use the BlackLitterman
estimator in
the MeanRisk
optimization.
A prior estimator fits a PriorModel
containing
the distribution estimate of asset returns. It represents the investor’s prior beliefs
about the model used to estimate such distribution.
The PriorModel
is a dataclass containing:
mu
: Expected returns estimation
covariance
: Covariance matrix estimation
returns
: assets returns estimation
cholesky
: Lower-triangular Cholesky factor of the covariance estimation (optional)
The BlackLitterman
estimator estimates the PriorModel
using the Black & Litterman
model. It takes as input a prior estimator used to compute the prior expected returns
and prior covariance matrix, which are updated using the analyst’s views to get the
posterior expected returns and posterior covariance matrix.
In this tutorial we will build a Maximum Sharpe Ratio portfolio using the
BlackLitterman
estimator.
Data#
We load the S&P 500 dataset composed of the daily prices of 20 assets from the SPX Index composition starting from 1990-01-02 up to 2022-12-28:
from plotly.io import show
from sklearn.model_selection import train_test_split
from skfolio import Population, RiskMeasure
from skfolio.datasets import load_sp500_dataset
from skfolio.optimization import MeanRisk, ObjectiveFunction
from skfolio.preprocessing import prices_to_returns
from skfolio.prior import BlackLitterman
prices = load_sp500_dataset()
X = prices_to_returns(prices)
X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)
Analyst views#
Let’s assume we are able to accurately estimate views about future realization of the
market. We estimate that Apple will have an expected return of 25% p.a. (absolute
view) and will outperform General Electric by 22% p.a. (relative view). We also
estimate that JPMorgan will outperform General Electric by 15% p.a (relative view).
By converting these annualized estimates into daily estimates to be homogenous with
the input X
, we get:
analyst_views = [
"AAPL == 0.00098",
"AAPL - GE == 0.00086",
"JPM - GE == 0.00059",
]
Black & Litterman Model#
We create a Maximum Sharpe Ratio model using the Black & Litterman estimator that we fit on the training set:
model_bl = MeanRisk(
risk_measure=RiskMeasure.VARIANCE,
objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
prior_estimator=BlackLitterman(views=analyst_views),
portfolio_params=dict(name="Black & Litterman"),
)
model_bl.fit(X_train)
model_bl.weights_
array([4.73670065e-01, 2.66647584e-02, 1.24355699e-09, 2.02231082e-02,
7.84980192e-03, 1.73718908e-10, 3.40597193e-09, 2.51376159e-03,
3.27250993e-01, 4.77910456e-03, 1.72985253e-02, 3.34073945e-02,
2.11421641e-03, 1.65451603e-02, 1.79851683e-08, 5.45803069e-09,
3.40429482e-02, 3.36401076e-02, 3.99610901e-09, 2.27962284e-08])
Empirical Model#
For comparison, we also create a Maximum Sharpe Ratio model using the default Empirical estimator:
model_empirical = MeanRisk(
risk_measure=RiskMeasure.VARIANCE,
objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
portfolio_params=dict(name="Empirical"),
)
model_empirical.fit(X_train)
model_empirical.weights_
array([9.43855248e-02, 2.09226948e-10, 7.30530766e-11, 1.20898034e-01,
3.18441126e-02, 1.28498817e-10, 1.28522027e-04, 1.24120028e-01,
1.43231855e-10, 2.78010014e-02, 2.19871439e-10, 2.49938736e-10,
1.16368341e-01, 5.73909314e-02, 1.74856659e-09, 1.09507654e-01,
8.64772972e-02, 1.84021249e-01, 1.34862950e-02, 3.35710067e-02])
Prediction#
We predict both models on the test set:
pred_bl = model_bl.predict(X_test)
pred_empirical = model_empirical.predict(X_test)
population = Population([pred_bl, pred_empirical])
population.plot_cumulative_returns()
Because our views were accurate, the Black & Litterman model outperformed the Empirical model on the test set. From the below composition, we can see that Apple and JPMorgan were allocated more weights:
fig = population.plot_composition()
show(fig)
Total running time of the script: (0 minutes 0.415 seconds)