PyPortfolioOpt
Prices in, weights out — efficient frontier, Black-Litterman and HRP.
by PyPortfolio
Last updated
What it is
PyPortfolioOpt is the library most people meet first when they go looking for Markowitz in
Python. The shape is deliberately scikit-learn-ish: expected_returns and risk_models turn a
price DataFrame into a mean vector and a covariance matrix, EfficientFrontier takes the pair and
solves for weights under max_sharpe(), min_volatility(), efficient_risk() or
efficient_return(), and DiscreteAllocation turns the resulting fractions into how many shares
to buy with the cash you actually have.
Around that core: shrinkage covariance (Ledoit-Wolf, oracle approximating, exponentially
weighted), L2 regularisation and sector constraints through objective_functions,
BlackLittermanModel for folding absolute or relative views into the prior, HRPOpt for
hierarchical risk parity, CLA for Markowitz's critical line algorithm, and efficient
semivariance, CVaR and CDaR frontiers in their own modules.
The project changed hands in 2026, and that is the fact worth knowing before you depend on it.
The repository now lives under the PyPortfolio organisation — the old robertmartin8 URL
redirects — and carries a GC.OS sponsorship badge, the same stewardship arrangement as sktime.
Version 1.6.0 landed on 26 February 2026 after 1.5.6 in December 2024, and its notes read like a
rescue rather than a feature release: Python 3.14 and pandas 3 support, Python 3.8 and 3.9 retired,
soft dependencies moved out of the core install, CI rebuilt. The published package metadata still
names Robert Andrew Martin as maintainer; the release was cut by Franz Király.
Pricing
Free and MIT, with nothing for sale — no pro build, no hosted tier, no data bundle. What is not
free of charge in the licence sense is the all-extras depset, which adds matplotlib, plotly,
ecos and cvxopt. The last two are GPLv3. That is irrelevant if you are running research on your
own machine and material if you redistribute a binary.
Data & coverage
None, and that is by design. Grep the installed package for a network call and you find nothing: no bundled dataset, no fetcher, no vendor client. Asset classes and markets are whatever your price series covers, so the library is as global as your data source is.
Integrations
cvxpy does the solving, so anything cvxpy supports is available by passing solver=. Hard
dependencies are numpy, pandas, scipy, scikit-learn and — new in 1.6.0 — scikit-base, the
base-class package from the sktime ecosystem, which is the clearest signal of where the project now
sits. Weights come back as a dict or an OrderedDict; save_weights_to_file writes csv, json or
txt, and everything else is a pandas object you export yourself.
Limitations
- No data and no backtest. If you arrived from a backtesting framework expecting to test a rebalancing rule, this is the wrong shelf — it computes one weight vector per call, and looping it over time is your code.
- Mean-variance is only as good as the expected returns you feed it, and the README says so. Historical means are a poor forecast, which is the reason Black-Litterman and shrinkage are in the package at all.
DiscreteAllocation.lp_portfolio()needs a mixed-integer solver. It currently defaults to ECOS_BB whenecosis installed and warns that in 1.7.0 the default becomes cvxpy's own choice — code written against today's behaviour will need an explicitsolver=argument.- PyPI still classifies it Development Status 4 - Beta, eight years in.
- 82 open issues and a release cadence measured in years, not weeks. The new maintainers are real but the backlog is real too.
Alternatives
Riskfolio-Lib covers far more risk measures and is the one to reach for if CVaR, drawdown-at-risk or Kelly objectives are the point. skfolio is the scikit-learn-native take, with cross-validation and hyper-parameter search around the optimiser rather than bolted on. Portfolio Optimizer does the same mathematics over HTTP for people who are not writing Python at all, and Portfolio Visualizer is the no-code version of the question.
Specs
- Interfaces
- Python, Python
- Export
- CSV, JSON
- Asset classes
- Stocks, ETF, Bonds, Commodities
- Markets
- Global
- Platforms
- Library
- AI features
- None
- Pricing verified
- Capabilities verified
- Coverage verified
Also worth comparing
- Riskfolio-Lib — Twenty-six convex risk measures, four objectives, one cvxpy-backed optimiser.
- skfolio — Portfolio optimisation as scikit-learn estimators — fit, predict, cross-validate.
- Portfolio Optimizer — 248 portfolio maths endpoints over HTTP — no install, no solver, no account.
- arch — GARCH and the rest of the volatility-model family, plus the tests you need around them.
- empyrical-reloaded — The maintained fork of Quantopian's empyrical — risk statistics, no plots.
- ffn — Performance stats, drawdowns and portfolio weights from a DataFrame of prices.
FAQ
Is PyPortfolioOpt still maintained?
Yes, by different people than wrote it. The repository moved from robertmartin8 to the PyPortfolio organisation, where it is a GC.OS sponsored project, and version 1.6.0 shipped on 26 February 2026 after fourteen months without a release. The last commit to main was 7 July 2026, the repository is not archived, and 82 issues are open excluding pull requests.
Does PyPortfolioOpt download prices or run a backtest?
Neither. Nothing in the installed package makes a network call — no yfinance, no requests, no urllib — and there is no simulation loop, no rebalancing schedule and no broker. You hand it a price or returns DataFrame you sourced yourself, and it hands you a weight vector back.
Which solver do I need, and do I have to pay for one?
No. cvxpy is a hard dependency and the solvers it installs handle everything on the continuous side. The one exception is the integer allocation step, DiscreteAllocation.lp_portfolio, which needs a mixed-integer solver and defaults to ECOS_BB when the optional ecos package is present.
Is the licence really MIT?
The LICENSE file is MIT and so is every line you import. Watch the optional extras rather than the core — the all-extras depset installs ecos and cvxopt, both of which are GPLv3, so a team that ships binaries should install them deliberately rather than by reflex.