Snapshot before the DuckDB->PostgreSQL migration. data/, archive/, the 232MB rebuild zip, the Windows .venv, and .env are excluded via .gitignore. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
29 lines
980 B
Python
29 lines
980 B
Python
"""Tradeable universe filtering (price band, volume, share class)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from config import UniverseConfig
|
|
|
|
|
|
def symbol_in_universe(
|
|
price: float,
|
|
avg_volume_20d: float | None = None,
|
|
is_etf: bool = False,
|
|
is_otc: bool = False,
|
|
config: UniverseConfig | None = None,
|
|
) -> tuple[bool, str | None]:
|
|
"""Check whether a symbol qualifies for the trading universe."""
|
|
config = config or UniverseConfig()
|
|
if price < config.price_min or price > config.price_max:
|
|
return False, f"price {price:.2f} outside [{config.price_min}, {config.price_max}]"
|
|
if (
|
|
avg_volume_20d is not None
|
|
and avg_volume_20d < config.min_avg_volume_20d
|
|
):
|
|
return False, f"avg volume {avg_volume_20d:,.0f} < {config.min_avg_volume_20d:,}"
|
|
if config.exclude_etf and is_etf:
|
|
return False, "ETF excluded"
|
|
if config.exclude_otc and is_otc:
|
|
return False, "OTC excluded"
|
|
return True, None
|