skfolio.alpha.PredictorAlpha#
- class skfolio.alpha.PredictorAlpha(*, predictor, descriptors, horizon=1, signal_lag=1, neutralize_against=None, outlier_transformer=None, scoring_transformer=None, target_outlier_transformer=None, target_scoring_transformer=None, transform_by_group=None, forecast_unit=IDIO_RETURN, calibrate_to_return_units=True, forecast_scale=1.0, half_life=20, cv=None, n_jobs=1)[source]#
Predictor alpha estimator using a user-provided regressor.
This estimator converts descriptors into cross-sectional scores, optionally neutralizes those scores against factor exposures and fits a scikit-learn compatible regressor where each observation-asset pair is one training sample. It supports nonlinear signal combinations while keeping the final forecast in expected idiosyncratic return units when calibration is enabled [1].
The predictor supports two forecast units. With
forecast_unit=ForecastUnit.IDIO_RETURN, it is fitted to the forward mean idiosyncratic return \(\epsilon_{t,i}\). Withforecast_unit=ForecastUnit.IDIO_SHARPE, it is fitted to \(\epsilon_{t,i} / \sigma_{t,i}\) and the forecast is multiplied by current idiosyncratic volatility soalpha_remains in expected return units. This is useful when signals are assumed to forecast idiosyncratic Sharpe rather than raw idiosyncratic return.When
calibrate_to_return_units=True, the raw predictor output \(\hat a_{t,i}\) is calibrated to expected-return units with scalar exponentially weighted least squares:\[\beta_t = \arg\min_\beta \sum_i \frac{(\epsilon_{t,i} - \hat a_{t,i}\beta)^2}{\sigma_{t,i}^2}\]The calibration coefficient is estimated with exponentially weighted least squares:
\[A_t^{EW} = \lambda A_{t-1}^{EW} + (1 - \lambda)\hat a_t^\top W_t \hat a_t\]\[b_t^{EW} = \lambda b_{t-1}^{EW} + (1 - \lambda)\hat a_t^\top W_t \epsilon_t, \quad \lambda = 2^{-1/\text{half-life}}\]and the ridge-stabilized coefficient is:
\[\beta_t = b_t^{EW} / (A_t^{EW} + \rho_t)\]This produces alpha in expected return units, which is required whenever the optimizer is trading off alpha against real costs and constraints such as transaction costs, market impact, borrow costs, or turnover constraints.
In batch mode, calibration uses predictions from held-out CV folds when enough samples are available. This reduces the in-sample scale inflation from fitting and calibrating on the same predictions. These predictions are used only for scale calibration, not as a time-series performance estimate. The default splitter treats valid observation-asset pairs as approximately exchangeable. Pass a date-aware or purged splitter through
cvwhen the calibration itself should enforce stricter temporal separation.The estimator supports
fitandpartial_fit. In online mode, samples are trained when their forward-return targets become observable, including rows carried in the target-maturity buffer. The predictor must supportpartial_fitafter the first fitted update.- Parameters:
- predictorestimator
Regressor that implements
fitandpredict. For online mode, the predictor must also implementpartial_fit. The predictor receives one sample per valid observation-asset pair, with shape(n_observations * n_assets, n_descriptors), and predicts the transformed target.- descriptorslist of (name, estimator) tuples
List of descriptors that compute signals from characteristics. Each tuple contains a string name and a descriptor estimator. Multiple descriptors are aggregated into a single alpha using multivariate regression. The descriptors are evaluated in parallel if
n_jobs > 1.- half_lifefloat, default=20
Half-life of the EWLS calibration statistics in number of observations. Only used when
calibrate_to_return_units=True.Larger half-life: More stable alpha estimates, slower adaptation
Smaller half-life: More responsive estimates, faster adaptation
- horizonint, default=1
Number of forward periods to average for the target idiosyncratic return. Must be >= 1. The target for observation \(t\) is
mean(idio_returns[t+signal_lag : t+signal_lag+horizon]).horizon=1: Predicts one-period idiosyncratic return starting aftersignal_laghorizon>1: Predicts the mean ofhorizonidiosyncratic returns starting aftersignal_lag.
- signal_lagint, default=1
Number of periods between the signal observation and the first return in the target window. Must be >= 1. Under skfolio’s as-of time-indexing convention,
signal_lag=0would use information observed at the end of \(t\) to predict return at \(t\), which is look-ahead. Values larger than 1 can model conservative data availability or execution delays.- neutralize_againstlist of str, optional
Factor names or families to neutralize scores against. If provided, scores are orthogonalized with respect to the specified factor exposures before prediction.
- outlier_transformerBaseCSTransformer or “passthrough”, optional
Cross-sectional transformer for descriptor outlier handling. If
None, defaults toCSWinsorizer(). Use"passthrough"to skip.- scoring_transformerBaseCSTransformer or “passthrough”, optional
Cross-sectional transformer for descriptor scoring applied after outlier handling. If None, defaults to
CSStandardScaler(). Use “passthrough” to skip.- target_outlier_transformerBaseCSTransformer or “passthrough”, optional
Cross-sectional transformer for target outlier handling. If
None, defaults toCSWinsorizer(). Use"passthrough"to skip.- target_scoring_transformerBaseCSTransformer or “passthrough”, optional
Cross-sectional transformer for target scoring. If
None, defaults to"passthrough". The calibration stage calibrates the predictor output back to expected-return units whencalibrate_to_return_units=True.- transform_by_groupstr, optional
Name of a categorical characteristic in the AssetPanel to use for group-wise transformations. If provided, cross-sectional transformations are applied within each group separately.
- forecast_unitForecastUnit, default=ForecastUnit.IDIO_RETURN
Unit of the intermediate forecast learned by the predictor. With
ForecastUnit.IDIO_RETURN, the predictor is trained on forward mean idiosyncratic return. WithForecastUnit.IDIO_SHARPE, the target is divided by forecast idiosyncratic volatility and the resulting idiosyncratic-Sharpe forecast is converted back to return units by multiplying by current idiosyncratic volatility.- calibrate_to_return_unitsbool, default=True
If
True, calibrate raw predictor output to expected return units using scalar EWLS. IfFalse, return the predictor output after any volatility conversion implied byforecast_unit.- forecast_scalefloat, default=1.0
Multiplicative scale applied to the final alpha forecast after optional return-unit calibration. This controls alpha strength without changing the predictor or calibration coefficient estimates.
- cvcross-validator, int, optional
Cross-validation strategy used to obtain predictions from held-out folds for return-unit calibration. When
None, usesKFold(5). CV is used only in batch mode whencalibrate_to_return_units=Trueand there are enough samples.- n_jobsint, default=1
Number of parallel jobs for descriptor computation and cross-validation.
- Attributes:
- alpha_ndarray of shape (n_assets,) or None
Estimated alpha for each asset, after applying
forecast_scale. Ifcalibrate_to_return_units=True, this is in expected return units. Otherwise, it is the predictor output after any volatility conversion. ReturnsNoneduring warmup.- predictor_estimator
Fitted predictor instance.
- descriptors_list of BaseDescriptor
Fitted descriptor estimators.
- named_descriptors_dict of {str: BaseDescriptor}
Dictionary mapping descriptor names to fitted estimators.
- outlier_transformer_BaseCSTransformer or str
Fitted descriptor outlier transformer.
- scoring_transformer_BaseCSTransformer or str
Fitted descriptor scoring transformer.
- target_outlier_transformer_BaseCSTransformer or str
Fitted target outlier transformer.
- target_scoring_transformer_BaseCSTransformer or str
Fitted target scoring transformer.
- n_assets_int
Number of assets seen during fitting.
- asset_names_ndarray
Names of assets in the coverage universe.
Methods
fit(X[, y])Fit the alpha model from scratch (batch mode).
Return metadata routing for descriptors and the predictor.
get_params([deep])Get the parameters of an estimator from the ensemble.
partial_fit(X[, y])Incrementally fit the alpha model with new observations (online mode).
set_params(**params)Set the parameters of a factor from the ensemble.
See also
EWSharpeOptimalAlphaLinear signal aggregation with Sharpe-optimal WLS weighting.
References
[1]“Active Portfolio Management: A Quantitative Approach for Producing Superior Returns and Controlling Risk”, McGraw-Hill, Grinold & Kahn (1999).
Examples
>>> import numpy as np >>> from sklearn.linear_model import SGDRegressor >>> from skfolio.datasets import make_synthetic_characteristics >>> from skfolio.alpha import ForecastUnit, PredictorAlpha >>> from skfolio.descriptor import EWMomentum, BookToPrice, Reversal, Passthrough >>> >>> X = make_synthetic_characteristics() >>> rng = np.random.default_rng(0) >>> >>> # Alpha models regress forward idiosyncratic returns. In production these >>> # come from a fitted CharacteristicsFactorModel. >>> idio_returns = rng.standard_normal((X.n_observations, X.n_assets)) >>> idio_returns[~X.active_mask] = np.nan >>> X["idio_returns"] = idio_returns >>> >>> # Required when forecast_unit=ForecastUnit.IDIO_SHARPE to scale targets and alphas. >>> idio_variances = rng.uniform(0.01, 0.05, (X.n_observations, X.n_assets)) >>> idio_variances[~X.active_mask] = np.nan >>> X["idio_variances"] = idio_variances >>> >>> # Required when neutralize_against is set. In production these are factor >>> # exposures from the characteristics factor model. >>> exposures = rng.standard_normal((X.n_observations, X.n_assets, 3)) >>> exposures[~X.active_mask] = np.nan >>> X.add_3d_field( ... "exposures", ... exposures, ... third_axis_name="factors", ... third_axis_labels=["market", "beta", "size"], ... ) >>> >>> alpha_model = PredictorAlpha( ... predictor=SGDRegressor(), ... descriptors=[ ... ("momentum", EWMomentum()), ... ("book_to_price", BookToPrice()), ... ("reversal", Reversal()), ... ("eps_ntm", Passthrough("eps_ntm")), ... ], ... horizon=5, ... half_life=21, ... neutralize_against=["market", "beta", "size"], ... forecast_unit=ForecastUnit.IDIO_SHARPE, ... ) >>> >>> alpha_model.fit(X) >>> print(alpha_model.alpha_) >>> >>> # Online learning (requires predictor with partial_fit) >>> alpha_model.partial_fit(X[-5:]) >>> print(alpha_model.alpha_)
- fit(X, y=None, **fit_params)[source]#
Fit the alpha model from scratch (batch mode).
This method works with any sklearn-compatible predictor. It resets all internal state and fits on the provided data. When calibration is enabled, predictions from held-out CV folds can be used to calibrate the return-unit scale.
- Parameters:
- XAssetPanel
Input panel containing “idio_returns”, descriptor fields and optionally “idio_variances” for calibration or volatility-scaled targets, and “exposures” for score neutralization.
- yNone
Ignored. Present for compatibility with scikit-learn’s API.
- **fit_paramsdict
Additional fit parameters passed to descriptors and predictor.
- Returns:
- selfPredictorAlpha
Fitted estimator.
- get_params(deep=True)#
Get the parameters of an estimator from the ensemble.
Returns the parameters given in the constructor as well as the estimators contained within the
estimatorsparameter.- Parameters:
- deepbool, default=True
Setting it to True gets the various estimators and the parameters of the estimators as well.
- Returns:
- paramsdict
Parameter and estimator names mapped to their values or parameter names mapped to their values.
- property named_descriptors#
Dictionary to access any fitted factors by name.
- Returns:
Bunch
- partial_fit(X, y=None, **fit_params)[source]#
Incrementally fit the alpha model with new observations (online mode).
This method supports streaming/online updates. It maintains internal buffers to compute forward returns across partial_fit calls. Only samples whose targets have newly matured are used for training, avoiding double-counting while still training buffered rows once their labels are observable.
On the first call, the predictor is trained using
fit(). On subsequent calls, the predictor is updated usingpartial_fit(), which requires the predictor to support this method.- Parameters:
- XAssetPanel
Input panel containing “idio_returns”, descriptor fields and optionally “idio_variances” for calibration or volatility-scaled targets, and “exposures” for score neutralization.
- yNone
Ignored. Present for compatibility with scikit-learn’s API.
- **fit_paramsdict
Additional fit parameters passed to descriptors and predictor.
- Returns:
- selfPredictorAlpha
Fitted estimator.
- Raises:
- TypeError
If the predictor does not support
partial_fit(raised on second or subsequent calls).
- set_params(**params)#
Set the parameters of a factor from the ensemble.
Valid parameter keys can be listed with
get_params(). Note that you can directly set the parameters of the estimators contained inestimators.- Parameters:
- **paramskeyword arguments
Specific parameters using e.g.
set_params(parameter_name=new_value). In addition, to setting the parameters of the estimator, the individual estimator of the estimators can also be set, or can be removed by setting them to ‘drop’.
- Returns:
- selfobject
Estimator instance.