robertmartin8 / PyPortfolioOpt

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

OptimizationError: 'Solver status: infeasible' #427

Closed markm812 closed 2 years ago

markm812 commented 2 years ago

What are you trying to do? I was attempting to obtain asset allocation weights based on 7-day asset values. Beginning in 2018, and ending in 2021. It works properly until the day 2020-02-20 arrives. From what I observed, it fails when all assets give negative return? If so, are there any alterative ways for avoiding this error? When it iterates over the data set shown below, it throws the following error:

    mu = expected_returns.mean_historical_return(stockData)
    cov = risk_models.CovarianceShrinkage(stockData).ledoit_wolf()
    ef = EfficientFrontier(mu, cov)
    weights = ef.max_sharpe()  #<------- error occurs upon execution of this line

Error messages:

in EfficientFrontier.max_sharpe(self, risk_free_rate)
    281 # Transformed max_sharpe convex problem:
    282 self._constraints = [
    283     (self.expected_returns - risk_free_rate).T @ self._w == 1,
    284     cp.sum(self._w) == k,
    285     k >= 0,
    286 ] + new_constraints
--> 288 self._solve_cvxpy_opt_problem()
    289 # Inverse-transform
    290 self.weights = (self._w.value / k.value).round(16) + 0.0
in BaseConvexOptimizer._solve_cvxpy_opt_problem(self)
    297     raise exceptions.OptimizationError from e
    299 if self._opt.status not in {"optimal", "optimal_inaccurate"}:
--> 300     raise exceptions.OptimizationError(
    301         "Solver status: {}".format(self._opt.status)
    302     )
    303 self.weights = self._w.value.round(16) + 0.0  # +0.0 removes signed zero
    304 return self._make_output_weights()

OptimizationError: ('Please check your objectives/constraints or use a different solver.', 'Solver status: infeasible')

What data are you using?

Data of that iteration Price data: <html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">

Date | HQL | GHY | BHK | MKTX -- | -- | -- | -- | -- 2020-02-20 00:00:00 | 17.89 | 15.33 | 15.49 | 344.6 2020-02-21 00:00:00 | 17.86 | 15.22 | 15.53 | 340.09 2020-02-24 00:00:00 | 17.47 | 14.99 | 15.69 | 341.91 2020-02-25 00:00:00 | 16.96 | 14.76 | 15.38 | 331.2 2020-02-26 00:00:00 | 17.16 | 14.91 | 15.13 | 338.28 2020-02-27 00:00:00 | 16.2 | 14.49 | 15.13 | 333.34 2020-02-28 00:00:00 | 15.88 | 14.24 | 14.85 | 324.33

mu: Symbols mean return
HQL -0.993300
GHY -0.954851
BHK -0.830038
MKTX -0.921618
S (Covariance): x HQL GHY BHK MKTX
HQL 0.087411 0.025599 -0.005226 0.023054
GHY 0.025599 0.052907 -0.004045 0.015761
BHK -0.005226 -0.004045 0.052848 0.006925
MKTX 0.023054 0.015761 0.006925 0.074175

Full dataset representative_assets_data_4y.xlsx

robertmartin8 commented 2 years ago

Hi @markm812,

Really appreciate the detailed issue. Unfortunately, the convex formulation of the max sharpe problem requires there to be a portfolio whose return exceeds the risk free rate (see this link).

Screenshot 2022-03-23 at 14 15 01

Practically speaking, I would insert a try/except statement within your loop to catch any OptimizationError and do something sensible (e.g equal weight, or use previous weights, or do nothing).

Hope this helps!

markm812 commented 2 years ago

Got it, much appreciated for the fast reply.

szeyao commented 2 years ago

@markm812 Hi Mark, would u mind to share how u overcome this problem?