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
« 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`.
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``).
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.
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"""
20import dataclasses
22import polars as pl
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
31@dataclasses.dataclass(frozen=True)
32class _BatchCore(_CoreDataMixin, _SolveMixin, _SignalEvaluatorMixin):
33 """Validated ``prices`` / ``mu`` / ``cfg`` with core data access and solve logic.
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 """
41 prices: pl.DataFrame
42 mu: pl.DataFrame
43 cfg: BasanosConfig
45 def __post_init__(self) -> None:
46 """Validate inputs by delegating to `_validate_inputs`."""
47 _validate_inputs(self.prices, self.mu, self.cfg)