cross_section

cross_section

Cross-sectional characteristics and relative asset measurements.

Factor calculations compare assets; they do not choose portfolio positions.

Functions

Name Description
compute_elo Compute daily cross-sectional Elo ratings within sectors.
group_weighted_return Calculate weighted simple returns for groups of assets.

compute_elo

cross_section.compute_elo(
    data,
    daily_vol_window=20,
    matches_per_stock=1,
    initial_elo=1500,
    epsilon=0.001,
    rf_data=None,
    low_qt=0.2,
    high_qt=0.8,
    use_excess_returns=True,
)

Compute daily cross-sectional Elo ratings within sectors.

Call this function once for a complete long-form universe. It calculates each symbol’s daily return, pairs symbols with nearby Elo ratings inside the same sectorid, and carries ratings forward through time.

Parameters

Name Type Description Default
data pd.DataFrame Daily observations with required date, symbol, close, and sectorid columns. Missing sector values are grouped into an "UnknownSector" bucket. required
daily_vol_window int Rolling return-volatility window. 20
matches_per_stock int Maximum opponents selected per symbol and date. 1
initial_elo int Starting rating for every symbol. 1500
epsilon float Absolute return difference treated as a draw. 0.001
rf_data pd.DataFrame | None Optional frame with date and decimal daily rate. None
low_qt float Legacy lower K-factor threshold. Its semantics require review; see the cross-section roadmap. 0.2
high_qt float Legacy upper K-factor threshold. Its semantics require review; see the cross-section roadmap. 0.8
use_excess_returns bool Use returns minus rf_data when both are supplied. If no risk-free frame is supplied, use log returns. True

Returns

Name Type Description
pd.DataFrame A new DataFrame containing the prepared return columns plus elo,
pd.DataFrame daily elo_change, and cumulative matches_played.

Raises

Name Type Description
TypeError If data is not a DataFrame.
ValueError If required columns are absent or parameters are invalid.

Notes

This is a migration of the legacy algorithm. Match scheduling, K-factor thresholds, and missing-price semantics remain under review and are tracked in the q.cross_section roadmap.

group_weighted_return

cross_section.group_weighted_return(
    data,
    *,
    group_field='sectorid',
    date_field='date',
    symbol_field='symbol',
    field=None,
    field_type=None,
    weighting='equal',
    weight_field=None,
    weight_lag=1,
    volatility_window=20,
    min_assets=1,
)

Calculate weighted simple returns for groups of assets.

The input must contain one row per symbol and date. When field is not supplied, a return column is used as simple returns if present; otherwise returns are calculated from close. Explicit fields require a field_type of "price", "simple_return", or "log_return".

Parameters

Name Type Description Default
data pd.DataFrame Long-form asset observations. required
group_field str Column defining groups, such as sectorid. 'sectorid'
date_field str Observation date or datetime column. 'date'
symbol_field str Asset identifier column. 'symbol'
field str | None Optional price or return column. None
field_type FieldType | None Interpretation of an explicitly supplied field. None
weighting Weighting Equal, market-cap, volume, inverse-volatility, or custom weighting. 'equal'
weight_field str | None Weight column. It defaults to market_cap or volume for those named methods and is required for custom. None
weight_lag int Observations by which non-equal weights are lagged within each symbol. The default prevents look-ahead bias. 1
volatility_window int Trailing window for inverse-volatility weights. 20
min_assets int Minimum valid assets required for a group return. 1

Returns

Name Type Description
pd.DataFrame A new DataFrame with the date and group columns, weighted_return,
pd.DataFrame contributing asset_count, and raw weight_sum.

Raises

Name Type Description
TypeError If the input or a required numeric column has the wrong type.
ValueError If columns, observations, or parameters are invalid.
Back to top