quantlab.portfolio.base.LowRankCovarianceEstimate#
- class quantlab.portfolio.base.LowRankCovarianceEstimate(symbols, exposures, specific_variance)[source]#
Bases:
objectA covariance estimate
B B' + diag(D)of low rank plus a diagonal, without risk factors.A shrunk sample covariance of a
T-bar window is one (Ledoit-Wolf:Bthe scaled demeaned window,k = Tcolumns): itsfactor_form()is(B, I, D), so an optimiser prices risk without the dense[n, n]matrix, when there are enough symbols for that to be faster (LOW_RANK_MIN_RATIO). The columns ofBare not risk factors, sofactor_exposurerefuses as a dense estimate’s does.- Attributes:
- symbolsnp.ndarray
The
nsymbols covered, the order ofexposures’ rows andspecific_variance.- exposuresnp.ndarray
B,[n, k].- specific_variancenp.ndarray
D,[n].
Examples
>>> low_rank = LowRankCovarianceEstimate( ... symbols=np.array(["AAA", "BBB"]), ... exposures=np.array([[0.1], [0.05]]), ... specific_variance=np.array([0.01, 0.02]), ... ) >>> low_rank.covariance array([[0.02 , 0.005 ], [0.005 , 0.0225]]) >>> low_rank.variance array([0.02 , 0.0225])
- property covariance#
The dense
[n, n]covarianceB B' + diag(D), built on each call.Examples
>>> low_rank.covariance.shape (2, 2)
- factor_exposure(name, symbols)[source]#
Refuse: the columns of
Bare not risk factors.- Raises:
- ValueError
Always.
Examples
>>> low_rank.factor_exposure("market", np.array(["AAA"])) Traceback (most recent call last): ... ValueError: the covariance estimate has no risk factors, so no exposure to 'market'
- factor_form()[source]#
Return
(B, I, D), the identity as the columns’ covariance, when it is the cheaper form.An optimiser’s low-rank risk term costs about
n k^2and the dense one aboutn^2: with CLARABEL on a long-only problem,k = 252took 4.5 s against 5.6 s dense at 3,000 symbols and 0.44 s against 0.15 s at 500. The form is returned whenn >= LOW_RANK_MIN_RATIO * k, elseNoneand the optimiser prices the densecovariance.Examples
>>> low_rank.factor_form() is None # 2 symbols, rank 1: dense is cheaper True >>> wide = LowRankCovarianceEstimate( ... symbols=np.arange(6), exposures=np.full((6, 1), 0.1), ... specific_variance=np.full(6, 0.01)) >>> exposures, factor_covariance, specific = wide.factor_form() >>> factor_covariance array([[1.]])
- scaled(factor)[source]#
Return the estimate with every entry multiplied by
factor(Bby its square root).Examples
>>> low_rank.scaled(5).variance array([0.1 , 0.1125])
- subset(rows)[source]#
Return the estimate over the symbols at positions
rows, in that order.Examples
>>> low_rank.subset(np.array([1])).variance array([0.0225])
- property variance#
Each covered symbol’s variance,
|B_i|^2 + D_i, without the dense matrix.Examples
>>> low_rank.variance array([0.02 , 0.0225])