Skip to content

Commit f53d9bb

Browse files
Merge pull request #299 from robertmartin8/v1.4.1
v1.4.1
2 parents f2450d7 + 6e978ce commit f53d9bb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2084
-1774
lines changed

.dockerignore

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
#https://stackoverflow.com/questions/28097064/dockerignore-ignore-everything-except-a-file-and-the-dockerfile
1+
# Environments
2+
.env
3+
.venv
4+
env/
5+
venv/
6+
ENV/
7+
env.bak/
8+
venv.bak/
29

3-
# Ignore Everything
4-
**
5-
6-
!pypfopt
7-
!tests
8-
!setup.py
9-
!README.md
10-
!requirements.txt
11-
!binder
12-
!cookbook
13-
14-
**/__pycache__
15-
**/*.pyc
10+
*/__pycache__
11+
*/*.pyc

.github/ISSUE_TEMPLATE/bug.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ A clear and concise description of what the bug is.
1313
**Expected behavior**
1414
A clear and concise description of what you expected to happen.
1515

16-
**Screenshots**
17-
If applicable, add screenshots to help explain your problem.
16+
**Code sample**
17+
Add a minimal reproducible example (see [here](https://stackoverflow.com/help/minimal-reproducible-example)).
1818

1919
**Operating system, python version, PyPortfolioOpt version**
2020
e.g MacOS 10.146, python 3.7.3, PyPortfolioOpt 1.2.6

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ assignees: ''
1010
**Is your feature request related to a problem?**
1111
A clear and concise description of what the problem is.
1212

13-
**Describe the solution you'd like**
14-
A clear and concise description of what you want to happen.
13+
**Describe the feature you'd like**
14+
A clear description of the feature you want, or a link to the textbook/article describing the feature.
1515

1616
**Additional context**
1717
Add any other context or screenshots about the feature request here.

.github/ISSUE_TEMPLATE/help-needed.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ assignees: ''
1010
**What are you trying to do?**
1111
Clear description of the problem you are trying to solve with PyPortfolioOpt
1212

13+
**What have you tried?**
14+
1315
**What data are you using?**
1416
What asset class, how many assets, how many data points. Preferably provide a sample of the dataset as a csv attachment.

.github/ISSUE_TEMPLATE/installation-error.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ pip install pyportfolioopt
1616
**Error message**
1717

1818
```
19-
Copy paste the terminal message here
19+
Copy paste the terminal message inside the backticks.
2020
```

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@ DEV/
1111
.pytest_cache/
1212
.vscode/
1313

14+
# Environments
15+
.env
16+
.venv
17+
env/
18+
venv/
19+
ENV/
20+
env.bak/
21+
venv.bak/
22+
1423
pip-selfcheck.json
1524

25+
.coverage
26+
.coverage*
27+
1628
html-coverage
1729
html-report
1830

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Please refer to the roadmap for a list of areas that I think PyPortfolioOpt coul
44
from. In addition, the following is always welcome::
55

66
- Improve performance of existing code (but not at the cost of readability) – are there any nice numpy tricks I've missed?
7-
- Add new optimisation objective functions. For example, if you think that the best performance metric has not been included, write it into a function (or suggest it in [Issues](https://github.com/robertmartin8/PyPortfolioOpt/issues) and I will have a go).
7+
- Add new optimization objective functions. For example, if you think that the best performance metric has not been included, write it into a function (or suggest it in [Issues](https://github.com/robertmartin8/PyPortfolioOpt/issues) and I will have a go).
88
- Help me write more tests! If you are someone learning about quant finance and/or unit testing in python, what better way to practice than to write some tests on an open-source project! Feel free to check for edge cases, or test performance on a dataset with more stocks.
99

1010
## Guidelines
@@ -37,7 +37,7 @@ If you have questions unrelated to the project, drop me an email – contact det
3737

3838
## Bugs/issues
3939

40-
If you find any bugs or the portfolio optimisation is not working as expected, feel free to [raise an issue](https://github.com/robertmartin8/PyPortfolioOpt/issues). I would ask that you provide the following information in the issue:
40+
If you find any bugs or the portfolio optimization is not working as expected, feel free to [raise an issue](https://github.com/robertmartin8/PyPortfolioOpt/issues). I would ask that you provide the following information in the issue:
4141

4242
- Descriptive title so that other users can see the existing issues
4343
- Operating system, python version, and python distribution (optional).

Dockerfile

Lines changed: 0 additions & 26 deletions
This file was deleted.

Makefile

Lines changed: 0 additions & 54 deletions
This file was deleted.

README.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<img src="https://img.shields.io/badge/python-v3-brightgreen.svg"
99
alt="python"></a> &nbsp;
1010
<a href="https://pypi.org/project/PyPortfolioOpt/">
11-
<img src="https://img.shields.io/badge/pypi-v1.4.0-brightgreen.svg"
11+
<img src="https://img.shields.io/badge/pypi-v1.4.1-brightgreen.svg"
1212
alt="pypi"></a> &nbsp;
1313
<a href="https://opensource.org/licenses/MIT">
1414
<img src="https://img.shields.io/badge/license-MIT-brightgreen.svg"
@@ -26,8 +26,8 @@
2626

2727
<!-- content -->
2828

29-
PyPortfolioOpt is a library that implements portfolio optimisation methods, including
30-
classical mean-variance optimisation techniques and Black-Litterman allocation, as well as more
29+
PyPortfolioOpt is a library that implements portfolio optimization methods, including
30+
classical mean-variance optimization techniques and Black-Litterman allocation, as well as more
3131
recent developments in the field like shrinkage and Hierarchical Risk Parity, along with
3232
some novel experimental features like exponentially-weighted covariance matrices.
3333

@@ -49,14 +49,14 @@ Head over to the [documentation on ReadTheDocs](https://pyportfolioopt.readthedo
4949
- [For development](#for-development)
5050
- [A quick example](#a-quick-example)
5151
- [What's new](#whats-new)
52-
- [An overview of classical portfolio optimisation methods](#an-overview-of-classical-portfolio-optimisation-methods)
52+
- [An overview of classical portfolio optimization methods](#an-overview-of-classical-portfolio-optimization-methods)
5353
- [Features](#features)
5454
- [Expected returns](#expected-returns)
5555
- [Risk models (covariance)](#risk-models-covariance)
5656
- [Objective functions](#objective-functions)
5757
- [Adding constraints or different objectives](#adding-constraints-or-different-objectives)
5858
- [Black-Litterman allocation](#black-litterman-allocation)
59-
- [Other optimisers](#other-optimisers)
59+
- [Other optimizers](#other-optimizers)
6060
- [Advantages over existing implementations](#advantages-over-existing-implementations)
6161
- [Project principles and design decisions](#project-principles-and-design-decisions)
6262
- [Testing](#testing)
@@ -124,7 +124,7 @@ df = pd.read_csv("tests/resources/stock_prices.csv", parse_dates=True, index_col
124124
mu = expected_returns.mean_historical_return(df)
125125
S = risk_models.sample_cov(df)
126126

127-
# Optimise for maximal Sharpe ratio
127+
# Optimize for maximal Sharpe ratio
128128
ef = EfficientFrontier(mu, S)
129129
raw_weights = ef.max_sharpe()
130130
cleaned_weights = ef.clean_weights()
@@ -206,23 +206,23 @@ As of v1.2.0:
206206
new plots. All other plotting functions (scattered in different classes) have been retained,
207207
but are now deprecated.
208208

209-
## An overview of classical portfolio optimisation methods
209+
## An overview of classical portfolio optimization methods
210210

211-
Harry Markowitz's 1952 paper is the undeniable classic, which turned portfolio optimisation from an art into a science. The key insight is that by combining assets with different expected returns and volatilities, one can decide on a mathematically optimal allocation which minimises the risk for a target return – the set of all such optimal portfolios is referred to as the **efficient frontier**.
211+
Harry Markowitz's 1952 paper is the undeniable classic, which turned portfolio optimization from an art into a science. The key insight is that by combining assets with different expected returns and volatilities, one can decide on a mathematically optimal allocation which minimises the risk for a target return – the set of all such optimal portfolios is referred to as the **efficient frontier**.
212212

213213
<center>
214214
<img src="https://github.com/robertmartin8/PyPortfolioOpt/blob/master/media/efficient_frontier_white.png" style="width:60%;"/>
215215
</center>
216216

217217
Although much development has been made in the subject, more than half a century later, Markowitz's core ideas are still fundamentally important and see daily use in many portfolio management firms.
218-
The main drawback of mean-variance optimisation is that the theoretical treatment requires knowledge of the expected returns and the future risk-characteristics (covariance) of the assets. Obviously, if we knew the expected returns of a stock life would be much easier, but the whole game is that stock returns are notoriously hard to forecast. As a substitute, we can derive estimates of the expected return and covariance based on historical data – though we do lose the theoretical guarantees provided by Markowitz, the closer our estimates are to the real values, the better our portfolio will be.
218+
The main drawback of mean-variance optimization is that the theoretical treatment requires knowledge of the expected returns and the future risk-characteristics (covariance) of the assets. Obviously, if we knew the expected returns of a stock life would be much easier, but the whole game is that stock returns are notoriously hard to forecast. As a substitute, we can derive estimates of the expected return and covariance based on historical data – though we do lose the theoretical guarantees provided by Markowitz, the closer our estimates are to the real values, the better our portfolio will be.
219219

220220
Thus this project provides four major sets of functionality (though of course they are intimately related)
221221

222222
- Estimates of expected returns
223223
- Estimates of risk (i.e covariance of asset returns)
224-
- Objective functions to be optimised
225-
- Optimisers.
224+
- Objective functions to be optimized
225+
- Optimizers.
226226

227227
A key design goal of PyPortfolioOpt is **modularity** – the user should be able to swap in their
228228
components while still making use of the framework that PyPortfolioOpt provides.
@@ -253,7 +253,7 @@ The covariance matrix encodes not just the volatility of an asset, but also how
253253
- an unbiased estimate of the covariance matrix
254254
- relatively easy to compute
255255
- the de facto standard for many years
256-
- however, it has a high estimation error, which is particularly dangerous in mean-variance optimisation because the optimiser is likely to give excess weight to these erroneous estimates.
256+
- however, it has a high estimation error, which is particularly dangerous in mean-variance optimization because the optimizer is likely to give excess weight to these erroneous estimates.
257257
- Semicovariance: a measure of risk that focuses on downside variation.
258258
- Exponential covariance: an improvement over sample covariance that gives more weight to recent data
259259
- Covariance shrinkage: techniques that involve combining the sample covariance matrix with a structured estimator, to reduce the effect of erroneous weights. PyPortfolioOpt provides wrappers around the efficient vectorised implementations provided by `sklearn.covariance`.
@@ -280,7 +280,7 @@ The covariance matrix encodes not just the volatility of an asset, but also how
280280

281281
### Adding constraints or different objectives
282282

283-
- Long/short: by default all of the mean-variance optimisation methods in PyPortfolioOpt are long-only, but they can be initialised to allow for short positions by changing the weight bounds:
283+
- Long/short: by default all of the mean-variance optimization methods in PyPortfolioOpt are long-only, but they can be initialised to allow for short positions by changing the weight bounds:
284284

285285
```python
286286
ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
@@ -299,7 +299,7 @@ ef.efficient_return(target_return=0.2, market_neutral=True)
299299
ef = EfficientFrontier(mu, S, weight_bounds=(0, 0.1))
300300
```
301301

302-
One issue with mean-variance optimisation is that it leads to many zero-weights. While these are
302+
One issue with mean-variance optimization is that it leads to many zero-weights. While these are
303303
"optimal" in-sample, there is a large body of research showing that this characteristic leads
304304
mean-variance portfolios to underperform out-of-sample. To that end, I have introduced an
305305
objective function that can reduce the number of negligible weights for any of the objective functions. Essentially, it adds a penalty (parameterised by `gamma`) on small weights, with a term that looks just like L2 regularisation in machine learning. It may be necessary to try several `gamma` values to achieve the desired number of non-negligible weights. For the test portfolio of 20 securities, `gamma ~ 1` is sufficient
@@ -328,14 +328,16 @@ ef = EfficientFrontier(rets, S)
328328
ef.max_sharpe()
329329
```
330330

331-
### Other optimisers
331+
### Other optimizers
332332

333-
The features above mostly pertain to solving efficient frontier optimisation problems via quadratic programming (though this is taken care of by `cvxpy`). However, we offer different optimisers as well:
333+
The features above mostly pertain to solving mean-variance optimization problems via quadratic programming (though this is taken care of by `cvxpy`). However, we offer different optimizers as well:
334334

335+
- Mean-semivariance optimization
336+
- Mean-CVaR optimization
335337
- Hierarchical Risk Parity, using clustering algorithms to choose uncorrelated assets
336338
- Markowitz's critical line algorithm (CLA)
337339

338-
Please refer to the [documentation](https://pyportfolioopt.readthedocs.io/en/latest/OtherOptimisers.html) for more.
340+
Please refer to the [documentation](https://pyportfolioopt.readthedocs.io/en/latest/OtherOptimizers.html) for more.
339341

340342
## Advantages over existing implementations
341343

@@ -350,10 +352,10 @@ Please refer to the [documentation](https://pyportfolioopt.readthedocs.io/en/lat
350352

351353
## Project principles and design decisions
352354

353-
- It should be easy to swap out individual components of the optimisation process
355+
- It should be easy to swap out individual components of the optimization process
354356
with the user's proprietary improvements.
355357
- Usability is everything: it is better to be self-explanatory than consistent.
356-
- There is no point in portfolio optimisation unless it can be practically
358+
- There is no point in portfolio optimization unless it can be practically
357359
applied to real asset prices.
358360
- Everything that has been implemented should be tested.
359361
- Inline documentation is good: dedicated (separate) documentation is better.

0 commit comments

Comments
 (0)