markowitz.views¶
markowitz.views
¶
Black-Litterman posterior construction from absolute and relative views.
Public re-exports
- :class:
BlackLitterman-- the main posterior-construction class. - :class:
Views, :class:AbsoluteView, :class:RelativeView-- view-specification dataclasses and their container. - :func:
implied_returns, :func:infer_delta-- equilibrium helpers. - :func:
idzorek_omega, :func:idzorek_omega_approx-- confidence-basedOmegaconstruction. - Exception hierarchy rooted at :class:
BlackLittermanError.
AbsoluteView(asset: str, expected_return: float, confidence: float | None = None)
dataclass
¶
A point estimate on a single asset's expected excess return.
BlackLitterman(cov: pd.DataFrame, market_weights: pd.Series, views: Views | None = None, *, tau: float = 0.05, delta: float = 2.5, omega: np.ndarray | None = None, omega_method: str = 'he_litterman', posterior_covariance_mode: str = 'full', risk_free_rate: float | None = None)
¶
Construct a Black-Litterman posterior from a covariance prior and views.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cov
|
DataFrame
|
Prior covariance matrix as a labelled |
required |
market_weights
|
Series
|
Market-cap weights series aligned to the covariance index. |
required |
views
|
Views | None
|
:class: |
None
|
tau
|
float
|
Prior-scaling parameter. Must be strictly positive. Defaults to
|
0.05
|
delta
|
float
|
Representative-investor risk-aversion coefficient. Defaults to
|
2.5
|
omega
|
ndarray | None
|
Optional pre-computed view-uncertainty matrix; if supplied,
|
None
|
omega_method
|
str
|
Strategy used to derive |
'he_litterman'
|
posterior_covariance_mode
|
str
|
|
'full'
|
risk_free_rate
|
float | None
|
Optional metadata used by :meth: |
None
|
Source code in src/markowitz/views/black_litterman.py
implied_returns() -> pd.Series
¶
Return the equilibrium-implied prior pi = delta * Sigma * w_mkt.
Source code in src/markowitz/views/black_litterman.py
posterior_covariance() -> pd.DataFrame
¶
Return the posterior covariance matrix.
Source code in src/markowitz/views/black_litterman.py
posterior_returns() -> pd.Series
¶
Return the Black-Litterman posterior excess-return vector.
posterior_weights(*, constrained: bool = False) -> pd.Series
¶
Return the unconstrained tangency weights implied by the posterior.
w_BL = (delta * Sigma_BL)^{-1} * mu_BL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
constrained
|
bool
|
If |
False
|
Source code in src/markowitz/views/black_litterman.py
summary() -> pd.DataFrame
¶
Return a per-asset table with prior, posterior and weight tilts.
Source code in src/markowitz/views/black_litterman.py
BlackLittermanError
¶
Bases: Exception
Base class for all errors raised by :mod:markowitz.views.
OmegaSpecificationError
¶
Bases: BlackLittermanError
Raised when the view-uncertainty matrix Omega is mis-specified.
Triggered for shape mismatches, non-positive-definite supplied matrices, or
inconsistent combinations of omega, omega_method and per-view
confidences.
RelativeView(long_leg: Mapping[str, float], short_leg: Mapping[str, float], spread: float, confidence: float | None = None)
dataclass
¶
A spread view between a long and a short basket of assets.
The basket weights specify how each leg is constructed: long_leg maps
asset names to non-negative coefficients and likewise short_leg. The
resulting pick row is long_leg - short_leg and must sum to zero (this
is verified at construction time).
TauScaleError
¶
Bases: BlackLittermanError
Raised when the prior-scaling parameter tau is invalid (non-positive).
ViewValidationError
¶
Bases: BlackLittermanError
Raised when a user-supplied view fails structural validation.
Examples:
- A relative view whose pick-row coefficients do not sum to zero.
- A view that references an asset which is not present in the universe.
- A confidence value outside the closed interval
[0, 1].
Views(views: Sequence[ViewSpec], assets: Sequence[str])
¶
Container that validates and serialises a list of :class:ViewSpec.
Source code in src/markowitz/views/view_specs.py
build_omega_he_litterman(tau: float, cov: np.ndarray) -> np.ndarray
¶
Return the He-Litterman diagonal Omega = diag(P tau Sigma P^T).
Source code in src/markowitz/views/view_specs.py
build_pq() -> tuple[np.ndarray, np.ndarray]
¶
Return the (P, Q) matrices for the current view set.
Source code in src/markowitz/views/view_specs.py
confidences() -> np.ndarray | None
¶
Return per-view confidences as an array, or None if unspecified.
Source code in src/markowitz/views/view_specs.py
idzorek_omega(P: np.ndarray, tau_Sigma: np.ndarray, confidences: np.ndarray, pi: np.ndarray, delta: float, w_mkt: np.ndarray, *, brent_xtol: float = 1e-10, brent_maxiter: int = 200) -> np.ndarray
¶
Exact Idzorek omega via per-view root finding (with safe fallback).
Source code in src/markowitz/views/idzorek.py
idzorek_omega_approx(P: np.ndarray, tau_Sigma: np.ndarray, confidences: np.ndarray) -> np.ndarray
¶
Closed-form Idzorek omega approximation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
P
|
ndarray
|
Pick matrix of shape |
required |
tau_Sigma
|
ndarray
|
The scaled prior covariance |
required |
confidences
|
ndarray
|
One-dimensional array of length |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Diagonal |
Source code in src/markowitz/views/idzorek.py
implied_returns(cov: pd.DataFrame, market_weights: pd.Series, delta: float = 2.5) -> pd.Series
¶
Compute the equilibrium-implied excess-return vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cov
|
DataFrame
|
Asset return covariance matrix as a square |
required |
market_weights
|
Series
|
Market-capitalisation weights indexed by asset. The index must align
with |
required |
delta
|
float
|
Representative-investor risk-aversion coefficient. Defaults to the
commonly cited value of |
2.5
|
Returns:
| Type | Description |
|---|---|
Series
|
Implied excess returns |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the covariance matrix is not square, weights cannot be aligned, or
|
Source code in src/markowitz/views/equilibrium.py
infer_delta(market_returns: pd.Series, risk_free_rate: float, ddof: int = 1) -> float
¶
Estimate the risk-aversion coefficient from market-return history.
Uses the standard identity delta = (E[r_m] - rf) / Var[r_m] where
r_m is the market portfolio return series. The series is assumed to
already be on the same periodicity as risk_free_rate (e.g. both annual
or both daily).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
market_returns
|
Series
|
Realised market returns (not excess). |
required |
risk_free_rate
|
float
|
Periodic risk-free rate matching the periodicity of
|
required |
ddof
|
int
|
Degrees-of-freedom passed through to :meth: |
1
|
Returns:
| Type | Description |
|---|---|
float
|
The implied risk-aversion coefficient. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the input series has fewer than two observations or has zero variance. |