from __future__ import annotations import zipfile from scripts import run_fundamentals_research as runner def _window(name, sharpe, drawdown): return { "window": name, "sharpe": sharpe, "sharpe_se": 0.2, "dsr": 0.8, "cagr_pct": 10.0, "max_drawdown_pct": drawdown, "calmar": 1.0, "trades": 20, } def test_arm_matrix_is_bounded_and_pre_registered(): assert runner.N_TRIALS == 13 assert runner.ARMS[0]["id"] == "control_w00" assert {arm["weight"] for arm in runner.ARMS[1:]} == {0.1, 0.2, 0.3, 0.4} assert {arm["composite"] for arm in runner.ARMS[1:]} == { "quality", "growth", "balanced", } def test_development_grade_does_not_read_test_window(): control = { "windows": [ _window("train", 1.0, 10.0), _window("validation", 1.0, 10.0), _window("test", 9.0, 1.0), ] } arm = { "windows": [ _window("train", 1.1, 10.0), _window("validation", 1.2, 11.0), _window("test", -9.0, 90.0), ] } assert runner._development_grade(control, arm)["pass"] is True def test_output_bundle_is_self_contained(tmp_path): report = { "generated_at": "2026-07-23T00:00:00Z", "splits": {"train_end": "2024-01-01", "test_start": "2025-01-01"}, "n_trials": 13, "warnings": ["survivorship bias"], "factor_ic": {"full": []}, "arms": [], "development_selection": None, "final_check": None, } output = tmp_path / "result.json" runner._write_outputs(report, output, bundle=True) with zipfile.ZipFile(output.with_suffix(".zip")) as archive: names = set(archive.namelist()) assert { "result.json", "result.md", "result-arms.csv", "result-factor-ic.csv", "result-trades.csv", } <= names def test_winner_concentration_exposes_top_five_dependence(): details = [ {"pnl": value, "r": value / 10} for value in (100, 90, 80, 70, 60, -10, -20) ] result = runner._winner_concentration(details) assert result["top5_pnl"] == 400 assert result["net_pnl_ex_top5"] == -30 assert result["avg_r_ex_top5"] == -1.5