24 lines
820 B
Python
24 lines
820 B
Python
import pandas as pd
|
|
|
|
|
|
LONG_MA_WINDOW = 200
|
|
RS_WINDOW = 63
|
|
|
|
|
|
def build_regime_filter(etf_close: pd.DataFrame, market_col: str = "SPY") -> pd.Series:
|
|
"""Return a next-day tradable regime flag based on market trend and ETF leadership."""
|
|
prices = etf_close.sort_index()
|
|
if market_col not in prices.columns:
|
|
raise KeyError(f"{market_col} not found in etf_close")
|
|
|
|
market = prices[market_col]
|
|
market_ma = market.rolling(LONG_MA_WINDOW, min_periods=LONG_MA_WINDOW).mean()
|
|
market_ok = market.gt(market_ma)
|
|
|
|
rs = prices.pct_change(RS_WINDOW, fill_method=None)
|
|
non_market_rs = rs.drop(columns=[market_col], errors="ignore")
|
|
leader_ok = non_market_rs.gt(rs[market_col], axis=0).any(axis=1)
|
|
|
|
regime = (market_ok & leader_ok).astype(bool)
|
|
return regime.shift(1, fill_value=False)
|