"""Causality proof: for every registered strategy, the target at bar t computed on data[:t+1] equals the target computed on the full series. Any use of future rows (centered windows, shift(-k), global normalisation…) fails.""" import numpy as np import pytest from ktrade.strategy.registry import _REGISTRY from tests.conftest import synthetic_candles @pytest.mark.parametrize("name", sorted(_REGISTRY)) def test_targets_are_causal(name): cls = _REGISTRY[name] df = synthetic_candles(n=700, seed=3) full = cls().run(df).target.to_numpy() for cut in (320, 450, 600, 699): part = cls().run(df.iloc[: cut + 1].copy()).target.to_numpy() assert np.allclose(np.nan_to_num(part), np.nan_to_num(full[: cut + 1]), atol=1e-9), f"{name}: look-ahead at bar {cut}" @pytest.mark.parametrize("name", sorted(_REGISTRY)) def test_targets_within_bounds(name): cls = _REGISTRY[name] t = cls().run(synthetic_candles(n=400, seed=5)).target lo = -1.0 if cls.meta.allows_short else 0.0 assert ((t >= lo - 1e-12) & (t <= 1.0 + 1e-12)).all()