<a id="skfolio-model-selection-online-predict"></a>

# skfolio.model_selection.online_predict

<a id="skfolio.model_selection.online_predict"></a>

### skfolio.model_selection.online_predict(estimator, X, y=None, warmup_size=252, test_size=1, freq=None, freq_offset=None, previous=False, purged_size=0, reduce_test=False, params=None, portfolio_params=None, entry_rebalancing_params=None)

Generate out-of-sample portfolios using online learning.

Walks forward through the data, updating the estimator incrementally via
`partial_fit` and predicting on each subsequent test window. Unlike
[`cross_val_predict`](https://skfolio.org/generated/skfolio.model_selection.cross_val_predict.html.md#skfolio.model_selection.cross_val_predict), which clones the estimator for
each fold, this function maintains a single stateful estimator that accumulates
knowledge over time.

The algorithm:

1. Clone the estimator to ensure a clean, unfitted starting state.
2. Initialize the estimator on the first `warmup_size` observations via `partial_fit`.
3. At each step, predict on the test window, then update the model with the newly
   observed data via `partial_fit`.

If the estimator declares `needs_previous_weights=True`, portfolio weights are
automatically propagated from one step to the next.

* **Parameters:**
  **estimator** *BaseOptimization*
  : Portfolio optimization estimator. It must implement `partial_fit`.
    Pipelines are not supported.

  **X** *array-like of shape (n_observations, n_assets)*
  : Price returns of the assets. Must be a DataFrame with a `DatetimeIndex` when
    `freq` is provided.

  **y** *array-like of shape (n_observations, n_targets), optional*
  : Target data to pass to `partial_fit`.

  **warmup_size** *int, default=252*
  : Number of initial observations (or periods when `freq` is set) used for the
    first `partial_fit` call. No predictions are made during warmup.

  **test_size** *int, default=1*
  : Length of each test set.
    If `freq` is `None` (default), it represents the number of observations.
    Otherwise, it represents the number of periods defined by `freq`. Controls the
    rebalancing frequency.

  **freq** *str | pandas.offsets.BaseOffset, optional*
  : If provided, it must be a frequency string or a pandas DateOffset, and `X` must
    be a DataFrame with an index of type `DatetimeIndex`. In that case,
    `warmup_size` and `test_size` represent the number of periods defined by `freq`
    instead of the number of observations.

  **freq_offset** *pandas.offsets.BaseOffset | datetime.timedelta, optional*
  : Only used if `freq` is provided. Offsets `freq` by a pandas DateOffset or a
    datetime timedelta offset.

  **previous** *bool, default=False*
  : Only used if `freq` is provided. If set to `True`, and if the period start or
    period end is not in the `DatetimeIndex`, the previous observation is used;
    otherwise, the next observation is used.

  **purged_size** *int, default=0*
  : The number of observations to exclude from the end of each training window
    before the test window. Use `purged_size >= 1` when execution is delayed
    relative to observation.

  **reduce_test** *bool, default=False*
  : If set to `True`, the last test window is returned even if it is partial,
    otherwise it is ignored.

  **params** *dict, optional*
  : Parameters to pass to the underlying estimator’s `partial_fit` through metadata
    routing.

  **portfolio_params** *dict, optional*
  : Portfolio parameters for the evaluation.
    <br/>
    Parameters shared by [`Portfolio`](https://skfolio.org/generated/skfolio.portfolio.Portfolio.html.md#skfolio.portfolio.Portfolio) and
    [`MultiPeriodPortfolio`](https://skfolio.org/generated/skfolio.portfolio.MultiPeriodPortfolio.html.md#skfolio.portfolio.MultiPeriodPortfolio) (`compounded`,
    `risk_free_rate`, `annualization_factor`, `fitness_measures` and the risk
    measure parameters) are applied to the returned `MultiPeriodPortfolio` and to
    each `Portfolio` it contains. A value passed here takes precedence over the
    optimizer’s `portfolio_params`. When omitted here, it is inherited from the
    optimizer’s `portfolio_params`. When omitted from both, `risk_free_rate` falls
    back to the optimizer’s `risk_free_rate` parameter when it has one. These
    parameters only affect how the portfolios are measured, not the optimization.
    <br/>
    `weight_drift` applies to each `Portfolio` of the path. With
    `weight_drift=True`, the weights held within each test window drift with the
    asset returns, and the path runs sequentially: the `ending_weights` of each
    portfolio are passed as `previous_weights` to the next update. A value passed
    here overrides the optimizer’s `portfolio_params`.
    Failed and empty portfolios do not update the previous holdings.
    <br/>
    Optimizer parameters such as `transaction_costs`, `management_fees` and
    `previous_weights` are not accepted here. Set them on the optimizer.
    <br/>
    `name`, `tag`, `sample_weight` and `check_observations_order` apply to the
    returned `MultiPeriodPortfolio` only.

  **entry_rebalancing_params** *dict, optional*
  : Portfolio optimizer parameters applied only while constructing the first
    portfolio. This is useful when the strategy starts with no existing position,
    while later portfolios represent regular rebalancing from the previously
    predicted weights. For example, the entry rebalancing can relax `max_turnover`
    or use lower `transaction_costs` to avoid a slow ramp from cash caused by
    recurring rebalancing constraints. The first portfolio is included in the
    result. The regular optimizer parameters are restored before the next online
    update.
* **Returns:**
  **prediction** *MultiPeriodPortfolio*
  : A [`MultiPeriodPortfolio`](https://skfolio.org/generated/skfolio.portfolio.MultiPeriodPortfolio.html.md#skfolio.portfolio.MultiPeriodPortfolio) containing one
    [`Portfolio`](https://skfolio.org/generated/skfolio.portfolio.Portfolio.html.md#skfolio.portfolio.Portfolio) per test window, ordered chronologically.
* **Raises:**
  TypeError
  : If the estimator is not a portfolio optimization estimator, does not
    implement `partial_fit`, or is a pipeline.

  ValueError
  : If `warmup_size < 1`, `test_size < 1`, or the data is too short for at least one
    test window.

#### SEE ALSO
[Online Evaluation of Portfolio Optimization](https://skfolio.org/auto_examples/online_learning/plot_3_online_portfolio_optimization_evaluation.html.md#sphx-glr-auto-examples-online-learning-plot-3-online-portfolio-optimization-evaluation-py)
: Online evaluation of portfolio optimization using `online_predict`.

### Notes

When the estimator needs previous weights, each portfolio’s `ending_weights` are
passed as `previous_weights` to the next update. Otherwise, previous weights are
assigned to the predicted portfolios afterward for turnover and cost calculations.
Ending weights equal the target `weights` when `weight_drift=False` and the
weights after the last observation when `weight_drift=True`. Failed and empty
portfolios are skipped when propagating holdings, preserving the last valid weights.

### Examples

```pycon
>>> from skfolio.datasets import load_sp500_dataset
>>> from skfolio.model_selection import online_predict
>>> from skfolio.moments import EWCovariance, EWMu
>>> from skfolio.optimization import MeanRisk
>>> from skfolio.preprocessing import prices_to_returns
>>> from skfolio.prior import EmpiricalPrior
>>>
>>> prices = load_sp500_dataset()
>>> X = prices_to_returns(prices).tail(504)
>>>
>>> model = MeanRisk(
...     prior_estimator=EmpiricalPrior(
...         mu_estimator=EWMu(half_life=40),
...         covariance_estimator=EWCovariance(half_life=40),
...     ),
... )
>>> pred = online_predict(model, X, warmup_size=252, test_size=5)
```

