<a id="sphx-glr-auto-examples-mean-risk-plot-3-efficient-frontier-py"></a>

<a id="efficient-frontier"></a>

# Efficient Frontier

This tutorial uses the [`MeanRisk`](https://skfolio.org/generated/skfolio.optimization.MeanRisk.html.md#skfolio.optimization.MeanRisk) optimization to find an
ensemble of portfolios belonging to the Mean-Variance efficient frontier (Pareto front).

<a id="data"></a>

## Data

We load the S&P 500 [dataset](https://skfolio.org/user_guide/datasets.html.md#datasets) composed of the daily prices of 20
assets from the S&P 500 Index composition starting from 1990-01-02 up to 2022-12-28:

```Python
import numpy as np
from plotly.io import show
from sklearn.model_selection import train_test_split

from skfolio import PerfMeasure, RatioMeasure, RiskMeasure
from skfolio.datasets import load_sp500_dataset
from skfolio.optimization import MeanRisk
from skfolio.preprocessing import prices_to_returns

prices = load_sp500_dataset()

X = prices_to_returns(prices)
X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)
```

<a id="model"></a>

## Model

We create the Mean-Variance model and then fit it on the training set.
The parameter `efficient_frontier_size=30` is used to find 30 portfolios on the entire
efficient frontier:

```Python
model = MeanRisk(
    risk_measure=RiskMeasure.VARIANCE,
    efficient_frontier_size=30,
    portfolio_params=dict(name="Variance"),
)
model.fit(X_train)
print(model.weights_.shape)
```

```none
(30, 20)
```

<a id="prediction"></a>

## Prediction

We predict this model on both the training set and the test set.
The `predict` method returns the [`Population`](https://skfolio.org/generated/skfolio.population.Population.html.md#skfolio.population.Population) of
30 [`Portfolio`](https://skfolio.org/generated/skfolio.portfolio.Portfolio.html.md#skfolio.portfolio.Portfolio):

```Python
population_train = model.predict(X_train)
population_test = model.predict(X_test)
```

<a id="analysis"></a>

## Analysis

For improved analysis, we add a “Train” and “Test” tag to the portfolios and
concatenate the training and the test populations:

```Python
population_train.set_portfolio_params(tag="Train")
population_test.set_portfolio_params(tag="Test")

population = population_train + population_test

fig = population.plot_measures(
    x=RiskMeasure.ANNUALIZED_STANDARD_DEVIATION,
    y=PerfMeasure.ANNUALIZED_MEAN,
    color_scale=RatioMeasure.ANNUALIZED_SHARPE_RATIO,
    hover_measures=[RiskMeasure.MAX_DRAWDOWN, RatioMeasure.ANNUALIZED_SORTINO_RATIO],
)
show(fig)
```

[plotly figure stripped from llms output]<style>html[data-theme="dark"] div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}}</style><script>if (!window.plotlySphinxGalleryResize) {window.plotlySphinxGalleryResize = true;window.addEventListener("load", function () {document.querySelectorAll(".plotly-graph-div").forEach(function (gd) { Plotly.Plots.resize(gd); });});}</script>

<br/>

Let’s plot the composition of the 30 portfolios:

```Python
population_train.plot_composition()
```

<style>html[data-theme="dark"] div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}}</style><script>if (!window.plotlySphinxGalleryResize) {window.plotlySphinxGalleryResize = true;window.addEventListener("load", function () {document.querySelectorAll(".plotly-graph-div").forEach(function (gd) { Plotly.Plots.resize(gd); });});}</script>[plotly figure stripped from llms output]
<br />
<br />

Let’s print the Sharpe Ratio of the 30 portfolios on the test set:

```Python
population_test.measures(measure=RatioMeasure.ANNUALIZED_SHARPE_RATIO)
```

```none
array([0.91785162, 0.93000375, 0.9401232 , 0.95027284, 0.96861483,
       0.98463685, 0.9983657 , 1.00992555, 1.01943433, 1.02702131,
       1.032813  , 1.03704654, 1.03993049, 1.04204356, 1.0430764 ,
       1.04289017, 1.04158213, 1.03774863, 1.02943678, 1.02092595,
       1.01241175, 1.00356473, 0.97964062, 0.93749217, 0.87986871,
       0.78090544, 0.68550154, 0.59858003, 0.53398775, 0.55455742])
```

Finally, we can show a full summary of the 30 portfolios evaluated on the test set:

```Python
population.summary()
```

[plotly figure stripped from llms output]
<br />
<br />

**Total running time of the script:** (0 minutes 1.858 seconds)

<a id="sphx-glr-download-auto-examples-mean-risk-plot-3-efficient-frontier-py"></a>
