import importlib.util import sys from pathlib import Path from types import SimpleNamespace import pytest def load_module(): path = Path(__file__).resolve().parents[1] / "scripts" / "search_recent_regime_mean_reversion.py" spec = importlib.util.spec_from_file_location("search_recent_regime_mean_reversion", path) assert spec is not None module = importlib.util.module_from_spec(spec) assert spec.loader is not None sys.modules[spec.name] = module spec.loader.exec_module(module) return module def test_trade_return_applies_roundtrip_fee_to_long_and_short(): module = load_module() assert module.trade_return("long", 100.0, 101.0) == pytest.approx(0.0092) assert module.trade_return("short", 100.0, 99.0) == pytest.approx((100.0 / 99.0 - 1.0) - 0.0008) def test_exit_price_uses_open_when_short_stop_gaps(): module = load_module() position = {"side": "short", "stop": 101.0, "take": 99.0, "midpoint": 99.5} row = SimpleNamespace(open=102.0, high=103.0, low=100.0) assert module.exit_price(position, row) == pytest.approx(102.0) def test_horizon_rows_include_required_recent_windows(): module = load_module() pandas = pytest.importorskip("pandas") index = pandas.date_range("2023-01-01", periods=1200, freq="D", tz="UTC") series = pandas.Series(10_000.0, index=index) spec = module.Spec("ETH-USDT-SWAP", "3m", "bidir", 24, 144, 0.2, 0.0016, 0.006, 0.006, 20) rows = module.horizon_rows(spec, series, []) assert [row["horizon"] for row in rows] == ["7d", "14d", "30d", "90d", "6m", "1y", "3y"] assert {"total_return", "annualized", "max_drawdown", "calmar", "trades", "win_rate", "profit_factor", "payoff_ratio"} <= set(rows[0])