robertmartin8 / PyPortfolioOpt

Financial portfolio optimisation in python, including classical efficient frontier, Black-Litterman, Hierarchical Risk Parity
https://pyportfolioopt.readthedocs.io/
MIT License
4.38k stars 942 forks source link

Semivariance optimization #202

Closed phschiele closed 3 years ago

phschiele commented 3 years ago

Describe the bug The current implementation of the semicovariance is to compute the standard covariance matrix after setting returns below the benchmark to zero for the individual assets. Applying standard mean-variance optimization to such a matrix does, in general, not correspond to the actual objective of obtaining an efficient portfolio in the mean-semivariance space. It can also be shown that a matrix S for which semivariance_portfolio = x'Sx does not exist in general. Intuitively, this can be seen as the current behavior sets returns to zero in time periods where the asset is below the benchmark, whereas the portfolio semivariance sets the portfolio returns to zero where the portfolio is below the benchmark.

A detailed description can be found in Computation of mean-semivariance efficient sets by the Critical Line Algorithm, Markowitz, Todd, Xu, and Yamane (1993).

One approach to deal with this is to use an implementation of the Critical Line Algorithm, which can handle semivariances as described in the mentioned paper (I am working on that and plan to add a PR here once ready). An easier, if computationally more expensive, approach is to use an augmented problem that splits up the portfolios' returns in above and below benchmark parts. This has the drawback that for n assets and T periods, the number of optimization variables increases from n to n + 2T. A CVXR implementation of this approach can be found here.

robertmartin8 commented 3 years ago

@phschiele Thanks for reaching out!

I've changed the label to "enhancement" from "bug" because currently PyPortfolioOpt uses the implementation of Estrada, so it is one approach (if not the best approach) to find a portfolio that maximises return for a given semivariance.

But I'd love to improve PyPortfolioOpt's current implementation and greatly look forward to a PR :)

robertmartin8 commented 3 years ago

Fixed in v1.3.0