Coverage for src/basanos/math/_engine_base.py: 100%

14 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-09-25 12:05 +0000

1"""Validated batch core shared by `BasanosEngine` and `BasanosStream`. 

2 

3`_BatchCore` holds the three engine inputs (``prices``, ``mu``, ``cfg``), 

4validates them on construction, and composes `_CoreDataMixin` (``assets``, 

5``ret_adj``, ``vola``, ``cor``) and `_SolveMixin` (the per-timestamp solve and 

6``warmup_state``). 

7 

8It also composes `_SignalEvaluatorMixin`. The stream never calls the IC 

9methods, but the solve mixin's methods are typed ``self: _EngineProtocol`` 

10(enforced by ``tests/test_math/test_engine_protocol.py``), and that protocol 

11includes ``_ic_series``. The IC mixin is stateless, so carrying it costs nothing 

12and keeps the single-protocol convention intact. 

13 

14`BasanosEngine` subclasses it and adds the diagnostics and performance 

15mixins. `BasanosStream.from_warmup` builds a `_BatchCore` 

16directly, so the streaming path runs the same validation and solve code as the 

17batch engine without depending on the ``optimizer`` facade. 

18""" 

19 

20import dataclasses 

21 

22import polars as pl 

23 

24from ._config import BasanosConfig 

25from ._engine_core import _CoreDataMixin 

26from ._engine_ic import _SignalEvaluatorMixin 

27from ._engine_solve import _SolveMixin 

28from ._engine_validation import _validate_inputs 

29 

30 

31@dataclasses.dataclass(frozen=True) 

32class _BatchCore(_CoreDataMixin, _SolveMixin, _SignalEvaluatorMixin): 

33 """Validated ``prices`` / ``mu`` / ``cfg`` with core data access and solve logic. 

34 

35 Attributes: 

36 prices: Polars DataFrame of price levels per asset over time. 

37 mu: Polars DataFrame of expected-return signals aligned with *prices*. 

38 cfg: Immutable `BasanosConfig`. 

39 """ 

40 

41 prices: pl.DataFrame 

42 mu: pl.DataFrame 

43 cfg: BasanosConfig 

44 

45 def __post_init__(self) -> None: 

46 """Validate inputs by delegating to `_validate_inputs`.""" 

47 _validate_inputs(self.prices, self.mu, self.cfg)