robertmartin8 / PyPortfolioOpt

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

"ValueError: Weights is None" for Efficient Frontier Plot #477

Open PooratPython opened 1 year ago

PooratPython commented 1 year ago

I'm trying to generate an Efficient frontier plot but continue to get the same error - "ValueError: Weights is None".

The code I have used is as follows:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import copy
from pypfopt import risk_models
from pypfopt import expected_returns
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import plotting

stock_prices = pd.read_excel(r'C:\Users\fergaloconnor\Dropbox\UCC\FI6003\python\small_portfoliostocks.xlsx', 
                     parse_dates = ["date"], 
                     index_col = "date")
stock_prices = stock_prices.dropna()
stock_prices.describe()

mu = expected_returns.mean_historical_return(stock_prices)
Sigma = risk_models.sample_cov(stock_prices)
ef = EfficientFrontier(mu, Sigma)

fig, ax = plt.subplots()
ef_max_sharpe = copy.deepcopy(ef)
plotting.plot_efficient_frontier(ef, ax=ax, show_assets=True)

# Find the tangency portfolio
ef_max_sharpe.max_sharpe()
ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance()
ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="Max Sharpe")

# Generate random portfolios
n_samples = 100
w = np.random.dirichlet(np.ones(ef.n_assets), n_samples)
rets = w.dot(ef.expected_returns)
stds = np.sqrt(np.diag(w @ ef.cov_matrix @ w.T))
sharpes = rets / stds
ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")

# Output
ax.set_title("Efficient Frontier with random portfolios")
ax.legend()
plt.tight_layout()
plt.savefig("ef_scatter.png", dpi=200)
plt.show()

I used a few years of price for General Electric, JP Morgan Microsft and P&G daily - attached. I get the following error message and a blank graph:

ValueError                                Traceback (most recent call last)
<ipython-input-9-db7baad5d74e> in <module>
      1 fig, ax = plt.subplots()
      2 ef_max_sharpe = copy.deepcopy(ef)
----> 3 plotting.plot_efficient_frontier(ef, ax=ax, show_assets=True)
      4 
      5 # Find the tangency portfolio

C:\ProgramData\Anaconda3\lib\site-packages\pypfopt\plotting.py in plot_efficient_frontier(opt, ef_param, ef_param_range, points, ax, show_assets, show_tickers, **kwargs)
    261             ef_param_range = _ef_default_returns_range(opt, points)
    262 
--> 263         ax = _plot_ef(
    264             opt,
    265             ef_param,

C:\ProgramData\Anaconda3\lib\site-packages\pypfopt\plotting.py in _plot_ef(ef, ef_param, ef_param_range, ax, show_assets, show_tickers)
    194             )
    195 
--> 196         ret, sigma, _ = ef.portfolio_performance()
    197         mus.append(ret)
    198         sigmas.append(sigma)

C:\ProgramData\Anaconda3\lib\site-packages\pypfopt\efficient_frontier\efficient_frontier.py in portfolio_performance(self, verbose, risk_free_rate)
    443             risk_free_rate = self._risk_free_rate
    444 
--> 445         return base_optimizer.portfolio_performance(
    446             self.weights,
    447             self.expected_returns,

C:\ProgramData\Anaconda3\lib\site-packages\pypfopt\base_optimizer.py in portfolio_performance(weights, expected_returns, cov_matrix, verbose, risk_free_rate)
    537         new_weights = np.asarray(weights)
    538     else:
--> 539         raise ValueError("Weights is None")
    540 
    541     sigma = np.sqrt(objective_functions.portfolio_variance(new_weights, cov_matrix))

ValueError: Weights is None

Thanks in advance for your help!

Suhetu commented 1 year ago

I'm getting the same error, any luck figuring it out?

giordanocolombi commented 1 year ago

+1

Suhetu commented 1 year ago

So, here's what I observed in my case. When the annual returns are turning out to be negative or when the solver is unable to optimize the solution, that is what's causing this error.

giordanocolombi commented 1 year ago

@Suhetu look at #488