<a id="skfolio-model-selection-onlinegridsearch"></a>

# skfolio.model_selection.OnlineGridSearch

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

### *class* skfolio.model_selection.OnlineGridSearch(estimator, param_grid, \*, scoring=None, warmup_size=252, test_size=1, freq=None, freq_offset=None, previous=False, purged_size=0, reduce_test=False, refit=True, error_score=nan, return_predictions=False, portfolio_params=None, entry_rebalancing_params=None, n_jobs=None, verbose=0)

Online exhaustive hyperparameter search over a parameter grid.

Each parameter combination is evaluated by running a full online
walk-forward pass. The best estimator is selected based on the
aggregate out-of-sample score.

* **Parameters:**
  **estimator** *BaseEstimator*
  : Estimator that supports `partial_fit`.

  **param_grid** *dict or list[dict]*
  : Dictionary with parameters names (`str`) as keys and lists of parameter
    settings to try as values, or a list of such dictionaries, in which case the
    grids spanned by each dictionary in the list are explored. This enables
    searching over any sequence of parameter settings.

  **scoring** *callable, dict, BaseMeasure, or None*
  : Scoring specification. Semantics depend on the estimator type:
    * **Component estimators** (e.g. covariance, expected returns):
      `None` uses `estimator.score`; otherwise pass a callable
      `scorer(estimator, X_test)` or a dict of such callables.
    * **Portfolio optimization estimators**:
      a [`BaseMeasure`](https://skfolio.org/generated/skfolio.measures.BaseMeasure.html.md#skfolio.measures.BaseMeasure) or a dict of measures.
      `None` defaults to
      `SHARPE_RATIO`.
    <br/>
    For portfolio optimization estimators, online evaluation scores the
    aggregated out-of-sample
    [`MultiPeriodPortfolio`](https://skfolio.org/generated/skfolio.portfolio.MultiPeriodPortfolio.html.md#skfolio.portfolio.MultiPeriodPortfolio), rather than scoring
    each test window independently and averaging as in
    `GridSearchCV`. Pass the measure enum
    directly; `make_scorer` is not supported.

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

  **test_size** *int, default=1*
  : Number of observations (or periods when `freq` is set) per test
    window.

  **freq** *str | pandas.offsets.BaseOffset, optional*
  : Rebalancing frequency. When provided, `warmup_size` and `test_size`
    are interpreted as period counts rather than observation counts, and
    `X` must be a DataFrame with a `DatetimeIndex`. See
    [`WalkForward`](https://skfolio.org/generated/skfolio.model_selection.WalkForward.html.md#skfolio.model_selection.WalkForward) for details and
    examples.

  **freq_offset** *pandas.offsets.BaseOffset | datetime.timedelta, optional*
  : Offset applied to the `freq` boundaries. Only used when `freq` is
    provided.

  **previous** *bool, default=False*
  : Only used when `freq` is provided. If `True`, period boundaries
    that fall between observations snap to the previous observation;
    otherwise they snap to the next.

  **purged_size** *int, default=0*
  : Number of observations (or periods) to skip between the last data the
    model sees and the start of the test window.

  **reduce_test** *bool, default=False*
  : If `True`, the last test window is included even when it contains
    fewer observations than `test_size`.

  **refit** *bool, str, or callable, default=True*
  : Controls how the best candidate is selected and whether the
    selected fitted candidate is exposed as `best_estimator_`.
    <br/>
    This parameter is named for API alignment with scikit-learn.
    Unlike scikit-learn search estimators, enabling `refit` does
    not trigger an additional fit after model selection because
    each candidate is already evaluated through a full online
    walk-forward pass and updated through the full sample.
    * Single-metric scoring: `True` or `False` are both supported.
      If `False`, `best_estimator_` is not stored, but
      `best_index_`, `best_params_`, and `best_score_` remain
      available.
    * Multi-metric scoring: set to a scorer name to select the best
      candidate for that metric, or to `False` to disable
      best-candidate selection and storage of `best_estimator_`.
    * A callable receives `cv_results_` and must return the best
      candidate index.

  **error_score** *“raise” or float, default=np.nan*
  : Value to assign to the score if an error occurs during fitting.
    If set to `"raise"`, the error is raised.

  **return_predictions** *bool, default=False*
  : If `True`, store
    [`MultiPeriodPortfolio`](https://skfolio.org/generated/skfolio.portfolio.MultiPeriodPortfolio.html.md#skfolio.portfolio.MultiPeriodPortfolio) objects per
    candidate in `cv_results_["predictions"]`. Only applies to
    portfolio optimization estimators.

  **portfolio_params** *dict, optional*
  : Portfolio parameters for the evaluation of each candidate parameter set.
    <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 `MultiPeriodPortfolio` scored for each
    parameter set 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, so they can change the scores and the ranking of the
    parameter sets.
    <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`. When refitting is enabled,
    `weight_drift` is retained in `best_estimator_`. The other parameters are not.
    <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
    scored `MultiPeriodPortfolio` only.

  **entry_rebalancing_params** *dict, optional*
  : Portfolio optimizer parameters applied only while constructing the first
    portfolio in the online path for each candidate parameter set. 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 use lower `transaction_costs` or require a
    valid initial solution with `fallback=None`. Only supported for portfolio
    optimization estimators.

  **n_jobs** *int, optional*
  : Number of parallel jobs. `None` means 1.

  **verbose** *int, default=0*
  : Verbosity level for `joblib.Parallel`.
* **Attributes:**
  **cv_results_** *dict[str, ndarray]*
  : A dict with keys:
    * `params`: list of candidate parameter dicts.
    * `mean_score`: array of aggregate scores (or
      `mean_score_<name>` for multi-metric).
    * `rank`: array of ranks where 1 is best (or `rank_<name>`
      for multi-metric).
    * `fit_time`: array of wall-clock times.
    * `predictions`: object array of `MultiPeriodPortfolio` or `None`
      aligned with candidates (only when `return_predictions=True` and
      the estimator is portfolio-based).

  **best_estimator_** *BaseEstimator*
  : Estimator fitted on the full data with the best parameters.
    Only available when `refit` is not `False`.

  **best_score_** *float*
  : Aggregate score of the selected best candidate. Available when
    `best_index_` is defined and `refit` is not callable.

  **best_params_** *dict*
  : Parameter setting that gave the selected best score. Available when
    `best_index_` is defined.

  **best_index_** *int*
  : Index into `cv_results_` of the best candidate. Available for
    single-metric scoring and for multi-metric scoring when `refit` is
    not `False`.

  **multimetric_** *bool*
  : Whether or not the scorers compute several metrics.

  **is_portfolio_estimator_** *bool*
  : Whether or not the estimator is a portfolio optimization estimator.

### Methods

| [`fit`](#skfolio.model_selection.OnlineGridSearch.fit)(X[, y])            | Run the online search over all candidate parameter combinations.   |
|-------------------------------------------------------------------------|--------------------------------------------------------------------|
| [`get_metadata_routing`](#skfolio.model_selection.OnlineGridSearch.get_metadata_routing)() | Get metadata routing of this object.                               |
| [`get_params`](#skfolio.model_selection.OnlineGridSearch.get_params)([deep])     | Get parameters for this estimator.                                 |
| [`predict`](#skfolio.model_selection.OnlineGridSearch.predict)(X)             | Predict using the best estimator found during search.              |
| [`score`](#skfolio.model_selection.OnlineGridSearch.score)(X[, y])          | Score using the best estimator found during search.                |
| [`set_params`](#skfolio.model_selection.OnlineGridSearch.set_params)(\*\*params) | Set the parameters of this estimator.                              |

#### SEE ALSO
[Online Covariance Hyperparameter Tuning](https://skfolio.org/auto_examples/online_learning/plot_2_online_hyperparameter_tuning.html.md#sphx-glr-auto-examples-online-learning-plot-2-online-hyperparameter-tuning-py)
: Exhaustive online tuning of covariance estimator hyperparameters.

[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)
: Exhaustive online tuning of a `MeanRisk` estimator.

### Examples

```pycon
>>> from skfolio.datasets import load_sp500_dataset
>>> from skfolio.model_selection import OnlineGridSearch
>>> 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(),
...         covariance_estimator=EWCovariance(),
...     ),
... )
>>> search = OnlineGridSearch(
...     model,
...     param_grid={
...         "prior_estimator__mu_estimator__half_life": [20, 40, 60],
...         "prior_estimator__covariance_estimator__half_life": [20, 40, 60],
...     },
...     warmup_size=252,
...     test_size=5,
...     n_jobs=-1,
... )
>>> search.fit(X)
OnlineGridSearch(...)
>>> search.best_params_
{'prior_estimator__covariance_estimator__half_life': 60,
 'prior_estimator__mu_estimator__half_life': 20}
>>> search.best_estimator_
MeanRisk(...)
```

<a id="skfolio.model_selection.OnlineGridSearch.fit"></a>

#### fit(X, y=None, \*\*fit_params)

Run the online search over all candidate parameter combinations.

* **Parameters:**
  **X** *array-like of shape (n_observations, n_assets)*
  : Price returns.

  **y** *array-like, optional*
  : Optional Target.

  **\*\*fit_params**
  : Additional parameters routed via metadata routing.
* **Returns:**
  self

<a id="skfolio.model_selection.OnlineGridSearch.get_metadata_routing"></a>

#### get_metadata_routing()

Get metadata routing of this object.

Please check [User Guide](https://skfolio.org/user_guide/metadata_routing.html.md#metadata-routing) on how the routing
mechanism works.

* **Returns:**
  **routing** *MetadataRequest*
  : A `MetadataRequest` encapsulating
    routing information.

<a id="skfolio.model_selection.OnlineGridSearch.get_params"></a>

#### get_params(deep=True)

Get parameters for this estimator.

* **Parameters:**
  **deep** *bool, default=True*
  : If True, will return the parameters for this estimator and
    contained subobjects that are estimators.
* **Returns:**
  **params** *dict*
  : Parameter names mapped to their values.

<a id="skfolio.model_selection.OnlineGridSearch.predict"></a>

#### predict(X)

Predict using the best estimator found during search.

* **Parameters:**
  **X** *array-like of shape (n_observations, n_assets)*
  : Price returns.
* **Returns:**
  **prediction** *Portfolio | Population*

<a id="skfolio.model_selection.OnlineGridSearch.score"></a>

#### score(X, y=None)

Score using the best estimator found during search.

* **Parameters:**
  **X** *array-like of shape (n_observations, n_assets)*
  : Price returns.

  **y** *Ignored*
  : Present for scikit-learn API compatibility.
* **Returns:**
  **score** *float*

<a id="skfolio.model_selection.OnlineGridSearch.set_params"></a>

#### set_params(\*\*params)

Set the parameters of this estimator.

The method works on simple estimators as well as on nested objects
(such as `Pipeline`). The latter have
parameters of the form `<component>__<parameter>` so that it’s
possible to update each component of a nested object.

* **Parameters:**
  **\*\*params** *dict*
  : Estimator parameters.
* **Returns:**
  **self** *estimator instance*
  : Estimator instance.

