Black-Litterman
Calculate the Black-Litterman expected returns and the weights they lead to. The starting point is the return the market implies through its capitalization weights: the excess return Π = δΣw_mkt at which holding the market is optimal, plus the risk free rate, so the Implied Return is a total return. Views then move these returns towards the investor’s expectations, in proportion to the confidence in each view. The result avoids the extreme weights that historical average returns give.
Views are absolute ({“AAPL”: 0.10}: AAPL returns 10% a year in total, risk free rate included) or relative ({“AAPL-MSFT”: 0.02}: AAPL beats MSFT by 2% a year). Without a confidence, a view is as uncertain as the variance of the view portfolio scaled by tau; a confidence c scales that by (1 - c) / c, Idzorek’s confidence method in the closed form of Walters (2014). The weights are the mean-variance portfolio of the Black-Litterman returns with the same risk aversion. Without views, or with relative views only, the risk free rate shifts every return by the same amount and leaves the weights unchanged; an absolute view is compared with the implied total return, so there it matters.
For more information, see the following papers:
- Black, F. and Litterman, R. (1992). “Global Portfolio Optimization.” Financial Analysts Journal, 48(5), 28-43.
- He, G. and Litterman, R. (1999). “The Intuition Behind Black-Litterman Model Portfolios.” Goldman Sachs Investment Management Research.
- Idzorek, T. (2005). “A Step-by-Step Guide to the Black-Litterman Model: Incorporating User-Specified Confidence Levels.” Working paper.
- Walters, J. (2014). “The Black-Litterman Model in Detail.” https://ssrn.com/abstract=1314585
Also known as: BL model, equilibrium returns with views.
Black-Litterman in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_black_litterman_weights as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["AAPL", "MSFT", "JNJ", "XOM"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
toolkit.portfolio.get_black_litterman_weights(
views={"XOM": 0.10, "AAPL-MSFT": 0.02}
)
Or, after setting up the Finance Toolkit MCP, ask:
What Black-Litterman weights do Apple, Microsoft, Johnson & Johnson and ExxonMobil get with the views that ExxonMobil returns 10% and Apple beats Microsoft by 2 percentage points, based on 2021 to 2025?
Which returns:
| Market Weight | Implied Return | Black-Litterman Return | Weight | |
|---|---|---|---|---|
| AAPL | 0.4899 | 0.1752 | 0.1769 | 0.4738 |
| MSFT | 0.376 | 0.1531 | 0.155 | 0.3729 |
| JNJ | 0.0614 | 0.0509 | 0.052 | 0.0145 |
| XOM | 0.0727 | 0.0709 | 0.0853 | 0.1387 |
Parameters
get_black_litterman_weights accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
views | dict[str, float] | None | The annualized views, absolute views as total returns, as described above. Defaults to None, which returns the market implied returns. | None, which returns the market implied returns |
view_confidences | dict[str, float] | None | The confidence per view, between 0 and 1. Defaults to None, which sets each view’s uncertainty to the variance of the view scaled by tau. | None, which sets each view's uncertainty to the variance of the view scaled by tau |
market_weights | dict[str, float] | None | The market weight per asset. Defaults to None, which uses the market capitalizations of the assets. | None, which uses the market capitalizations of the assets |
risk_aversion | float | The risk aversion δ of the market. Defaults to 2.5. | 2.5 |
tau | float | The uncertainty of the implied returns relative to the covariance matrix. Defaults to 0.05. | 0.1 |
period | str | The frequency of the returns the covariance matrix is estimated from. Defaults to “daily”. | "weekly" |
minimum_weight | float | The lowest weight an asset may have. Defaults to 0. | 0 |
maximum_weight | float | The highest weight an asset may have. Defaults to 1. | 1 |
rounding | int | None | The number of decimals to round the results to. Defaults to None, which uses the Toolkit’s rounding. | 2 |