quantlab.factor.kunquant_cs.CrossSectionalWinsorize#

class quantlab.factor.kunquant_cs.CrossSectionalWinsorize(v, lower=0.01, upper=0.99)[source]#

Bases: _CrossSectionalQuantileBounds

Cross-sectional winsorization (缩尾): clip each bar to its quantile bounds.

At every timestamp the lower and upper quantiles are computed over all symbols, ignoring NaN, with linear interpolation (numpy’s and pandas’ default). A value below the lower bound is replaced by the lower bound, a value above the upper bound by the upper bound, and every other value passes through unchanged. Winsorizing keeps every observation but limits how far an outlier can pull a later cross-sectional statistic, such as CrossSectionalZScore.

NaN inputs stay NaN, and an all-NaN bar stays all NaN. A bar with a single valid value returns that value. No fill is applied.

The op shares CrossSectionalZScore’s constraints: batch runs must start at bar 0, and the number of symbols must be a multiple of the host’s SIMD block width. Each distinct (lower, upper) pair compiles its own C++ function (see _CrossSectionalQuantileBounds), so the constructed object’s class is a subclass such as CrossSectionalWinsorize_0p01_0p99.

Parameters:
vOpBase

The input series, usually a factor expression.

lowerfloat, default 0.01

Lower quantile, in [0, 1).

upperfloat, default 0.99

Upper quantile, in (lower, 1].

Raises:
ValueError

If 0 <= lower < upper <= 1 does not hold.

Examples

>>> Output(CrossSectionalZScore(CrossSectionalWinsorize(alpha(all_data))), "alpha001_cs")