{"id":26123502,"url":"https://github.com/cvxgrp/cvxcla","last_synced_at":"2026-03-15T08:58:53.989Z","repository":{"id":183986513,"uuid":"660398743","full_name":"cvxgrp/cvxcla","owner":"cvxgrp","description":"critical line algorithm for efficient frontier","archived":false,"fork":false,"pushed_at":"2025-11-18T09:41:50.000Z","size":5960,"stargazers_count":18,"open_issues_count":11,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-18T11:24:38.096Z","etag":null,"topics":["critical-line-algorithm","efficient-frontier","markowitz"],"latest_commit_sha":null,"homepage":"http://www.cvxgrp.org/cvxcla","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cvxgrp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-29T23:32:12.000Z","updated_at":"2025-11-18T09:41:15.000Z","dependencies_parsed_at":"2024-01-01T14:37:16.395Z","dependency_job_id":"c762008d-642b-4d3c-8121-6c44bfc9d415","html_url":"https://github.com/cvxgrp/cvxcla","commit_stats":null,"previous_names":["cvxgrp/cvxcla"],"tags_count":25,"template":false,"template_full_name":"cvxgrp/simulator","purl":"pkg:github/cvxgrp/cvxcla","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cvxgrp%2Fcvxcla","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cvxgrp%2Fcvxcla/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cvxgrp%2Fcvxcla/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cvxgrp%2Fcvxcla/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cvxgrp","download_url":"https://codeload.github.com/cvxgrp/cvxcla/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cvxgrp%2Fcvxcla/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285920997,"owners_count":27254100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-23T02:00:06.149Z","response_time":135,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["critical-line-algorithm","efficient-frontier","markowitz"],"created_at":"2025-03-10T15:53:28.278Z","updated_at":"2026-03-15T08:58:53.968Z","avatar_url":"https://github.com/cvxgrp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 📈 [cvxcla](https://www.cvxgrp.org/cvxcla) - Critical Line Algorithm for Portfolio Optimization\n\n[![PyPI version](https://badge.fury.io/py/cvxcla.svg)](https://badge.fury.io/py/cvxcla)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Downloads](https://static.pepy.tech/personalized-badge/cvxcla?period=month\u0026units=international_system\u0026left_color=black\u0026right_color=orange\u0026left_text=PyPI%20downloads%20per%20month)](https://pepy.tech/project/cvxcla)\n[![Coverage](https://img.shields.io/endpoint?url=https://www.cvxgrp.org/cvxcla/tests/coverage-badge.json)](https://www.cvxgrp.org/cvxcla/tests/html-coverage/index.html)\n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/cvxgrp/cvxcla)\n\n---\n\n**Quick Links:**\n[📖 Documentation](https://www.cvxgrp.org/cvxcla) •\n[🐛 Report Bug](https://github.com/cvxgrp/cvxcla/issues) •\n[💡 Request Feature](https://github.com/cvxgrp/cvxcla/issues) •\n[💬 Discussions](https://github.com/cvxgrp/cvxcla/discussions)\n\n---\n\n\u003c/div\u003e\n\n## 📋 Overview\n\n`cvxcla` is a Python package that implements the Critical Line Algorithm (CLA)\nfor portfolio optimization.\nThe CLA efficiently computes the entire efficient frontier for portfolio optimization\nproblems with linear constraints and bounds on the weights.\n\nThe Critical Line Algorithm was introduced by Harry Markowitz\nin [The Optimization of Quadratic Functions Subject to Linear Constraints](https://www.rand.org/pubs/research_memoranda/RM1438.html)\nand further described in his book [Portfolio Selection](https://www.wiley.com/en-us/Portfolio+Selection%3A+Efficient+Diversification+of+Investments%2C+2nd+Edition-p-9781557861085).\n\nThe algorithm is based on the observation that the efficient frontier\nis a piecewise linear function when expected return is plotted against\nexpected variance. The CLA computes the turning points (corners)\nof the efficient frontier, allowing for efficient representation of the entire frontier.\n\nI gave the plenary talk at [EQD's Singapore conference](https://tschm.github.io/eqd_markowitz/PresentationEQDweb.pdf).\n\n## 🧮 Why the Algorithm Works\n\nThe Markowitz problem is a quadratic program parametrized by a return target λ:\n\n```\nmin  wᵀΣw - λ · μᵀw\ns.t. Aw = b,  lb ≤ w ≤ ub\n```\n\nAs λ sweeps from ∞ (maximize return) down to 0 (minimize variance), the solution\ntraces the entire efficient frontier. The key insight is that **between consecutive\nevents, the optimal weights are a linear function of λ**:\n\n```\nw(λ) = α + λ · β\n```\n\nThis holds because the KKT optimality conditions are linear in λ whenever the active\nset — which assets sit at their bounds — is fixed. The algorithm exploits this in\nthree steps:\n\n1. **Start** at λ = ∞, where the portfolio concentrates on the highest-return asset\n   within bounds\n   ([`init_algo`](https://github.com/cvxgrp/cvxcla/blob/main/src/cvxcla/first.py),\n   called from [`_first_turning_point`](https://github.com/cvxgrp/cvxcla/blob/main/src/cvxcla/cla.py#L223)).\n\n2. **Solve** the KKT system for the current active set to find α and β\n   ([`_solve`](https://github.com/cvxgrp/cvxcla/blob/main/src/cvxcla/cla.py#L189)),\n   then decrease λ until one of two events occurs\n   ([main loop](https://github.com/cvxgrp/cvxcla/blob/main/src/cvxcla/cla.py#L122)):\n   - a **free** asset hits its bound (leaves the free set), or\n   - a **blocked** asset's KKT multiplier changes sign (enters the free set).\n\n3. **Update** the active set (exactly one asset changes status) and repeat until λ ≤ 0.\n\nBecause only one asset changes per step and each step requires only a single linear\nsolve, the algorithm traces the full frontier cheaply and exactly — no approximation\nneeded.\n\n## ✨ Features\n\n- Efficient computation of the entire efficient frontier\n- Support for linear constraints and bounds on portfolio weights\n- Multiple implementations based on different approaches from the literature\n- Visualization of the efficient frontier using Plotly\n- Computation of the maximum Sharpe ratio portfolio\n- Fully tested and documented codebase\n\n## 🚀 Installation\n\n### Using pip\n\n```bash\npip install cvxcla\n```\n\nTo include plotting support (Plotly and Kaleido):\n\n```bash\npip install cvxcla[plot]\n```\n\n### Development Setup\n\nTo set up a development environment:\n\n1. Clone the repository:\n\n    ```bash\n    git clone https://github.com/cvxgrp/cvxcla.git\n    cd cvxcla\n    ```\n\n2. Create a virtual environment and install dependencies:\n\n    ```bash\n    make install\n    ```\n\nThis will:\n\n- Install the uv package manager\n- Create a Python 3.12 virtual environment\n- Install all dependencies from pyproject.toml\n\n## 🔧 Usage\n\nHere's a simple example of how to use `cvxcla` to compute the efficient frontier:\n\n```python\nimport numpy as np\n# Set a seed for reproducibility\nnp.random.seed(42)\nfrom cvxcla import CLA\n\n# Define your portfolio problem\nn = 10  # Number of assets\nmean = np.random.randn(n)  # Expected returns\ncov = np.random.randn(n, n)\ncovariance = cov @ cov.T  # Covariance matrix\nlower_bounds = np.zeros(n)  # No short selling\nupper_bounds = np.ones(n)  # No leverage\n\n# Create a CLA instance\ncla = CLA(\n    mean = mean,\n    covariance = covariance,\n    lower_bounds = lower_bounds,\n    upper_bounds = upper_bounds,\n    a = np.ones((1, n)),  # Fully invested constraint\n    b = np.ones(1)\n)\n\n# Access the efficient frontier\nfrontier = cla.frontier\n\n# Get the maximum Sharpe ratio portfolio\nmax_sharpe_ratio, max_sharpe_weights = frontier.max_sharpe\nprint(f\"Maximum Sharpe ratio: {max_sharpe_ratio:.6f}\")\n# Print first few weights to avoid long output\nprint(f\"First 3 weights: {max_sharpe_weights[:3]}\")\n\n```\n\n```result\nMaximum Sharpe ratio: 2.946979\nFirst 3 weights: [0.         0.         0.08509841]\n```\n\nFor visualization, you can plot the efficient frontier:\n\n```python\n# Plot the efficient frontier\nfig = frontier.plot(volatility=True)\nfig.show()\n```\n\n\n## 📚 Literature and Implementations\n\nThe package includes implementations based on several key papers:\n\n### 📝 Niedermayer and Niedermayer\n\nThey suggested a method to avoid the expensive inversion\nof the covariance matrix in [Applying Markowitz's critical line algorithm](https://www.researchgate.net/publication/226987510_Applying_Markowitz%27s_Critical_Line_Algorithm).\nOur testing shows that in Python, this approach is not significantly\nfaster than explicit matrix inversion using LAPACK via `numpy.linalg.inv`.\n\n### 📝 Bailey and Lopez de Prado\n\nWe initially started with their code published\nin [An Open-Source Implementation of the Critical-Line Algorithm for Portfolio Optimization](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2197616).\nWe've made several improvements:\n\n- Using boolean numpy arrays to indicate whether a weight is free or blocked\n- Rewriting the computation of the first turning point\n- Isolating the computation of λ and weight updates to make them testable\n- Using modern and immutable dataclasses throughout\n\nOur updated implementation is included in the tests but not part of cvxcla package.\nWe use it to verify our results and include it for educational purposes.\n\n### 📝 Markowitz et al\n\nIn\n[Avoiding the Downside: A Practical Review of the Critical Line Algorithm for Mean-Semivariance Portfolio Optimization](https://www.hudsonbaycapital.com/documents/FG/hudsonbay/research/599440_paper.pdf),\nMarkowitz and researchers from Hudson Bay Capital Management and Constantia Capital\npresent a step-by-step tutorial.\n\nWe address a problem they overlooked: after finding the first starting point,\nall variables might be blocked. We enforce that one variable\nlabeled as free (even if it sits on a boundary) to avoid a singular matrix.\n\nRather than using their sparse matrix construction, we bisect the\nweights into free and blocked parts and use a linear solver for the free part only.\n\n## 🧪 Testing\n\nRun the test suite with:\n\n```bash\nmake test\n```\n\n## 🧹 Code Quality\n\nFormat and lint the code with:\n\n```bash\nmake fmt\n```\n\n## 📖 Documentation\n\n- [Online Documentation](https://www.cvxgrp.org/cvxcla/book)\n- [API Reference](https://www.cvxgrp.org/cvxcla/pdoc/)\n\n## 👥 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Run the tests to make sure everything works (`make test`)\n4. Format your code (`make fmt`)\n5. Commit your changes (`git commit -m 'Add some amazing feature'`)\n6. Push to the branch (`git push origin feature/amazing-feature`)\n7. Open a Pull Request\n\n## 📄 License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE)\nfile for details.\n\n## 🔍 Related Projects\n\n- [PyCLA](https://github.com/phschiele/PyCLA) by Philipp Schiele - A\nprevious implementation of the Critical Line Algorithm in Python.\n\n- [CLA](https://github.com/mdengler/cla) by Martin Dengler - The\noriginal implementation by David Bailey and Marcos Lopez de Prado.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcvxgrp%2Fcvxcla","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcvxgrp%2Fcvxcla","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcvxgrp%2Fcvxcla/lists"}