Skip to content

universe

optimizer.universe

Investability screening for stock universe construction.

ExchangeRegion

Bases: str, Enum

Exchange region for region-specific screening thresholds.

HysteresisConfig dataclass

Entry/exit thresholds with hysteresis to reduce turnover.

Setting exit below entry prevents marginal stocks from oscillating in and out of the universe with small fluctuations.

Parameters

entry : float Threshold a stock must exceed to enter the universe. exit_ : float Threshold below which a current member is removed. Must be <= entry.

InvestabilityScreenConfig dataclass

Immutable configuration for investability screening.

Enforces minimum standards of market capitalization, liquidity, price level, listing history, and data availability. All hysteresis thresholds use separate entry/exit values to reduce turnover at screen boundaries.

Parameters

market_cap : HysteresisConfig Free-float market capitalization thresholds (USD). addv_12m : HysteresisConfig 12-month average daily dollar volume thresholds (USD). addv_3m : HysteresisConfig 3-month average daily dollar volume thresholds (USD). trading_frequency : HysteresisConfig Fraction of trading days with nonzero volume (0-1). price_us : HysteresisConfig Minimum price for US-listed equities (USD). price_europe : HysteresisConfig Minimum price for European-listed equities (local currency). min_trading_history : int Minimum trading days of price history required. min_ipo_seasoning : int Minimum trading days since first price observation. min_annual_reports : int Minimum annual financial statements required. min_quarterly_reports : int Minimum quarterly financial statements required. exchange_region : ExchangeRegion Region for price threshold selection. mcap_percentile_entry : float Minimum exchange-percentile rank (0-1) for entry. A stock must exceed BOTH the absolute market_cap.entry floor AND this percentile within its exchange to enter the universe. Defaults to the 10th percentile (0.10). Requires an exchange column in the fundamentals DataFrame passed to apply_investability_screens. mcap_percentile_exit : float Minimum exchange-percentile rank (0-1) for existing members to avoid removal. Must be <= mcap_percentile_entry. Defaults to the 7.5th percentile (0.075).

for_developed_markets() classmethod

Strict thresholds for developed-market institutional universes.

for_broad_universe() classmethod

Relaxed thresholds for broader coverage.

for_small_cap() classmethod

Thresholds appropriate for small-cap universes.

screen_universe(fundamentals, price_history, volume_history, financial_statements=None, config=None, current_members=None)

Screen a stock universe for investability.

Convenience wrapper around :func:apply_investability_screens that applies default configuration when none is provided.

Parameters

fundamentals : pd.DataFrame Cross-sectional data with one row per ticker. price_history : pd.DataFrame Price matrix (dates x tickers). volume_history : pd.DataFrame Volume matrix (dates x tickers). financial_statements : pd.DataFrame or None Statement-level data. config : InvestabilityScreenConfig or None Screening configuration. current_members : pd.Index or None Tickers currently in the universe for hysteresis.

Returns

pd.Index Tickers passing all investability screens.

apply_investability_screens(fundamentals, price_history, volume_history, financial_statements=None, config=None, current_members=None)

Apply all investability screens to produce a universe.

Parameters

fundamentals : pd.DataFrame Cross-sectional data with one row per ticker. Required columns: market_cap, current_price. Index is ticker. price_history : pd.DataFrame Price matrix (dates x tickers). volume_history : pd.DataFrame Volume matrix (dates x tickers). financial_statements : pd.DataFrame or None Statement-level data with ticker, period_type, and optionally period_date columns. config : InvestabilityScreenConfig or None Screening configuration. Defaults to developed-market thresholds. current_members : pd.Index or None Tickers currently in the universe for hysteresis.

Returns

pd.Index Tickers passing all investability screens.

apply_screen(values, hysteresis, current_members=None)

Apply a single screen with hysteresis.

New stocks must exceed hysteresis.entry; existing members are retained until they fall below hysteresis.exit_.

Parameters

values : pd.Series Metric values indexed by ticker. hysteresis : HysteresisConfig Entry/exit thresholds. current_members : pd.Index or None Tickers currently in the universe. If None, entry thresholds are applied to all stocks.

Returns

pd.Index Tickers passing the screen.

compute_addv(price_history, volume_history, window)

Compute average daily dollar volume over a trailing window.

Parameters

price_history : pd.DataFrame Price matrix (dates x tickers). volume_history : pd.DataFrame Volume matrix (dates x tickers), aligned with price_history. window : int Number of trailing trading days.

Returns

pd.Series Average daily dollar volume per ticker.

compute_exchange_mcap_percentile_thresholds(market_caps, exchange_mapping, percentile, min_exchange_size=10)

Compute per-exchange market-cap percentile threshold for each ticker.

For each exchange, the Nth percentile of all member market caps is computed and assigned as the threshold for every stock on that exchange. Exchanges with fewer than min_exchange_size stocks receive a threshold of 0 (no filter applied).

Parameters

market_caps : pd.Series Free-float market caps indexed by ticker. exchange_mapping : pd.Series Exchange labels indexed by ticker. percentile : float Percentile to compute on a 0–1 scale (e.g. 0.10 for the 10th percentile). min_exchange_size : int Minimum number of stocks an exchange must have before the percentile threshold is applied. Smaller exchanges default to a threshold of 0.

Returns

pd.Series Per-ticker threshold values (same index as market_caps).

compute_listing_age(price_history)

Compute listing age in trading days for each ticker.

Parameters

price_history : pd.DataFrame Price matrix (dates x tickers).

Returns

pd.Series Number of non-NaN trading days per ticker.

compute_trading_frequency(volume_history, window)

Compute fraction of trading days with nonzero volume.

Parameters

volume_history : pd.DataFrame Volume matrix (dates x tickers). window : int Number of trailing trading days.

Returns

pd.Series Trading frequency per ticker (0 to 1).

count_financial_statements(statements, period_type, min_lookback_days=None)

Count financial statements per ticker.

Parameters

statements : pd.DataFrame Must contain columns ticker, period_type, and optionally period_date. period_type : str Filter to this period type (e.g. "annual" or "quarterly"). min_lookback_days : int or None If provided, only count statements with period_date within this many calendar days from the latest date.

Returns

pd.Series Statement count indexed by ticker.