quantlab.portfolio.base.CovarianceEstimator#

class quantlab.portfolio.base.CovarianceEstimator(config)[source]#

Bases: _Configured, ABC

Base class of every covariance estimator: the covariance of returns at one bar.

A covariance estimator is what a rule that prices risk holds. It is not trained, has no checkpoint and is not a BaseModel: it is run at every bar from what the context holds, such as the trailing return window (Ledoit-Wolf), or reads a forecast stored ahead (a factor risk model’s stores, through FactorRiskStoreEstimator). A forecast that feeds it, such as predicted volatility, comes from a model in quantlab/model through the predictor; the estimator only combines it with what it estimates. It returns a covariance and nothing else, so any rule that needs one (mean-variance, minimum variance, risk parity) can hold it.

Subclass it, set config_cls to a dataclass of the model’s parameters (with a lookback_bars field when it reads a return window) and implement estimate. The estimate is of one-bar returns; a rule scales it to its own horizon.

An estimator reading a factor risk model declares it in declared_inputs(); the decision inputs take the model’s exposures from the model itself (FactorRiskModel.exposures, so a decision, the model’s stores, attribution and bias statistics share one source) and its estimate store’s row, and put their values at the bar in context.risk_exposures and context.risk_estimate: the estimator reads no store. Its estimate is a quantlab.risk.base.ReturnCovariance; one in factor form is a FactorRiskForecast, whose factor_form() makes the mean-variance optimiser build a low-rank risk term.

Parameters:
configdataclass instance

An instance of config_cls.

Examples

>>> from quantlab.portfolio.config import LedoitWolfEstimatorConfig
>>> from quantlab.portfolio.predefined.ledoit_wolf import LedoitWolfEstimator
>>> risk = LedoitWolfEstimator(LedoitWolfEstimatorConfig(lookback_bars=60))
>>> isinstance(risk, CovarianceEstimator), risk.declared_inputs().lookback_bars
(True, 60)
declared_inputs()[source]#

What estimate reads from a context: its return window, its risk model.

By default a lookback_bars-bar return window when the config has a lookback_bars field (none otherwise), from lookback_bars + 1 prices. A model whose coverage reads staleness reaches further back (LedoitWolfEstimator); one reading a factor risk model declares it (FactorRiskStoreEstimator).

Examples

>>> risk.declared_inputs().lookback_bars
60
abstractmethod estimate(context, volatility=None)[source]#

Estimate the covariance of one-bar returns at the context’s bar.

Parameters:
contextPortfolioContext

The bar’s context; its returns window is the history.

volatilityxr.DataArray, optional

Per-symbol one-bar volatilities on symbol to use in place of the historical ones.

Returns:
ReturnCovariance

The covariance over the symbols with enough history: a CovarianceEstimate, or a FactorRiskForecast when the model has a factor form.

Examples

>>> risk.estimate(context).symbols.tolist()
['AAA', 'BBB', 'CCC']
pools_symbols = False#

Whether one symbol’s estimate depends on the other symbols the context holds (Ledoit-Wolf’s shrinkage is estimated over all of them): a run whose rule holds such an estimator keeps its whole price axis (PortfolioConstructor.keeps_every_symbol).

takes_volatility = True#

Whether estimate takes per-symbol volatilities in place of its own: a rule asking for them (volatility_label) refuses an estimator that does not, when it is constructed.