Skip to main content

Critical line algorithm for the efficient frontier

Project description

📈 cvxcla - Critical Line Algorithm for Portfolio Optimization

PyPI version License: MIT Downloads Coverage

Open in GitHub Codespaces


Quick Links: 📖 Documentation🐛 Report Bug💡 Request Feature💬 Discussions


📋 Overview

cvxcla is a Python package that implements the Critical Line Algorithm (CLA) for portfolio optimization. The CLA efficiently computes the entire efficient frontier for portfolio optimization problems with linear constraints and bounds on the weights.

The Critical Line Algorithm was introduced by Harry Markowitz in The Optimization of Quadratic Functions Subject to Linear Constraints and further described in his book Portfolio Selection.

The algorithm is based on the observation that the efficient frontier is a piecewise linear function when expected return is plotted against expected variance. The CLA computes the turning points (corners) of the efficient frontier, allowing for efficient representation of the entire frontier.

I gave the plenary talk at EQD's Singapore conference.

✨ Features

  • Efficient computation of the entire efficient frontier
  • Support for linear constraints and bounds on portfolio weights
  • Multiple implementations based on different approaches from the literature
  • Visualization of the efficient frontier using Plotly
  • Computation of the maximum Sharpe ratio portfolio
  • Fully tested and documented codebase

🚀 Installation

Using pip

pip install cvxcla

Development Setup

To set up a development environment:

  1. Clone the repository:

    git clone https://github.com/cvxgrp/cvxcla.git
    cd cvxcla
    
  2. Create a virtual environment and install dependencies:

    make install
    

This will:

  • Install the uv package manager
  • Create a Python 3.12 virtual environment
  • Install all dependencies from pyproject.toml

🔧 Usage

Here's a simple example of how to use cvxcla to compute the efficient frontier:

import numpy as np
# Set a seed for reproducibility
np.random.seed(42)
from cvxcla import CLA

# Define your portfolio problem
n = 10  # Number of assets
mean = np.random.randn(n)  # Expected returns
cov = np.random.randn(n, n)
covariance = cov @ cov.T  # Covariance matrix
lower_bounds = np.zeros(n)  # No short selling
upper_bounds = np.ones(n)  # No leverage

# Create a CLA instance
cla = CLA(
    mean = mean,
    covariance = covariance,
    lower_bounds = lower_bounds,
    upper_bounds = upper_bounds,
    a = np.ones((1, n)),  # Fully invested constraint
    b = np.ones(1)
)

# Access the efficient frontier
frontier = cla.frontier

# Get the maximum Sharpe ratio portfolio
max_sharpe_ratio, max_sharpe_weights = frontier.max_sharpe
print(f"Maximum Sharpe ratio: {max_sharpe_ratio:.6f}")
# Print first few weights to avoid long output
print(f"First 3 weights: {max_sharpe_weights[:3]}")
Maximum Sharpe ratio: 2.946979
First 3 weights: [0.         0.         0.08509841]

For visualization, you can plot the efficient frontier:

# Plot the efficient frontier
fig = frontier.plot(volatility=True)
fig.show()
</code></pre>
<h2>📚 Literature and Implementations</h2>
<p>The package includes implementations based on several key papers:</p>
<h3>📝 Niedermayer and Niedermayer</h3>
<p>They suggested a method to avoid the expensive inversion
of the covariance matrix in <a href="https://www.researchgate.net/publication/226987510_Applying_Markowitz%27s_Critical_Line_Algorithm">Applying Markowitz's critical line algorithm</a>.
Our testing shows that in Python, this approach is not significantly
faster than explicit matrix inversion using LAPACK via <code>numpy.linalg.inv</code>.</p>
<h3>📝 Bailey and Lopez de Prado</h3>
<p>We initially started with their code published
in <a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2197616">An Open-Source Implementation of the Critical-Line Algorithm for Portfolio Optimization</a>.
We've made several improvements:</p>
<ul>
<li>Using boolean numpy arrays to indicate whether a weight is free or blocked</li>
<li>Rewriting the computation of the first turning point</li>
<li>Isolating the computation of λ and weight updates to make them testable</li>
<li>Using modern and immutable dataclasses throughout</li>
</ul>
<p>Our updated implementation is included in the tests but not part of cvxcla package.
We use it to verify our results and include it for educational purposes.</p>
<h3>📝 Markowitz et al</h3>
<p>In
<a href="https://www.hudsonbaycapital.com/documents/FG/hudsonbay/research/599440_paper.pdf">Avoiding the Downside: A Practical Review of the Critical Line Algorithm for Mean-Semivariance Portfolio Optimization</a>,
Markowitz and researchers from Hudson Bay Capital Management and Constantia Capital
present a step-by-step tutorial.</p>
<p>We address a problem they overlooked: after finding the first starting point,
all variables might be blocked. We enforce that one variable
labeled as free (even if it sits on a boundary) to avoid a singular matrix.</p>
<p>Rather than using their sparse matrix construction, we bisect the
weights into free and blocked parts and use a linear solver for the free part only.</p>
<h2>🧪 Testing</h2>
<p>Run the test suite with:</p>
<pre lang="bash"><code>make test

🧹 Code Quality

Format and lint the code with:

make fmt

📖 Documentation

👥 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Run the tests to make sure everything works (make test)
  4. Format your code (make fmt)
  5. Commit your changes (git commit -m 'Add some amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

📄 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🔍 Related Projects

  • PyCLA by Philipp Schiele - A previous implementation of the Critical Line Algorithm in Python.

  • CLA by Martin Dengler - The original implementation by David Bailey and Marcos Lopez de Prado.

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

cvxcla-1.5.1.tar.gz (140.4 kB view details)

Uploaded Source

Built Distribution

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

cvxcla-1.5.1-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

Details for the file cvxcla-1.5.1.tar.gz.

File metadata

  • Download URL: cvxcla-1.5.1.tar.gz
  • Upload date:
  • Size: 140.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cvxcla-1.5.1.tar.gz
Algorithm Hash digest
SHA256 90130f206c0fda81233fa169ae02034ee5d16ed9f5120e6fb1cbd640b0a943ba
MD5 fe9c6d07fcd2b0e95a4eca62a328a7af
BLAKE2b-256 85169ba5aa6fdda838b5e4946ab436f9e3a6993e196c6ebbf280db75ef12105e

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvxcla-1.5.1.tar.gz:

Publisher: release.yml on cvxgrp/cvxcla

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

File details

Details for the file cvxcla-1.5.1-py3-none-any.whl.

File metadata

  • Download URL: cvxcla-1.5.1-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cvxcla-1.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 852d9dc65bf9eba48f452a6ceaf69ded66eb1ae5dbfa153b2853bd2dc626ec86
MD5 4c6476cc680e8d16043120782f393e34
BLAKE2b-256 5809fd6dce437ac781e83a4778636e27cd416b259c3752c58a2016fc9064a917

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvxcla-1.5.1-py3-none-any.whl:

Publisher: release.yml on cvxgrp/cvxcla

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