Coverage for src/cvxmarkowitz/risk/__init__.py: 100%

10 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-15 05:21 +0000

1# Copyright 2023 Stanford University Convex Optimization Group 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14"""Risk model subpackage public API.""" 

15 

16from __future__ import annotations 

17 

18from cvxmarkowitz.model import Model 

19 

20from .cvar.cvar import CVar as CVar 

21from .factor.factor import FactorModel as FactorModel 

22from .sample.sample import SampleCovariance as SampleCovariance 

23 

24__all__ = ["CVar", "FactorModel", "SampleCovariance", "default_risk_model"] 

25 

26 

27def default_risk_model(assets: int, factors: int | None) -> Model: 

28 """Return the risk model a `Builder` uses when the caller injects none. 

29 

30 A `FactorModel` when `factors` is given, a `SampleCovariance` otherwise. 

31 

32 This rule lives here rather than in `Builder` so that the risk package owns 

33 the choice among its own members: adding a further default is a change to 

34 this subpackage, not to the abstract base class every builder inherits 

35 from. `Builder` therefore imports this function instead of the concrete 

36 model classes. 

37 

38 Note what this does *not* do: it cannot default to `CVar`, which needs 

39 `rows` and `alpha` that a builder does not carry. `CVar` stays an injected 

40 model -- pass `model={ModelName.RISK: CVar(...)}` to the builder, which 

41 skips this function entirely. 

42 

43 Args: 

44 assets: Number of assets the model is sized for. 

45 factors: Number of factors, or None for a non-factor problem. 

46 

47 Returns: 

48 A `Model` instance to register under `ModelName.RISK`. 

49 """ 

50 if factors is None: 

51 return SampleCovariance(assets=assets) 

52 

53 return FactorModel(assets=assets, factors=factors)