malkhut(spec): item 4 — ScenarioLibrary sweep for Mode 1 coverage

ScenarioLibrary sweeps the state space (not samples) across:
  - spread_mult: [0.1, 0.5, 1.0, 2.0, 5.0, 10.0]
  - depth_fraction: [0.01, 0.05, 0.1, 0.3, 0.5, 1.0]
  - toxicity: [0.0, 0.3, 0.7, 1.0]
  - regime: [normal, crisis, recovery, transition]

Default: 13 assets × 576 grid points = 7,488 scenarios.
Customizable: specify symbols, dimensions, ranges.

7 tests covering: grid size, sweep output, point fields,
regime coverage, custom dimensions, summary, factory function.
This commit is contained in:
Codex
2026-07-14 05:34:05 +02:00
parent 833f262d12
commit 1f41be845b
2 changed files with 153 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
"""
Tests for ScenarioLibrary — sweep coverage.
"""
import pytest
from malkhut.training.scenario_library import ScenarioLibrary, SweepPoint, get_scenario_library
class TestScenarioLibrary:
def test_default_grid_size(self):
lib = ScenarioLibrary()
size = lib.grid_size()
assert size == 13 * 6 * 6 * 4 * 4 # 13 assets × 576 grid points
print(f' Default grid: {size} points')
def test_sweep_produces_points(self):
lib = ScenarioLibrary(symbols=("BTCUSDT",))
points = lib.sweep()
assert len(points) == 6 * 6 * 4 * 4 # 576 for one asset
def test_sweep_point_fields(self):
lib = ScenarioLibrary(symbols=("BTCUSDT",))
points = lib.sweep()
p = points[0]
assert isinstance(p, SweepPoint)
assert p.symbol == "BTCUSDT"
assert isinstance(p.spread_mult, float)
assert isinstance(p.depth_fraction, float)
assert isinstance(p.toxicity, float)
assert isinstance(p.regime, str)
assert isinstance(p.label, str)
def test_sweep_covers_all_regimes(self):
lib = ScenarioLibrary(symbols=("BTCUSDT",))
points = lib.sweep()
regimes = set(p.regime for p in points)
assert regimes == {"normal", "crisis", "recovery", "transition"}
def test_custom_dimensions(self):
lib = ScenarioLibrary(
symbols=("BTCUSDT", "ETHUSDT"),
spread_mults=[1.0, 5.0],
depth_fracs=[0.1, 0.5],
tox_levels=[0.0, 0.5],
regimes=["normal", "crisis"],
)
assert lib.grid_size() == 2 * 2 * 2 * 2 * 2 # 32 points
def test_summary(self):
lib = ScenarioLibrary()
s = lib.summary()
assert "13" in s
assert "7488" in s # 13 × 576
def test_get_scenario_library(self):
lib = get_scenario_library()
assert lib.grid_size() > 0