Skip to main content

Constructing minimum variance portfolios

Project description

fast-minimum-variance: Solving Minimum Variance Portfolios Fast

Python License Rhiza

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

fast_minimum_variance-0.2.1.tar.gz (202.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fast_minimum_variance-0.2.1-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

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

Hashes for fast_minimum_variance-0.2.1.tar.gz
Algorithm Hash digest
SHA256 cb23beef20ea9d624aebc5627baaeb7593d368ff169a01ff278b7e9903177cb6
MD5 89866fb701deaee71e2853b695e3ae60
BLAKE2b-256 cde82a6c30e93dd6b8d6ad74e93d25f969dbcafcea09588d8cb3e9b48bcf974e

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fast_minimum_variance-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fast_minimum_variance-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 567244a97e521e3299a30f0bf1f788765d4673ed42da62500b6e1544f19e7279
MD5 30b3a76e587fd38f2512a2ed59ec6508
BLAKE2b-256 fcbcf58cd80432b6d82d5f55db15d0576af6e02d9009da5d945cb124eef3f467

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page