robertmartin8 / PyPortfolioOpt

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

.max_sharpe() not working. Returns are positive btw #437

Closed fernando2xV closed 2 years ago

fernando2xV commented 2 years ago

Describe the bug

OptimizationError                         Traceback (most recent call last)
Input In [29], in <module>
      5 cov_mat = risk_models.exp_cov(prices_df_port)
      7 ef = EfficientFrontier(avg_returns, cov_mat)
---> 10 ef.max_sharpe()

File ~\anaconda3\envs\comp0162\lib\site-packages\pypfopt\efficient_frontier\efficient_frontier.py:288, 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

File ~\anaconda3\envs\comp0162\lib\site-packages\pypfopt\base_optimizer.py:300, 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')

Code sample

prices_df_port = prices_df[1:]
prices_df_port.fillna(method='ffill', inplace = True)

avg_returns = expected_returns.mean_historical_return(prices_df_port, compounding = True)
cov_mat = risk_models.exp_cov(prices_df_port)
ef = EfficientFrontier(avg_returns, cov_mat)
ef.max_sharpe()
robertmartin8 commented 2 years ago

That code should work: typically errors like this are due to missing data etc.