# Portfolio Optimization with PyPortfolioOpt and Riskfolio-Lib: A Practical Guide

> Master portfolio optimization with PyPortfolioOpt and Riskfolio-Lib. Learn to build risk-adjusted portfolios using modern techniques integrated into systematic trading.

- Repository: [Papers With Backtest/awesome-systematic-trading](https://github.com/paperswithbacktest/awesome-systematic-trading)
- Tags: how-to-guide
- Published: 2026-08-01

---

**Portfolio optimization with PyPortfolioOpt and Riskfolio-Lib enables quantitative researchers to construct risk-adjusted portfolios using classical mean-variance techniques and modern hierarchical risk models, seamlessly integrated into the systematic trading pipeline curated in the `paperswithbacktest/awesome-systematic-trading` repository.**

The `paperswithbacktest/awesome-systematic-trading` repository serves as a comprehensive catalog of 97+ libraries for quantitative finance, positioning these two Python packages at the core of the asset allocation workflow. Both tools transform raw return matrices into optimized weight vectors, bridging the gap between data ingestion and backtesting execution.

## Architectural Role in the Quantitative Pipeline

Within the ecosystem outlined in the repository's README, **PyPortfolioOpt** and **Riskfolio-Lib** occupy the critical optimization layer between data preprocessing and strategy execution. According to the source code analysis, the pipeline flows through distinct stages:

- **Data Acquisition**: Libraries like `yfinance` and `AkShare` fetch historical series (referenced in [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) at line 119).
- **Optimization Layer**: `PyPortfolioOpt` solves convex problems including mean-variance and Black-Litterman models, while `Riskfolio-Lib` provides multi-objective optimization with CVaR and Omega risk measures (documented at lines 179 and 180).
- **Backtesting Consumption**: Generated weights feed into engines like `backtrader` or `QuantConnect` (listed at line 87).
- **Performance Analytics**: Metrics computation via `quantstats` or `pyfolio` evaluates the optimized allocations (found at line 67).

This architecture ensures that once you compute returns from raw price data, you can pass clean matrices to either optimizer and receive portfolio weights ready for live deployment or historical simulation.

## PyPortfolioOpt: Convex Optimization Methods

Listed at line 179 of [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md), **PyPortfolioOpt** specializes in classical portfolio theory implementations. The library provides the `EfficientFrontier` class along with modules for `risk_models` and `expected_returns`, enabling users to solve minimum-variance, maximum-Sharpe, and market-implied Black-Litterman allocations.

### Minimum-Variance Portfolio Implementation

The following implementation demonstrates the `EfficientFrontier` object solving for minimum volatility without requiring expected return estimates:

```python
import pandas as pd
import yfinance as yf
from pypfopt import EfficientFrontier, risk_models, expected_returns

# Download price data for universe construction

tickers = ["AAPL", "MSFT", "GLD", "TLT"]
prices = yf.download(tickers, start="2020-01-01")["Adj Close"]

# Compute daily returns matrix

returns = prices.pct_change().dropna()

# Estimate covariance using sample covariance

cov_matrix = risk_models.sample_cov(returns)

# Initialize frontier with covariance only (no expected returns required)

ef = EfficientFrontier(None, cov_matrix)

# Solve minimum variance optimization

weights = ef.min_volatility()
cleaned_weights = ef.clean_weights()

print("Min-variance weights:")
print(cleaned_weights)

# Extract performance metrics

expected_annual_ret = ef.expected_return()
annual_vol = ef.portfolio_performance()[1]
print(f"Expected annual return: {expected_annual_ret:.2%}")
print(f"Annual volatility:      {annual_vol:.2%}")

```

The `clean_weights()` method rounds near-zero positions to exactly zero, producing a tradable allocation vector suitable for brokerage API submission.

## Riskfolio-Lib: Advanced Risk-Aware Allocation

Documented immediately below PyPortfolioOpt at line 180, **Riskfolio-Lib** extends beyond traditional mean-variance frameworks. The library supports hierarchical risk parity (HRP), conditional value-at-risk (CVaR) minimization, and Omega ratio optimization, while handling complex constraint sets through the `Portfolio` class interface.

### Hierarchical Risk Parity Optimization

This example utilizes `rp.Portfolio` with historical methods for mean and covariance estimation, applying the HRP algorithm that constructs portfolios based on the dendrogram structure of asset correlations:

```python
import pandas as pd
import yfinance as yf
import riskfolio as rp

# Fetch historical prices

tickers = ["AAPL", "MSFT", "GLD", "TLT"]
prices = yf.download(tickers, start="2020-01-01")["Adj Close"]

# Calculate log-returns for optimization input

ret = prices.pct_change().dropna()

# Instantiate portfolio object

port = rp.Portfolio(returns=ret)

# Configure estimation methods and constraints

port.assets_stats(method_mu='hist', method_cov='hist')
port.set_constraints(w_min=0, w_max=1)  # Enforce long-only positions

# Execute HRP optimization

weights = port.optimise(method='HRP')
print("HRP weights:")
print(weights.T)

```

The `assets_stats()` method computes the necessary distributional parameters, while `optimise(method='HRP')` invokes the machine learning-based allocation that typically produces more stable out-of-sample weights than traditional inverse-volatility approaches.

## Repository Integration Points

To locate these tools within the `paperswithbacktest/awesome-systematic-trading` codebase:

| Component | Location | Direct Link |
|-----------|----------|-------------|
| **PyPortfolioOpt** | [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) line 179 | Optimization table |
| **Riskfolio-Lib** | [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) line 180 | Optimization table |
| **Data Sources** | [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) line 119 | Price data acquisition |
| **Backtesting Engines** | [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) line 87 | Weight consumption |
| **Analytics** | [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) line 67 | Post-optimization metrics |

These specific line references allow practitioners to verify library versions, documentation links, and complementary tools within the curated list.

## Summary

- **PyPortfolioOpt** (line 179) provides efficient convex solvers for mean-variance, minimum-volatility, and Black-Litterman portfolios using the `EfficientFrontier` class.
- **Riskfolio-Lib** (line 180) delivers sophisticated risk models including CVaR, Omega, and HRP through the `Portfolio` object with extensive constraint handling.
- Both libraries accept preprocessed return matrices from data sources listed at line 119 and generate weights consumable by backtesters documented at line 87.
- The `clean_weights()` method in PyPortfolioOpt and `set_constraints()` in Riskfolio-Lib ensure outputs meet real-world trading restrictions.

## Frequently Asked Questions

### What differentiates PyPortfolioOpt from Riskfolio-Lib?

**PyPortfolioOpt** focuses on classical convex optimization problems such as mean-variance efficiency and Black-Litterman models, utilizing `scipy` and `cvxpy` solvers. **Riskfolio-Lib** extends into modern risk measures like CVaR and Omega while providing hierarchical clustering methods (HRP) and multi-objective optimization capabilities that exceed traditional quadratic programming frameworks.

### How do I connect these optimizers to backtesting frameworks?

After generating weights via `ef.clean_weights()` or `port.optimise()`, export the resulting allocation vector to a pandas DataFrame with datetime indexing. Pass this series to backtesting engines like `backtrader` or `zipline` (referenced at [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md) line 87) as the target position dictionary for each rebalancing date.

### Which risk models are exclusive to Riskfolio-Lib?

While PyPortfolioOpt handles variance, semi-variance, and CVaR through quadratic programming, Riskfolio-Lib uniquely implements the **Omega ratio**, ** Sortino ratio**, **Fama-French factor constraints**, and **hierarchical risk parity** without requiring convexity assumptions, making it suitable for non-normal return distributions.

### Where are these libraries documented in the Awesome Systematic Trading repository?

Both packages appear in the **Optimization** section of [`README.md`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/README.md), with **PyPortfolioOpt** specifically at line 179 and **Riskfolio-Lib** at line 180. The repository lists installation commands, GitHub source links, and brief descriptions of each library's mathematical foundations adjacent to these line numbers.