from __future__ import annotations import random from mcp_common.stats import cointegration_test def test_cointegrated_synthetic_pair(): """Costruisco coppia cointegrata: B random walk, A = 2*B + noise stazionario.""" r = random.Random(1) b = [100.0] for _ in range(300): b.append(b[-1] + r.gauss(0, 1)) a = [2 * b[i] + r.gauss(0, 0.5) for i in range(len(b))] out = cointegration_test(a, b) assert out["cointegrated"] is True assert out["beta"] == pytest_approx(2.0, rel=0.05) assert out["adf_t_stat"] is not None assert out["adf_t_stat"] < -2.86 def test_not_cointegrated_independent_walks(): """Due random walk indipendenti โ†’ spread non stazionario โ†’ no cointegration.""" r = random.Random(2) a = [100.0] b = [100.0] for _ in range(300): a.append(a[-1] + r.gauss(0, 1)) b.append(b[-1] + r.gauss(0, 1)) out = cointegration_test(a, b) # Per due RW indipendenti, t-stat ADF รจ solitamente > -2.86 โ†’ non cointegrate assert out["cointegrated"] is False or out["adf_t_stat"] > -3.0 def test_cointegration_short_series(): out = cointegration_test([1.0, 2.0], [3.0, 4.0]) assert out["cointegrated"] is None assert out["beta"] is None def test_cointegration_mismatched_length(): out = cointegration_test([1.0, 2.0, 3.0], [1.0, 2.0]) assert out["cointegrated"] is None def pytest_approx(value, rel): """Tiny helper to avoid importing pytest just for approx.""" class _Approx: def __eq__(self, other): return abs(other - value) <= abs(value) * rel return _Approx()