feat: compare legacy and live ranking universes
This commit is contained in:
@@ -1166,12 +1166,29 @@ def test_slim_replay_can_retain_shorts_for_ranking_universe(monkeypatch):
|
||||
full_ranking_universe = bt._replay_candidates_for_period(
|
||||
"AAA", columns, {}, {}, None, date.min, "daily", True
|
||||
)
|
||||
dual_ranking_replay = bt._replay_candidates_for_period(
|
||||
"AAA", columns, {}, {}, None, date.min, "daily", True, True
|
||||
)
|
||||
|
||||
assert [row["direction"] for row in long_only] == ["long"]
|
||||
assert {row["direction"] for row in full_ranking_universe} == {
|
||||
"long",
|
||||
"short",
|
||||
}
|
||||
assert len(dual_ranking_replay) == 2
|
||||
assert sum(
|
||||
bool(row.get("_universe_rank_observation"))
|
||||
for row in dual_ranking_replay
|
||||
) == 1
|
||||
|
||||
monkeypatch.setattr(bt, "_window_setups", lambda *_args, **_kwargs: [])
|
||||
rank_only = bt._replay_candidates_for_period(
|
||||
"AAA", columns, {}, {}, None, date.min, "daily", True, True
|
||||
)
|
||||
assert len(rank_only) == 1
|
||||
assert rank_only[0]["direction"] == "rank_only"
|
||||
assert rank_only[0]["_rank_only"] is True
|
||||
assert rank_only[0]["_universe_rank_observation"] is True
|
||||
|
||||
|
||||
def test_daily_replay_uses_exact_date_ranking_periods():
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
from datetime import date
|
||||
from datetime import date, timedelta
|
||||
|
||||
from scripts.run_daily_reentry_matrix import PrecomputedDailyEngine, ReentryPolicy
|
||||
import pytest
|
||||
|
||||
from scripts.run_daily_reentry_matrix import (
|
||||
PrecomputedDailyEngine,
|
||||
ReentryPolicy,
|
||||
_live_universe_rank_map,
|
||||
)
|
||||
|
||||
|
||||
RANKING_KEY = "strategy_rank"
|
||||
@@ -95,3 +101,72 @@ def test_two_session_confirmation_excludes_stop_day_close():
|
||||
emitted = _call(policy, ORD + 2, state, 2)
|
||||
assert emitted is not None
|
||||
assert emitted["_reentry_reason"] == "two_qualified_post_stop_closes"
|
||||
|
||||
|
||||
def _rank_observation(
|
||||
symbol: str,
|
||||
*,
|
||||
raw: float,
|
||||
residual: float,
|
||||
volatility: float,
|
||||
) -> dict:
|
||||
return {
|
||||
"symbol": symbol,
|
||||
"date": date.fromordinal(ORD).isoformat(),
|
||||
"ranking_period": ("date", ORD),
|
||||
"momentum": raw,
|
||||
"residual_momentum": residual,
|
||||
"vol_6m": volatility,
|
||||
}
|
||||
|
||||
|
||||
def test_live_universe_rank_uses_each_ticker_once_and_residual_when_available():
|
||||
observations = [
|
||||
_rank_observation("AAA", raw=0.1, residual=0.3, volatility=0.1),
|
||||
_rank_observation("BBB", raw=0.3, residual=0.1, volatility=0.2),
|
||||
_rank_observation("CCC", raw=0.2, residual=0.2, volatility=0.3),
|
||||
]
|
||||
first_benchmark_day = date.fromordinal(ORD) - timedelta(days=300)
|
||||
benchmark = {
|
||||
first_benchmark_day + timedelta(days=offset): 100.0
|
||||
for offset in range(252)
|
||||
}
|
||||
|
||||
ranks = _live_universe_rank_map(observations, benchmark, 0.8)
|
||||
|
||||
assert ranks[("AAA", date.fromordinal(ORD).isoformat())] == {
|
||||
"momentum_percentile": 100.0,
|
||||
"volatility_percentile": 0.0,
|
||||
"strategy_rank": 80.0,
|
||||
}
|
||||
assert ranks[("BBB", date.fromordinal(ORD).isoformat())][
|
||||
"momentum_percentile"
|
||||
] == 0.0
|
||||
assert ranks[("CCC", date.fromordinal(ORD).isoformat())][
|
||||
"strategy_rank"
|
||||
] == 60.0
|
||||
|
||||
|
||||
def test_live_universe_rank_uses_raw_fallback_before_benchmark_is_ready():
|
||||
observations = [
|
||||
_rank_observation("AAA", raw=0.1, residual=0.3, volatility=0.1),
|
||||
_rank_observation("BBB", raw=0.3, residual=0.1, volatility=0.2),
|
||||
]
|
||||
|
||||
ranks = _live_universe_rank_map(observations, {}, 0.8)
|
||||
|
||||
assert ranks[("AAA", date.fromordinal(ORD).isoformat())][
|
||||
"momentum_percentile"
|
||||
] == 0.0
|
||||
assert ranks[("BBB", date.fromordinal(ORD).isoformat())][
|
||||
"momentum_percentile"
|
||||
] == 100.0
|
||||
|
||||
|
||||
def test_live_universe_rank_rejects_duplicate_ticker_date():
|
||||
observation = _rank_observation(
|
||||
"AAA", raw=0.1, residual=0.2, volatility=0.1
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError, match="one observation"):
|
||||
_live_universe_rank_map([observation, dict(observation)], {}, 0.8)
|
||||
|
||||
Reference in New Issue
Block a user