From 654324f5efe0213f201cb8ec4a5c7f6ed91ec2ab Mon Sep 17 00:00:00 2001 From: robertmartin8 Date: Sat, 13 Feb 2021 15:26:48 +0800 Subject: [PATCH] misc touchups --- docs/BlackLitterman.rst | 9 +++--- docs/index.rst | 50 +++++++++++++++++-------------- pypfopt/base_optimizer.py | 2 +- pypfopt/cla.py | 3 +- pypfopt/hierarchical_portfolio.py | 2 +- pypfopt/objective_functions.py | 4 +-- 6 files changed, 36 insertions(+), 34 deletions(-) diff --git a/docs/BlackLitterman.rst b/docs/BlackLitterman.rst index 29ba2bf..bba80a8 100644 --- a/docs/BlackLitterman.rst +++ b/docs/BlackLitterman.rst @@ -5,7 +5,7 @@ Black-Litterman Allocation ########################## The Black-Litterman (BL) model [1]_ takes a Bayesian approach to asset allocation. -Specifically, it combines a **prior** estimate of returns (canonically, the market-implied +Specifically, it combines a **prior** estimate of returns (for example, the market-implied returns) with **views** on certain assets, to produce a **posterior** estimate of expected returns. The advantages of this are: @@ -52,11 +52,10 @@ I'd like to thank `Felipe Schneider `_ for contributions to the Black-Litterman implementation. A full example of its usage, including the acquistion of market cap data for free, please refer to the `cookbook recipe `_. -.. caution:: +.. tip:: - Our implementation of Black-Litterman makes frequent use of the fact that python 3.6+ dictionaries - remain ordered. It is still possible to use python 3.5 but you will have to construct the BL inputs - explicitly (``Q``, ``P``, ``omega``). + Thomas Kirschenmann has built a neat interactive `Black-Litterman tool `_ + on top of PyPortfolioOpt, which allows you to visualise BL outputs and compare optimisation objectives. Priors ====== diff --git a/docs/index.rst b/docs/index.rst index 3ad1e8a..45fd9fd 100755 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,14 +43,16 @@ in a risk-efficient way. Installation ============ -Installation on macOS or linux is as simple as:: +Prior to installing PyPortfolioOpt, you need to install C++. On macOS, this means that you need +to install XCode Command Line Tools (see `here `__). + +For Windows users, download Visual Studio `here `__, +with additional instructions `here `__. + +Installation can then be done via pip:: pip install PyPortfolioOpt -Windows users need to go through the additional step of downloading C++ (for ``cvxpy``). You can -download this `here `__, -with additional instructions `here `__. - For the sake of best practice, it is good to do this with a dependency manager. I suggest you set yourself up with `poetry `_, then within a new poetry project run: @@ -73,8 +75,7 @@ Thanks to Thomas Schmelzer, PyPortfolioOpt now supports Docker (requires .. note:: If any of these methods don't work, please `raise an issue - `_ on GitHub - + `_ with the 'packaging' label on GitHub @@ -82,14 +83,14 @@ For developers -------------- If you are planning on using PyPortfolioOpt as a starting template for significant -modifications, it probably makes sense to clone this repository and to just use the +modifications, it probably makes sense to clone the repository and to just use the source code .. code-block:: text git clone https://github.com/robertmartin8/PyPortfolioOpt -Alternatively, if you still want the convenience of ``from pypfopt import x``, +Alternatively, if you still want the convenience of a global ``from pypfopt import x``, you should try .. code-block:: text @@ -158,25 +159,13 @@ Contents Plotting .. toctree:: + :maxdepth: 1 :caption: Other information Roadmap Contributing About -Advantages over existing implementations -======================================== - -- Includes both classical methods (Markowitz 1952 and Black-Litterman), suggested best practices - (e.g covariance shrinkage), along with many recent developments and novel - features, like L2 regularisation, shrunk covariance, hierarchical risk parity. -- Native support for pandas dataframes: easily input your daily prices data. -- Extensive practical tests, which use real-life data. -- Easy to combine with your proprietary strategies and models. -- Robust to missing data, and price-series of different lengths (e.g FB data - only goes back to 2012 whereas AAPL data goes back to 1980). - - Project principles and design decisions ======================================= @@ -193,10 +182,24 @@ Project principles and design decisions `_. +Advantages over existing implementations +======================================== + +- Includes both classical methods (Markowitz 1952 and Black-Litterman), suggested best practices + (e.g covariance shrinkage), along with many recent developments and novel + features, like L2 regularisation, exponential covariance, hierarchical risk parity. +- Native support for pandas dataframes: easily input your daily prices data. +- Extensive practical tests, which use real-life data. +- Easy to combine with your proprietary strategies and models. +- Robust to missing data, and price-series of different lengths (e.g FB data + only goes back to 2012 whereas AAPL data goes back to 1980). + + Contributors ============= -This is a non-exhaustive unordered list of contributors: +This is a non-exhaustive unordered list of contributors. I am sincerely grateful for all +of your efforts! - Philipp Schiele - Carl Peasnell @@ -206,6 +209,7 @@ This is a non-exhaustive unordered list of contributors: - Aditya Bhutra - Thomas Schmelzer - Rich Caputo +- Nicolas Knudde Indices and tables diff --git a/pypfopt/base_optimizer.py b/pypfopt/base_optimizer.py index 513be2f..1d57a15 100644 --- a/pypfopt/base_optimizer.py +++ b/pypfopt/base_optimizer.py @@ -183,7 +183,7 @@ class BaseConvexOptimizer(BaseOptimizer): def _map_bounds_to_constraints(self, test_bounds): """ - Process input bounds into a form acceptable by cvxpy and add to the constraints list. + Convert input bounds into a form acceptable by cvxpy and add to the constraints list. :param test_bounds: minimum and maximum weight of each asset OR single min/max pair if all identical OR pair of arrays corresponding to lower/upper bounds. defaults to (0, 1). diff --git a/pypfopt/cla.py b/pypfopt/cla.py index 012c396..c207904 100644 --- a/pypfopt/cla.py +++ b/pypfopt/cla.py @@ -4,7 +4,6 @@ generates optimal portfolios using the Critical Line Algorithm as implemented by Marcos Lopez de Prado and David Bailey. """ -import math import numpy as np import pandas as pd from . import base_optimizer @@ -266,7 +265,7 @@ class CLA(base_optimizer.BaseOptimizer): sign = -1 if "args" in kargs: args = kargs["args"] - numIter = int(math.ceil(-2.078087 * math.log(tol / abs(b - a)))) + numIter = int(np.ceil(-2.078087 * np.log(tol / abs(b - a)))) r = 0.618033989 c = 1.0 - r # Initialize diff --git a/pypfopt/hierarchical_portfolio.py b/pypfopt/hierarchical_portfolio.py index 5070816..35ae33c 100644 --- a/pypfopt/hierarchical_portfolio.py +++ b/pypfopt/hierarchical_portfolio.py @@ -32,7 +32,7 @@ class HRPOpt(base_optimizer.BaseOptimizer): - ``n_assets`` - int - ``tickers`` - str list - - ``returns`` - pd.Series + - ``returns`` - pd.DataFrame - Output: diff --git a/pypfopt/objective_functions.py b/pypfopt/objective_functions.py index 292c2f6..07c33ca 100644 --- a/pypfopt/objective_functions.py +++ b/pypfopt/objective_functions.py @@ -183,7 +183,7 @@ def transaction_cost(w, w_prev, k=0.001): def ex_ante_tracking_error(w, cov_matrix, benchmark_weights): """ Calculate the (square of) the ex-ante Tracking Error, i.e - :math:`\\(w - w_b)^T \\Sigma (w-w_b)`. + :math:`(w - w_b)^T \\Sigma (w-w_b)`. :param w: asset weights in the portfolio :type w: np.ndarray OR cp.Variable @@ -201,7 +201,7 @@ def ex_ante_tracking_error(w, cov_matrix, benchmark_weights): def ex_post_tracking_error(w, historic_returns, benchmark_returns): """ - Calculate the (square of) the ex-post Tracking Error, i.e :math:`\\Var(r - r_b)`. + Calculate the (square of) the ex-post Tracking Error, i.e :math:`Var(r - r_b)`. :param w: asset weights in the portfolio :type w: np.ndarray OR cp.Variable