# Portfolio optimization (/features/optimization/portfolio-optimization)

## Riskfolio-Lib \[#riskfolio-lib]

New in 1.7.0

✅ [Riskfolio-Lib](https://github.com/dcajasn/Riskfolio-Lib) is another increasingly popular library
for portfolio optimization that has been integrated into VBT. Integration was done
by automating typical workflows inside Riskfolio-Lib and putting them into a single function,
so many portfolio optimization problems can be expressed using a single set of keyword arguments
and easily parameterized.

```python title="Run Nested Clustered Optimization (NCO) on a monthly basis"
>>> data = vbt.YFData.pull(
...     ["SPY", "TLT", "XLF", "XLE", "XLU", "XLK", "XLB", "XLP", "XLY", "XLI", "XLV"],
...     start="2020",
...     end="2023",
...     missing_index="drop"
... )
>>> pfo = vbt.PFO.from_riskfolio(
...     returns=data.close.vbt.to_returns(),
...     port_cls="hc",
...     every="M"
... )
>>> pfo.plot().show()
```

Monthly asset weights from Riskfolio-Lib nested clustered optimization from 2020 through 2022. [Figure data (JSON)](/assets/figures/features/optimization/riskfolio-lib.c10fa4f9b800.json)

!!! info "Tutorial"
    Learn more in the [Portfolio optimization](/tutorials/portfolio-optimization) tutorial.

## Portfolio optimization \[#portfolio-optimization]

New in 1.2.0

✅ Portfolio optimization is the process of creating a portfolio of assets that aims to maximize return
and minimize risk. Usually, this process is performed periodically and involves
generating new weights to rebalance an existing portfolio. As with most things in VBT,
the weight generation step is implemented as a callback by the user, while the optimizer
calls that callback periodically. The final result is a collection of returned weight allocations
that can be analyzed, visualized, and used in actual simulations 🥧

```python title="Allocate assets inversely to their total return in the last month"
>>> def regime_change_optimize_func(data):
...     returns = data.returns
...     total_return = returns.vbt.returns.total()
...     weights = data.symbol_wrapper.fill_reduced(0)
...     pos_mask = total_return > 0
...     if pos_mask.any():
...         weights[pos_mask] = total_return[pos_mask] / total_return.abs().sum()
...     neg_mask = total_return < 0
...     if neg_mask.any():
...         weights[neg_mask] = total_return[neg_mask] / total_return.abs().sum()
...     return -1 * weights

>>> data = vbt.YFData.pull(
...     ["SPY", "TLT", "XLF", "XLE", "XLU", "XLK", "XLB", "XLP", "XLY", "XLI", "XLV"],
...     start="2020",
...     end="2023",
...     missing_index="drop"
... )
>>> pfo = vbt.PFO.from_optimize_func(
...     data.symbol_wrapper,
...     regime_change_optimize_func,
...     vbt.RepEval("data[index_slice]", context=dict(data=data)),
...     every="M"
... )
>>> pfo.plot().show()
```

Monthly regime-change portfolio allocations across eleven assets from 2020 through 2022. [Figure data (JSON)](/assets/figures/features/optimization/portfolio-optimization.f2d874e1afd4.json)

!!! info "Tutorial"
    Learn more in the [Portfolio optimization](/tutorials/portfolio-optimization) tutorial.

## PyPortfolioOpt \[#pyportfolioopt]

New in 1.2.0

✅ [PyPortfolioOpt](https://github.com/robertmartin8/PyPortfolioOpt) is a popular financial portfolio
optimization package that includes both classical methods (Markowitz 1952 and Black-Litterman),
suggested best practices (such as covariance shrinkage), and many recent developments and novel
features, like L2 regularization, shrunk covariance, and hierarchical risk parity.

```python title="Run Nested Clustered Optimization (NCO) on a monthly basis"
>>> data = vbt.YFData.pull(
...     ["SPY", "TLT", "XLF", "XLE", "XLU", "XLK", "XLB", "XLP", "XLY", "XLI", "XLV"],
...     start="2020",
...     end="2023",
...     missing_index="drop"
... )
>>> pfo = vbt.PFO.from_pypfopt(
...     returns=data.returns,
...     optimizer="hrp",
...     target="optimize",
...     every="M"
... )
>>> pfo.plot().show()
```

Monthly asset weights from PyPortfolioOpt hierarchical risk parity from 2020 through 2022. [Figure data (JSON)](/assets/figures/features/optimization/pyportfolioopt.71817c556f5b.json)

!!! info "Tutorial"
    Learn more in the [Portfolio optimization](/tutorials/portfolio-optimization) tutorial.

## Universal Portfolios \[#universal-portfolios]

New in 1.2.0

✅ [Universal Portfolios](https://github.com/Marigold/universal-portfolios) is a package that
brings together various Online Portfolio Selection (OLPS) algorithms.

```python title="Simulate an online minimum-variance portfolio on a weekly time frame"
>>> data = vbt.YFData.pull(
...     ["SPY", "TLT", "XLF", "XLE", "XLU", "XLK", "XLB", "XLP", "XLY", "XLI", "XLV"],
...     start="2020",
...     end="2023",
...     missing_index="drop"
... )
>>> pfo = vbt.PFO.from_universal_algo(
...     "MPT",
...     data.resample("W").close,
...     window=52,
...     min_history=4,
...     mu_estimator='historical',
...     cov_estimator='empirical',
...     method='mpt',
...     q=0
... )
>>> pfo.plot().show()
```

Weekly online minimum-variance portfolio weights across eleven assets from 2020 through 2022. [Figure data (JSON)](/assets/figures/features/optimization/universal-portfolios.2016998532d6.json)

!!! info "Tutorial"
    Learn more in the [Portfolio optimization](/tutorials/portfolio-optimization) tutorial.
