quantlab.model.predefined.smoothed.SmoothedPredictor#
- class quantlab.model.predefined.smoothed.SmoothedPredictor(predictor, halflife_bars, warmup_bars=None, standardize=True)[source]#
Bases:
PredictorViewA
Predictorwhose predictions are a causal exponential mean of the wrapped ones.predict_window(start, end)asks the wrapped predictor for the window and up towarmup_barsbars before it, z-scores every bar over its symbols (cross_sectional_zscore,ddof=1) whenstandardize, and returns, for every bar of the window, each symbol’s exponentially weighted mean of those values over the bars up to that one: weight2 ** (-age / halflife_bars)for a valueagebars old, normalised over the values the symbol has (pandasewm(halflife=halflife_bars, adjust=True, ignore_na=False)). A bar where a symbol has no value adds nothing to its mean, but its older values keep ageing. A cell NaN in the wrapped predictions at t is NaN in the output at t, so a mask at t (aMembershipMaskedPredictor) still decides who may be entered.The warm-up is counted in the wrapped predictor’s bars: the request is widened until
warmup_barsbars before the window come back (ten halflives by default, the weight left beyond them at most2 ** -10) and cut to them. When the wrapped predictor holds fewer (its first bar, a record’s start), the mean starts at its first bar, a warning gives the count, andlast_warmup_barsholds it.The warm-up must be out of sample. A wrapped model predicts the bars before the window with its loaded checkpoint, so a warm-up bar on or before the end of the checkpoint’s fitted training window (
fitted_train_bounds) would blend an in-sample fit into the smoothed values, and is refused. ARecordedPredictorwithhistory=Trueserves each earlier bar as the checkpoint live then predicted it, so it is not checked. Every other protocol member forwards to the wrapped predictor (PredictorView);label_scalesis"standardized"for every label when standardising.- Parameters:
- predictorPredictor
The model or ensemble whose predictions are smoothed. In a
run_cvreplay, wrap aRecordedPredictor(..., history=True)so each fold’s warm-up is what the earlier folds predicted.- halflife_barsfloat
The halflife of the weights, in bars; positive.
- warmup_barsint, optional
Bars before the window the mean reads; non-negative. Ten halflives, rounded up, by default.
- standardizebool, default True
Whether to z-score each bar over its symbols before smoothing.
- Attributes:
- last_warmup_barsint or None
The warm-up bars the last
predict_windowread.
- Raises:
- ValueError
If
halflife_barsis not positive and finite orwarmup_barsis negative; frompredict_window, if a warm-up bar lies inside the loaded checkpoint’s fitted training window.
Examples
With
wholearun_cvresult,modelthe predictor it ran andbacktesterarun_cvbacktester over the same folds:>>> recorded = RecordedPredictor(model, whole.run_dir, history=True) >>> backtester.config = dataclasses.replace( ... backtester.config, model=SmoothedPredictor(recorded, halflife_bars=20) ... ) >>> smoothed = backtester.run_cv() # every fold's warm-up from the earlier folds
>>> SmoothedPredictor(None, halflife_bars=2.5).warmup_bars 25
- config_cls#
The config dataclass the wrapper is serialised and rebuilt with.
alias of
SmoothedPredictorConfig
- property label_scales#
"standardized"for every label when standardising, else the wrapped predictor’s.Examples
>>> SmoothedPredictor(model, halflife_bars=5).label_scales {'fwd_ret_1': 'standardized'}
- predict_window(start, end)[source]#
The smoothed predictions for every bar from
starttoend.The wrapped predictor is asked for the window and days before it, widened until
warmup_barsbars beforestartcome back or it holds no earlier bar; the lastwarmup_barsare kept.- Raises:
- ValueError
If a warm-up bar lies inside the loaded checkpoint’s fitted training window (an in-sample fit), unless the wrapped predictor serves recorded history (
RecordedPredictor(history=True)).
Examples
With
modela loaded model over business days:>>> out = SmoothedPredictor(model, halflife_bars=5).predict_window("2024-02-12", "2024-03-11") >>> str(out.timestamp.values[0])[:10] # the warm-up bars are not returned '2024-02-12'
- smooth(predictions)[source]#
Return the causal exponential mean of every variable of
predictions.Every bar of
predictionsis read; nothing before it. See the class docstring for the weights.- Parameters:
- predictionsxr.Dataset
Predictions on
(timestamp, symbol), in time order.
- Returns:
- xr.Dataset
The smoothed panel on the same coordinates, NaN where the input is NaN (or, standardising, where the bar is degenerate).
Examples
>>> panel = xr.Dataset( ... {"fwd_ret_1": (("timestamp", "symbol"), [[1.0, 2.0, 3.0], [3.0, 2.0, np.nan]])}, ... coords={"timestamp": pd.bdate_range("2024-01-01", periods=2), ... "symbol": ["A", "B", "C"]}, ... ) >>> SmoothedPredictor(None, halflife_bars=1).smooth(panel)["fwd_ret_1"].values.round(4) array([[-1. , 0. , 1. ], [ 0.1381, -0.4714, nan]])