Constructing minimum variance portfolios
Project description
fast-minimum-variance: Solving Minimum Variance Portfolios Fast
Overview
fast-minimum-variance is a Python library for computing long-only minimum variance portfolios without ever forming the sample covariance matrix. By operating directly on the returns matrix $R \in \mathbb{R}^{T \times N}$, it exposes a clean hierarchy of solvers — from an exact direct KKT solve to matrix-free Krylov methods — that scale gracefully as $N$ grows.
The core insight is that minimising portfolio variance is equivalent to minimising $|Rw|^2$, which can be evaluated using two matrix-vector products $w \mapsto R^\top(Rw)$ without constructing $R^\top R$ explicitly. This reframing connects the portfolio optimisation literature directly to Krylov subspace methods.
The long-only constraint $w \geq 0$ is handled throughout via an active-set method: solve the unconstrained problem on the current active set, drop assets with negative weights, and repeat. The process terminates in at most $N$ iterations.
Solvers
| Solver | Module | Method | Notes |
|---|---|---|---|
minvar_kkt |
kkt |
Direct KKT via numpy.linalg.solve |
Exact; baseline for accuracy comparisons |
minvar_minres |
krylov |
MINRES on the indefinite KKT system | Matrix-free capable; handles indefiniteness correctly |
minvar_cg |
krylov |
CG in the constraint-reduced space | Positive-definite reduced system; no indefinite solver needed |
minvar_cvxpy |
cvx |
General-purpose convex solver via CVXPY | Reference implementation; slowest but most flexible |
All solvers return a weight vector $w \in \mathbb{R}^N$ satisfying $\sum_i w_i = 1$ and $w_i \geq 0$.
Quick Start
from fast_minimum_variance.random import make_returns
from fast_minimum_variance.kkt import minvar_kkt
from fast_minimum_variance.krylov import minvar_cg, minvar_minres
from fast_minimum_variance.cvx import minvar_cvxpy
# Generate a synthetic return matrix: 500 daily returns, 20 assets
R = make_returns(T=500, N=20, seed=42)
# Solve with any of the available solvers
w_kkt = minvar_kkt(R) # exact KKT solve
w_minres = minvar_minres(R) # MINRES on the indefinite KKT system
w_cg = minvar_cg(R) # CG in the constraint-reduced space
w_cvxpy = minvar_cvxpy(R) # CVXPY reference
# All solutions satisfy the portfolio constraints
assert abs(w_kkt.sum() - 1.0) < 1e-8
assert (w_kkt >= 0).all()
The KKT System
The equality-constrained minimum variance problem yields the $(N+1) \times (N+1)$ KKT system:
$$\begin{pmatrix} 2R^\top R & \mathbf{1} \cr \mathbf{1}^\top & 0 \end{pmatrix} \begin{pmatrix} w \cr \lambda \end{pmatrix} = \begin{pmatrix} \mathbf{0} \cr 1 \end{pmatrix}$$
This system is symmetric but indefinite — the zero in the bottom-right corner of the KKT matrix introduces a negative eigenvalue. This rules out standard CG on the full system, but it opens the door to MINRES. Alternatively, the CG solver eliminates the constraint entirely by parameterising $w = w_0 + Pv$ where $P$ spans the null space of $\mathbf{1}^\top$, yielding a positive-definite reduced system of size $(N-1) \times (N-1)$.
Installation
pip install fast-minimum-variance
For development:
git clone https://github.com/Jebel-Quant/fast_minimum_variance
cd fast_minimum_variance
make install
Requirements
- Python 3.11+
- numpy
- scipy
- cvxpy
Citing
If you use this library in academic work or research, please cite:
@software{fast_minimum_variance,
author = {Schmelzer, Thomas},
title = {fast-minimum-variance: Solving Minimum Variance Portfolios Fast},
url = {https://github.com/Jebel-Quant/fast_minimum_variance},
year = {2026},
license = {MIT}
}
License
MIT License — see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fast_minimum_variance-0.2.1.tar.gz.
File metadata
- Download URL: fast_minimum_variance-0.2.1.tar.gz
- Upload date:
- Size: 202.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb23beef20ea9d624aebc5627baaeb7593d368ff169a01ff278b7e9903177cb6
|
|
| MD5 |
89866fb701deaee71e2853b695e3ae60
|
|
| BLAKE2b-256 |
cde82a6c30e93dd6b8d6ad74e93d25f969dbcafcea09588d8cb3e9b48bcf974e
|
Provenance
The following attestation bundles were made for fast_minimum_variance-0.2.1.tar.gz:
Publisher:
rhiza_release.yml on Jebel-Quant/fast_minimum_variance
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fast_minimum_variance-0.2.1.tar.gz -
Subject digest:
cb23beef20ea9d624aebc5627baaeb7593d368ff169a01ff278b7e9903177cb6 - Sigstore transparency entry: 1399568411
- Sigstore integration time:
-
Permalink:
Jebel-Quant/fast_minimum_variance@1fcd8acc17e80acb407a3837dd63042d48add506 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/Jebel-Quant
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
rhiza_release.yml@1fcd8acc17e80acb407a3837dd63042d48add506 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fast_minimum_variance-0.2.1-py3-none-any.whl.
File metadata
- Download URL: fast_minimum_variance-0.2.1-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
567244a97e521e3299a30f0bf1f788765d4673ed42da62500b6e1544f19e7279
|
|
| MD5 |
30b3a76e587fd38f2512a2ed59ec6508
|
|
| BLAKE2b-256 |
fcbcf58cd80432b6d82d5f55db15d0576af6e02d9009da5d945cb124eef3f467
|
Provenance
The following attestation bundles were made for fast_minimum_variance-0.2.1-py3-none-any.whl:
Publisher:
rhiza_release.yml on Jebel-Quant/fast_minimum_variance
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fast_minimum_variance-0.2.1-py3-none-any.whl -
Subject digest:
567244a97e521e3299a30f0bf1f788765d4673ed42da62500b6e1544f19e7279 - Sigstore transparency entry: 1399568416
- Sigstore integration time:
-
Permalink:
Jebel-Quant/fast_minimum_variance@1fcd8acc17e80acb407a3837dd63042d48add506 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/Jebel-Quant
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
rhiza_release.yml@1fcd8acc17e80acb407a3837dd63042d48add506 -
Trigger Event:
push
-
Statement type: