Package: cvxportfolio
Cvxportfolio is an object-oriented library for portfolio optimization
and back-testing. It implements models described in theaccompanying
paper.The documentation of the library is atwww.cvxportfolio.com.News:Since end of 2023 we’re running dailyexample strategiesusing the development version (master branch); each day we commit target
weights and initial holdings to the repository. All the code that runs them,
including the cron script, is in the repository.InstallationCvxportolio is written in Python and can be easily installed in any Python
environment by simple:pipinstall-UcvxportfolioYou can see how this works on ourInstallation and Hello
Worldyoutube video.
Anaconda installsare also supported.Cvxportfolio’s main dependencies areCvxpyfor
interfacing with numerical solvers andPandasfor interfacing with databases. We don’t require any specific version of our
dependencies and test against all recent ones (up to a few years ago).TestAfter installing you can run our unit test suite in you local environment bypython-mcvxportfolio.testsWe test against recent python versions (3.8, 3.9, 3.10, 3.11, 3.12) and recent versions
of the main dependencies (from pandas 1.4, cvxpy 1.1, …, up to the current
versions) on all major operating systems. You can see theautomated testing code.Simple exampleIn the following example market data is downloaded by a public source
(Yahoo finance) and the forecasts are computed iteratively, at each
point in the backtest, from past data.importcvxportfolioascvxgamma=3# risk aversion parameter (Chapter 4.2)kappa=0.05# covariance forecast error risk parameter (Chapter 4.3)objective=cvx.ReturnsForecast()-gamma*(cvx.FullCovariance()+kappa*cvx.RiskForecastError())-cvx.StocksTransactionCost()constraints=[cvx.LeverageLimit(3)]policy=cvx.MultiPeriodOptimization(objective,constraints,planning_horizon=2)simulator=cvx.StockMarketSimulator(['AAPL','AMZN','TSLA','GM','CVX','NKE'])result=simulator.backtest(policy,start_time='2020-01-01')# print back-test result statisticsprint(result)# plot back-test resultsresult.plot()At each point in the back-test, the policy object only operates onpast data, and thus the result you get is a realistic simulation of
what the strategy would have performed in the market. Returns are
forecasted as the historical mean returns and covariances as historical
covariances (both ignoringnp.nan’s). The simulator by default
includes holding and transaction costs, using the models described in
the paper, and default parameters that are typical for the US stock
market.Other examplesMany examplesare shown in the documentation website, along with
their output and comments.Even more example scriptsare available in the code repository.The original examples from the paperare visible in a dedicated branch,
and are being translated to run with the stable versions (1.0.0and above) of the
library. The translations are visible atthis documentation page.We show in the example onuser-provided
forecastershow the user can define custom classes to forecast the expected returns
and covariances. These provide callbacks that are executed at each point
in time during the back-test. The system enforces causality and safety
against numerical errors. We recommend to always include the default
forecasters that we provide in any analysis you may do, since they are
very robust and well-tested.We show in the examples onDOW30
componentsandwide assets-classes
ETFshow a simple sweep over hyper-parameters, taking advantage of our
sophisticated parallel backtest machinery, quickly provides results on
the best strategy to apply to any given selection of assets.Similar projectsThere are many open-source projects for portfolio optimization and back-testing.
Some notable ones in the Python ecosystem areZipline,
which implements a call-back model for back-testing very similar to the one
we provide,Riskfolio-Libwhich implements (many!) portfolio optimization models and also follows a modular
approach like ours,VectorBT, a back-testing library
well-suited for high frequency applications,PyPortfolioOpt,
a simple yet powerful library for portfolio optimization that uses well-known models,YFinance, which is not a portfolio
optimization library (it only provides a data interface to Yahoo Finance), but
used to be one of our dependencies, and alsoCVXPYby
itself, which is used by some of the above and has an extensiveset of examplesdevoted to portfolio optimization (indeed, Cvxportfolio was born out of those).ContributionsWe welcome contributors and you don’t need to sign a CLA. If you don’t have
a Github account you may also send agit patch via emailto theproject maintainer.Bug fixes, improvements in the documentations and examples,
new constraints, new cost objects, …, are good contributions and can be done
even if you’re not familiar with the low-level details on the library.
For more advanced contributions we recommend reading theTODOs and roadmapfile.DevelopmentTo set up a development environment locally you should clone the
repository (or,fork on
Githuband then clone your fork)gitclonehttps://github.com/cvxgrp/cvxportfolio.gitcdcvxportfolioThen, you should have a look at ourMakefileand possibly change thePYTHONvariable to match your system’s
python interpreter. Once you have done that,makeenvmaketestThis will replicate ourdevelopment
environmentand run our
test suite.You activate the shell environment with one of scripts inenv/bin(orenv\Scriptson Windows), for example if you use bash on POSIXsourceenv/bin/activateand from the environment you can run any of the scripts in the examples
(the cvxportfolio package is installed ineditable
mode).
Or, if you don’t want to activate the environment, you can just run
scripts directly usingenv/bin/python(orenv\Scripts\pythonon
Windows) like we do in the Makefile.Additionally, to match our CI/CD pipeline, you may set the followinggit hooksecho"make lint">.git/hooks/pre-commitchmod+x.git/hooks/pre-commitecho"make test">.git/hooks/pre-pushchmod+x.git/hooks/pre-pushCode style and qualityCvxportfolio follows thePEP8specification for code style. This is enforced by thePylintautomated linter, with options
in thePyprojectconfiguration file.
Pylint is also used to enforce code quality standards, along with some of its
optional plugins.
Docstrings are written in theSphinx style, are also checked by
Pylint, and are used to generate the documentation.Versions and releasesCvxportfolio follows thesemantic versioningspecification. No breaking change in its public API will be introduced
until the next major version (2.0.0), which won’t happen for some time.
New features in the public API are introduced with minor versions
(1.1.0,1.2.0, …), and only bug fixes at each revision.The history of our releases (source distributions and wheels) is visible on ourPyPI page.Releases are also tagged in our git repository and include a short summary
of changes intheir commit messages.We maintain adocument listing the planned changes and target releases.CitingIf you use Cvxportfolio in work that leads to publication, you can cite the following:@misc{busseti2017cvx,author="Busseti, Enzo and Diamond, Steven and Boyd, Stephen",title="Cvxportfolio",month="January",year="2017",note="Portfolio Optimization and Back--{T}esting",howpublished={\url{https://github.com/cvxgrp/cvxportfolio}},}@article{boyd2017multi,author="Boyd, Stephen and Busseti, Enzo and Diamond, Steven and Kahn, Ron and Nystrup, Peter and Speth, Jan",journal="Foundations and Trends in Optimization",title="Multi--{P}eriod Trading via Convex Optimization",month="August",year="2017",number="1",pages="1--76",volume="3",url={\url{https://stanford.edu/~boyd/papers/pdf/cvx_portfolio.pdf}},}The latter is also the first chapter of this PhD thesis:@phdthesis{busseti2018portfolio,author="Busseti, Enzo",title="Portfolio Management and Optimal Execution via Convex Optimization",school="Stanford University",address="Stanford, California, USA",month="May",year="2018",url={\url{https://stacks.stanford.edu/file/druid:wm743bj5020/thesis-augmented.pdf}},}LicensingCvxportfolio is licensed under theApache 2.0permissive
open source license.