diff --git a/README.md b/README.md index 1391cb3f..0d305449 100755 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ If you use Riskfolio-Lib for published work, please use the following BibTeX ent ``` @misc{riskfolio, author = {Dany Cajas}, - title = {Riskfolio-Lib (6.2.2)}, + title = {Riskfolio-Lib (6.2.3)}, year = {2024}, url = {https://github.com/dcajasn/Riskfolio-Lib}, } diff --git a/docs/requirements.txt b/docs/requirements.txt index aca8b346..d810c649 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,10 +1,13 @@ -sphinx>=7.2.6 +sphinx>=7.4.6 numpydoc sphinxcontrib-napoleon==0.7 sphinx_rtd_theme==2.0.0 -sphinxcontrib-bibtex==2.6.1 -sphinxemoji==0.1.8 -sphinx-sitemap==2.5.1 +sphinxcontrib-bibtex==2.6.2 +sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 +sphinxemoji==0.3.1 +sphinx-sitemap==2.6.0 +backports.tarfile==1.2.0 RinohType numpy scipy diff --git a/docs/source/biblio.bib b/docs/source/biblio.bib index adf42768..b3628c51 100755 --- a/docs/source/biblio.bib +++ b/docs/source/biblio.bib @@ -575,7 +575,6 @@ @article{Ahmadi2017 author = {Ahmadi Javid, Amir and Fallah, Malihe}, year = {2017}, month = {08}, -pages = {}, title = {Portfolio optimization with entropic value-at-risk}, journal = {European Journal of Operational Research}, doi = {10.1016/j.ejor.2019.02.007} @@ -585,7 +584,6 @@ @article{Ahmadi2012 author = {Ahmadi Javid, Amir}, year = {2012}, month = {12}, -pages = {}, title = {Entropic Value-at-Risk: A new coherent risk measure}, volume = {155}, journal = {Journal of Optimization Theory and Applications}, @@ -709,7 +707,7 @@ @article{twogap @article{Szekely, author = {Gábor J. Székely and Maria L. Rizzo and Nail K. Bakirov}, -title = {{Measuring and testing dependence by correlation of distances}}, +title = {Measuring and testing dependence by correlation of distances}, volume = {35}, journal = {The Annals of Statistics}, number = {6}, @@ -753,14 +751,21 @@ @article{Song } @article{Massara, - title={Network Filtering for Big Data: Triangulated Maximally Filtered Graph}, - author={Guido Previde Massara and T. D. Matteo and T. Aste}, - journal={J. Complex Networks}, - year={2017}, - volume={5}, - pages={161-178} + author = {Massara, Guido Previde and Di Matteo, T. and Aste, Tomaso}, + title = "{Network Filtering for Big Data: Triangulated Maximally Filtered Graph}", + journal = {Journal of Complex Networks}, + volume = {5}, + number = {2}, + pages = {161-178}, + year = {2016}, + month = {06}, + issn = {2051-1310}, + doi = {10.1093/comnet/cnw015}, + url = {https://doi.org/10.1093/comnet/cnw015}, + eprint = {https://academic.oup.com/comnet/article-pdf/5/2/161/13794756/cnw015.pdf}, } + @article{Song2, title = {Nested hierarchies in planar graphs}, journal = {Discrete Applied Mathematics}, @@ -786,7 +791,6 @@ @TechReport{Pfitzinger number={14/2019}, abstract={Hierarchical Risk Parity (HRP) is a risk-based portfolio optimisation algorithm, which has been shown to generate diversified portfolios with robust out-of-sample properties without the need for a positive-definite return covariance matrix (Lopez de Prado 2016). The algorithm applies machine learning techniques to identify the underlying hierarchical correlation structure of the portfolio, allowing clusters of similar assets to compete for capital. The resulting allocation is both well-diversified over risk sources and intuitively appealing. This paper proposes a method of fully exploiting the information created by the clustering process, achieving enhanced out-of-sample risk and return characteristics. In addition, a practical approach to calculating HRP weights under box and group constraints is introduced. A comprehensive set of portfolio simulations over 6 equity universes demonstrates the appeal of the algorithm for portfolios consisting of 20 - 200 assets. HRP delivers highly diversified allocations with low volatility, low portfolio turnover and competitive performance metrics.}, keywords={Risk Parity; Diversification; Portfolio Optimisation; Clustering}, - doi={}, } @@ -814,8 +818,6 @@ @TechReport{RichardRoncalli url={https://ideas.repec.org/p/arx/papers/1902.05710.html}, number={1902.05710}, abstract={This article develops the theory of risk budgeting portfolios, when we would like to impose weight constraints. It appears that the mathematical problem is more complex than the traditional risk budgeting problem. The formulation of the optimization program is particularly critical in order to determine the right risk budgeting portfolio. We also show that numerical solutions can be found using methods that are used in large-scale machine learning problems. Indeed, we develop an algorithm that mixes the method of cyclical coordinate descent (CCD), alternating direction method of multipliers (ADMM), proximal operators and Dykstra's algorithm. This theoretical body is then applied to some investment problems. In particular, we show how to dynamically control the turnover of a risk parity portfolio and how to build smart beta portfolios based on the ERC approach by improving the liquidity of the portfolio or reducing the small cap bias. Finally, we highlight the importance of the homogeneity property of risk measures and discuss the related scaling puzzle.}, - keywords={}, - doi={}, } @article{Prado2, @@ -839,7 +841,8 @@ @article{jLogo publisher={American Physical Society (APS)}, author={Barfuss, Wolfram and Massara, Guido Previde and Di Matteo, T. and Aste, Tomaso}, year={2016}, - month={Dec} } + month={12} + } @book{MLforAM, place={Cambridge}, @@ -849,7 +852,8 @@ @book{MLforAM publisher={Cambridge University Press}, author={López de Prado, Marcos M.}, year={2020}, -collection={Elements in Quantitative Finance}} +collection={Elements in Quantitative Finance} +} @article{Cajas3, doi = {10.2139/ssrn.3988927}, @@ -889,7 +893,7 @@ @article{Gerber2021 publisher = {Elsevier {BV}}, author = {Sander Gerber and Harry Markowitz and Philip Ernst and Yinsen Miao and Babak Javid and Paul Sargen}, title = {The Gerber Statistic: A Robust Co-Movement Measure for Portfolio Optimization}, -journal = {{SSRN} Electronic Journal} + journal = {SSRN Electronic Journal}, } @article{Cajas4, @@ -924,7 +928,8 @@ @article{Cajas5 publisher = {Elsevier {BV}}, author = {Dany Cajas}, title = {Portfolio Optimization of Relativistic Value at Risk}, - journal = {{SSRN} Electronic Journal} + journal = {SSRN Electronic Journal}, + doi = {10.2139/ssrn.4378498}, } @article{Cajas6, @@ -933,14 +938,14 @@ @article{Cajas6 publisher = {Elsevier {BV}}, author = {Dany Cajas}, title = {Higher Order Moment Portfolio Optimization with L-Moments}, - journal = {{SSRN} Electronic Journal} + journal = {SSRN Electronic Journal}, + doi = {10.2139/ssrn.4393155}, } @article{Cajas7, author = {Dany Cajas}, year = {2023}, month = {6}, -pages = {}, title = {Approximation of Portfolio Kurtosis through Sum of Squared Quadratic Forms}, journal = {SSRN Electronic Journal}, doi = {10.2139/ssrn.4472793}, @@ -950,7 +955,6 @@ @article{Cajas8 author = {Dany Cajas}, year = {2023}, month = {8}, -pages = {}, title = {On the Spectral Decomposition of Portfolio Skewness and its Application to Portfolio Optimization}, journal = {SSRN Electronic Journal}, doi = {10.2139/ssrn.4540021}, @@ -960,7 +964,6 @@ @article{Cajas9 author = {Dany Cajas}, year = {2023}, month = {9}, -pages = {}, title = {Portfolio Optimization of Brownian Distance Variance}, journal = {SSRN Electronic Journal}, doi = {10.2139/ssrn.4540021}, @@ -970,22 +973,20 @@ @article{Cajas10 author = {Dany Cajas}, year = {2023}, month = {10}, -pages = {}, title = {A Graph Theory Approach to Portfolio Optimization}, journal = {SSRN Electronic Journal}, doi = {10.2139/ssrn.4602019}, } + @article{Cajas11, author = {Dany Cajas}, year = {2023}, month = {12}, -pages = {}, title = {A Graph Theory Approach to Portfolio Optimization Part II}, journal = {SSRN Electronic Journal}, doi = {10.2139/ssrn.4667426}, } - @book{Meucci2005, doi = {10.1007/978-3-540-27904-4}, url = {https://doi.org/10.1007/978-3-540-27904-4}, @@ -1058,8 +1059,8 @@ @Inbook{VanLoan1993 address={Dordrecht}, pages={293--314}, isbn={978-94-015-8196-7}, -doi={10.1007/978-94-015-8196-7_17}, -url={https://doi.org/10.1007/978-94-015-8196-7_17} +doi={10.1007/978-94-015-8196-7\_17}, +url={https://doi.org/10.1007/978-94-015-8196-7\_17} } @mastersthesis{Yang2019, diff --git a/docs/source/conf.py b/docs/source/conf.py index 03cd5d70..7b1be7ba 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,7 +25,7 @@ copyright = '2020-2024, Dany Cajas' author = 'Dany Cajas' -__version__ = "6.2.2" +__version__ = "6.2.3" # The short X.Y version version = '.'.join(__version__.split('.')[:2]) diff --git a/docs/source/index.rst b/docs/source/index.rst index 7d8513d4..8a32aa58 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -310,7 +310,7 @@ If you use Riskfolio-Lib for published work, please use the following BibTeX ent @misc{riskfolio, author = {Dany Cajas}, - title = {Riskfolio-Lib (6.2.2)}, + title = {Riskfolio-Lib (6.2.3)}, year = {2024}, url = {https://github.com/dcajasn/Riskfolio-Lib}, } diff --git a/riskfolio/__init__.py b/riskfolio/__init__.py index b24bd2ac..e395498e 100644 --- a/riskfolio/__init__.py +++ b/riskfolio/__init__.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/external/__init__.py b/riskfolio/external/__init__.py index 9c636ce9..36a13fd3 100644 --- a/riskfolio/external/__init__.py +++ b/riskfolio/external/__init__.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/external/cppfunctions.py b/riskfolio/external/cppfunctions.py index a63fcb31..0ced4cb6 100644 --- a/riskfolio/external/cppfunctions.py +++ b/riskfolio/external/cppfunctions.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/AuxFunctions.py b/riskfolio/src/AuxFunctions.py index 440864ac..b5d35087 100644 --- a/riskfolio/src/AuxFunctions.py +++ b/riskfolio/src/AuxFunctions.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. @@ -267,6 +268,10 @@ def block_vec_pq(A, p, q): """ if isinstance(A, pd.DataFrame): A_ = A.to_numpy() + elif isinstance(A, np.ndarray): + A_ = A.copy() + else: + raise ValueError("A must be an 2darray or DataFrame.") mp, nq = A_.shape if mp % p == 0 and nq % q == 0: @@ -406,9 +411,7 @@ def numBins(n_samples, corr=None): b = np.round(z / 6 + 2 / (3 * z) + 1 / 3) # bivariate case else: - b = np.round( - 2**-0.5 * (1 + (1 + 24 * n_samples / (1 - corr**2)) ** 0.5) ** 0.5 - ) + b = np.round(2**-0.5 * (1 + (1 + 24 * n_samples / (1 - corr**2)) ** 0.5) ** 0.5) bins = np.int32(b) diff --git a/riskfolio/src/ConstraintsFunctions.py b/riskfolio/src/ConstraintsFunctions.py index 681f0579..37e24b61 100644 --- a/riskfolio/src/ConstraintsFunctions.py +++ b/riskfolio/src/ConstraintsFunctions.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/DBHT.py b/riskfolio/src/DBHT.py index fcd0278d..ee002479 100644 --- a/riskfolio/src/DBHT.py +++ b/riskfolio/src/DBHT.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. @@ -812,14 +813,14 @@ def BubbleCluster8s(Rpm, Dpm, Hb, Mb, Mv, CliqList): ) # Assign discrete cluster membership of vertices in the converging bubbles. Udjv = Dpm @ (Mdjv @ np.diag(1 / np.sum(1 * (Mdjv != 0), axis=0))) - Udjv[ - Adjv == 0 - ] = np.inf # Compute the distance between a vertex and the converging bubbles. + Udjv[Adjv == 0] = ( + np.inf + ) # Compute the distance between a vertex and the converging bubbles. # mn = np.min(Udjv[np.sum(Mdjv.T, axis=0)==0,:].T) # Look for the closest converging bubble imn = np.argmin(Udjv[np.sum(Mdjv, axis=1) == 0, :], axis=1) - Tc[ - Tc == -1 - ] = imn # Assign discrete cluster membership according to the distances to the converging bubbles + Tc[Tc == -1] = ( + imn # Assign discrete cluster membership according to the distances to the converging bubbles + ) else: Tc = np.ones( N diff --git a/riskfolio/src/GerberStatistic.py b/riskfolio/src/GerberStatistic.py index 5a9028dd..730a360d 100644 --- a/riskfolio/src/GerberStatistic.py +++ b/riskfolio/src/GerberStatistic.py @@ -1,4 +1,5 @@ """""" # + """ This code is mainly based on Yinsen Miao's work available in: https://github.com/yinsenm/gerber/blob/af04c2ee5adf342393b028b85ab5546f31c0c8d3/src/gerber.py diff --git a/riskfolio/src/HCPortfolio.py b/riskfolio/src/HCPortfolio.py index 49552333..09c717fd 100644 --- a/riskfolio/src/HCPortfolio.py +++ b/riskfolio/src/HCPortfolio.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/OwaWeights.py b/riskfolio/src/OwaWeights.py index efea3545..910595ec 100644 --- a/riskfolio/src/OwaWeights.py +++ b/riskfolio/src/OwaWeights.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/ParamsEstimation.py b/riskfolio/src/ParamsEstimation.py index b5add527..3581b20f 100644 --- a/riskfolio/src/ParamsEstimation.py +++ b/riskfolio/src/ParamsEstimation.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/PlotFunctions.py b/riskfolio/src/PlotFunctions.py index 64db4012..7b88fbfc 100644 --- a/riskfolio/src/PlotFunctions.py +++ b/riskfolio/src/PlotFunctions.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. @@ -683,8 +684,8 @@ def plot_pie( else: fig = ax.get_figure() - labels = w.index.tolist() - sizes = w.iloc[:, 0].tolist() + labels = w_.index.tolist() + sizes = w_.iloc[:, 0].tolist() abs_sizes = [np.absolute(s) for s in sizes] sizes2 = pd.DataFrame([labels, abs_sizes, sizes]).T sizes2.columns = ["labels", "abs_values", "values"] diff --git a/riskfolio/src/Portfolio.py b/riskfolio/src/Portfolio.py index 6ec45d75..49a11f05 100644 --- a/riskfolio/src/Portfolio.py +++ b/riskfolio/src/Portfolio.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/Reports.py b/riskfolio/src/Reports.py index bac85baf..803fc3f3 100644 --- a/riskfolio/src/Reports.py +++ b/riskfolio/src/Reports.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/RiskFunctions.py b/riskfolio/src/RiskFunctions.py index 4cc8a5a0..c339159c 100644 --- a/riskfolio/src/RiskFunctions.py +++ b/riskfolio/src/RiskFunctions.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/riskfolio/src/__init__.py b/riskfolio/src/__init__.py index 1562d336..56328be7 100644 --- a/riskfolio/src/__init__.py +++ b/riskfolio/src/__init__.py @@ -1,4 +1,5 @@ """""" # + """ Copyright (c) 2020-2024, Dany Cajas All rights reserved. diff --git a/setup.py b/setup.py index 6115b3a7..7260088c 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ MAJOR = 6 MINOR = 2 -MICRO = 2 +MICRO = 3 VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO) def write_version_py(filename='riskfolio/version.py'):