quantlab.factor.polars.FactorPolars#

class quantlab.factor.polars.FactorPolars(config)[source]#

Bases: Factor

Batch-only factor backend whose factor logic is a Polars expression chain.

A subclass overrides _get_factor_lazyframe, which receives the dataset as a LazyFrame and returns a lazy frame carrying only timestamp, symbol and the factor columns. Nothing is materialized until compute() collects it and converts the result to an xarray.Dataset. Factor names are not declared: they are read from the schema of the returned frame, so they are known at construction time (which reads a few rows from the store) and always match what the expression chain produces.

Column names are whatever the underlying store holds; unlike the KunQuant path, no per-market renaming is applied. A merged input is the exception: a merge renames every input to the shared names (close, not Close) before the factor sees it.

Parameters:
configPolarsFactorConfig

The factor config.

Examples

A factor comparing each bar’s volume with its 20-bar average:

class RelativeVolume(FactorPolars):
    def _get_factor_lazyframe(self, lf):
        volume = pl.col("Volume")
        return (
            lf.sort(["symbol", "timestamp"])
            .with_columns(
                (volume / volume.rolling_mean(20).over("symbol") - 1.0)
                .alias("rel_volume_20")
            )
            .select(["timestamp", "symbol", "rel_volume_20"])
        )
PEAK_COPIES = 16#

The panel goes through a long frame, a pandas frame and back, each a copy with index columns: a one-output momentum on us3000 (2723 bars x 7625 symbols) peaked at 14 times its input and output at 8 bytes (2026-10-09). See Factor.cell_bytes.

config_cls#

The config class from_config rebuilds this factor with.

alias of PolarsFactorConfig