fmilthaler / FinQuant

A program for financial portfolio management, analysis and optimisation.
MIT License
1.38k stars 190 forks source link

ValueError when optimizing a portfolio with 3 indices #52

Closed noobmaster29 closed 4 years ago

noobmaster29 commented 4 years ago

I'm currently having an issue running the demo code when I try to run the mc_optimisation with 3 stocks in the portfolio. I've tried running with 2 stocks as well as portfolios with more than 3 stocks and everything seems to work fine. However, when I setup a portfolio with 3 stocks, I run into the following error.

ValueError: Shape of passed values is (2, 5000), indices imply (2, 3)

Code that produced the error:

from finquant.portfolio import build_portfolio

names = ['MSFT', 'AAPL', 'GOOG']

start_date = '2015-01-01' end_date = '2020-04-25' pf = build_portfolio(names=names, start_date=start_date, end_date=end_date, data_api="yfinance")

opt_w, opt_res = pf.mc_optimisation(num_trials=5000)

fmilthaler commented 4 years ago

This seems really odd to me. I will test this over the coming weekend.

However, are you sure there is data in each of the columns? Try to print out the data: print(pf.data). Does it show data in all three columns? If not, the data that was downloaded through yfinance is incomplete. This should then be caught by FinQuant and an appropriate error message should be given to the user.

Thinking about it, I thought that check should already be in FinQuant. I'll check this weekend. Sorry for the inconvenience.

nuvious commented 4 years ago

I'm getting the exact same issue. Reproduction steps below:

https://pastebin.com/cap5ZGaP

If you set the allocation on line 25 to:

# Define portfolio and allocation
stocks = {'MSFT': 25, 'TSLA': 95, 'AAPL': 100, 'GNSS': 0}

the error does not occur.

At first I thought it was on my end because I'm downloading yahoo finance docs, caching them, and then reshaping dataframes to match the yahoo finance query output shape, but ended up ruling that out.

My best guess is np.stack(res).T[0] is the root of the issue, but that's a rough guess as I'm relatively green when it comes to numpy.

nuvious commented 4 years ago

P.S. Here's a copy of the above repro in Jupyter Notebook format. Its prints out the data and shows it's in the proper shape for processing:

https://1drv.ms/u/s!Am1tgTvkI9ZOt5kYuQXQ6I0sJfEd2g?e=DnnM2u (Above link expires on the 15th so message me if you don't download it before then)

Additionally I threw a breakpoint in and inspected pf.data (specifically pf_api.data in my reproduction) at the exception point and it doesn't have any missing data. You can verify that by calling dropna on the dataframe in an inspector and can see it's not dropping any rows.

Hope this helps narrow down the issue and thanks for your time!

noobmaster29 commented 4 years ago

The data is loaded correctly. I've tried with multiple 3 tickers combinations with long trading history and none of them work. If I load the same stocks with more than 3 tickers, the code runs fine.

fmilthaler commented 4 years ago

thanks, will investigate this in the next two days.

noobmaster29 commented 4 years ago

Thank you for the fix. I just wanted to note that the pip upgrade does not reflect these changes. I have replaced the new files with the fix in my install but upgrading or reinstalling via pip did not work.