<a id="metadata-routing"></a>

<a id="id1"></a>

# Metadata Routing

This document shows how you can use the metadata routing mechanism to route metadata
to the estimators consuming them.
For a complete explanation, you can refer to the [scikit-learn documentation](https://scikit-learn.org/stable/auto_examples/miscellaneous/plot_metadata_routing.html#sphx-glr-auto-examples-miscellaneous-plot-metadata-routing-py)

A full example is available here: [Using Implied Volatility with Metadata Routing](https://skfolio.org/auto_examples/metadata_routing/plot_1_implied_volatility.html.md#sphx-glr-auto-examples-metadata-routing-plot-1-implied-volatility-py)

Let’s suppose you use the [`ImpliedCovariance`](https://skfolio.org/generated/skfolio.moments.ImpliedCovariance.html.md#skfolio.moments.ImpliedCovariance) estimator
inside a [`MeanRisk`](https://skfolio.org/generated/skfolio.optimization.MeanRisk.html.md#skfolio.optimization.MeanRisk) estimator.
In addition to the assets’ returns `X`, the `ImpliedCovariance` estimator also needs
the assets’ implied volatilities passed to its `fit` method.
In order to route the implied volatilities time series from the `MeanRisk` estimator
to the `ImpliedCovariance` estimator, we need metadata routing.

First, a few imports and some random data for the rest of the script:

```python
from sklearn import set_config

from skfolio.moments import ImpliedCovariance
from skfolio.optimization import MeanRisk
from skfolio.prior import EmpiricalPrior
from skfolio.preprocessing import prices_to_returns
from skfolio.datasets import load_sp500_dataset, load_sp500_implied_vol_dataset

prices = load_sp500_dataset()
implied_vol = load_sp500_implied_vol_dataset()

X = prices_to_returns(prices)
X = X.loc["2010":]
```

Metadata routing is available only if explicitly enabled:

```python
set_config(enable_metadata_routing=True)
```

Then, in order to route the metadata, you must use `set_fit_request`:

```python
model = MeanRisk(
    prior_estimator=EmpiricalPrior(
        covariance_estimator=ImpliedCovariance(
        ).set_fit_request(implied_vol=True)
    )
)
model.fit(X, implied_vol=implied_vol)
print(model.weights_)
```
