JerBouma / FinanceToolkit

Transparent and Efficient Financial Analysis
https://www.jeroenbouma.com/projects/financetoolkit
MIT License
2.81k stars 344 forks source link

[BUG] Reindexing only valid with uniquely valued Index objects #44

Closed sword134 closed 1 year ago

sword134 commented 1 year ago

Using the new v1.1.1 version I get the following error when passing a list of symbols of approximately 50 different tickers. The issue doesnt happen when I try other tickers, so I assume that it is because 1 ticker is causing a problem here:

companies = Toolkit(symbols, api_key="XXX")

df_total = companies.ratios.collect_all_ratios()

df_total.to_excel(dir_path + "\\df_total.xlsx")

Yields:

Traceback (most recent call last):
  File "c:\Desktop\Proj1\\data_fetch_fmp.py", line 73, in <module>
    df_total = companies.ratios.collect_all_ratios()
  File "C:\Users\Tomas\anaconda3\envs\Toolkit\lib\site-packages\financetoolkit\base\toolkit_controller.py", line 156, in ratios
    self.get_balance_sheet_statement()
  File "C:\Users\Tomas\anaconda3\envs\Toolkit\lib\site-packages\financetoolkit\base\toolkit_controller.py", line 542, in get_balance_sheet_statement
    ) = _get_financial_statements(
  File "C:\Users\Tomas\anaconda3\envs\Toolkit\lib\site-packages\financetoolkit\base\models\fundamentals_model.py", line 111, in get_financial_statements
    financial_statement_total = pd.concat(financial_statement_dict, axis=0)
  File "C:\Users\Tomas\anaconda3\envs\Toolkit\lib\site-packages\pandas\core\reshape\concat.py", line 385, in concat
    return op.get_result()
  File "C:\Users\Tomas\anaconda3\envs\Toolkit\lib\site-packages\pandas\core\reshape\concat.py", line 612, in get_result
    indexers[ax] = obj_labels.get_indexer(new_labels)
  File "C:\Users\Tomas\anaconda3\envs\Toolkit\lib\site-packages\pandas\core\indexes\base.py", line 3732, in get_indexer
    raise InvalidIndexError(self._requires_unique_msg)
pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects

Ticker list in question: ['AIR', 'AJRD', 'AVAV', 'AXON', 'BA', 'BWXT', 'CUB', 'HEI', 'HEI-A', 'HII', 'JOBY', 'LHX', 'LMT', 'MOG-A', 'MOG-B', 'MRCY', 'NOC', 'POWWP', 'RKLB', 'RTX', 'SPR', 'TDG', 'TXT', 'WWD', 'AAWW', 'CHRW', 'EXPD', 'FDX', 'FWRD', 'HUBG', 'JBHT', 'MIC', 'UPS', 'XPO', 'AAL', 'ALGT', 'ALK', 'DAL', 'JBLU', 'LUV', 'SAVE', 'SKYW', 'UAL', 'ULCC', 'ALSN', 'BWA', 'CTB', 'DAN', 'DORM', 'GNTX']

JerBouma commented 1 year ago

Seems to be multiple issues, in some cases the length of the financial statements (e.g. cash and balance) differ which is why "LHX" for example won't work.

PeriodIndex(['1986', '1987', '1988', '1989', '1990', '1991', '1992', '1993',
             '1994', '1995', '1996', '1997', '1998', '1999', '2000', '2001',
             '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009',
             '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017',
             '2018', '2019', '2021', '2021', '2021', '2021', '2022'],
            dtype='period[A-DEC]', name='date')

PeriodIndex(['1989', '1990', '1991', '1992', '1993', '1994', '1995', '1996',
             '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004',
             '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012',
             '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2021',
             '2021', '2021', '2021', '2022'],
            dtype='period[A-DEC]', name='date')

This also seems to be one of the reasons you get this error. For example ['AIR', 'AJRD', 'AVAV', 'AXON', 'CUB'] works fine but ['AIR', 'AJRD', 'AVAV', 'AXON', 'CUB', "LHX"] doesn't.

In other cases there is no historical data, like in the case of "CUB". However, this is not an issue unless its the only ticker. All bugs to fix, for sure, but if you could help me out and delve a bit deeper the issue is fixed sooner!

sword134 commented 1 year ago

I guess the easiest temporary fix is to remove these tickers as corrupted until a proper fix can be created. I will help for sure. But if you can push an exception fix to the repo then we can work from there so we have common ground to work on.

Additionally do you have discord or something similar, I've got a couple of ideas as how to solve some of these issues. But such brainstorming might work better in a chat format than a github issue

JerBouma commented 1 year ago

Yes I do, you can connect with me via my username "jerbouma".

sword134 commented 1 year ago

The issue still persists with the latest commit

EDIT: Only persists with the new filing date addition. I've made a new commit that fixes this issue for it as well.

In total i believe this issue to be completely fixed and can be closed

GITChr commented 1 year ago

Dear Both, I downloaded the package yesterday and it is shown as 1.1.2. I still get the error with a list of symbols. I am not enough into python internals to help out, I'm sorry. Just signaling that it seems the bug is still around. Is there a workaround? Does it depend on the function used? As a start, I would like to get the PE ratio and dividend yield. By the way, it seems to be an awesome project. Just starting with it.

Error traceback: Traceback (most recent call last):

File ~\anaconda3\envs\py311\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals)

File c:\users\ms\mon drive\aktien und anlage, finanzen, rente\software\findatabase\getntvaluations.py:57 ratios = companies.ratios

File ~\anaconda3\envs\py311\Lib\site-packages\financetoolkit\base\toolkit_controller.py:175 in ratios self.get_balance_sheet_statement()

File ~\anaconda3\envs\py311\Lib\site-packages\financetoolkit\base\toolkit_controller.py:570 in get_balance_sheet_statement ) = _get_financial_statements(

File ~\anaconda3\envs\py311\Lib\site-packages\financetoolkit\base\models\fundamentals_model.py:111 in get_financial_statements financial_statement_total = pd.concat(financial_statement_dict, axis=0)

File ~\anaconda3\envs\py311\Lib\site-packages\pandas\core\reshape\concat.py:385 in concat return op.get_result()

File ~\anaconda3\envs\py311\Lib\site-packages\pandas\core\reshape\concat.py:612 in get_result indexers[ax] = obj_labels.get_indexer(new_labels)

File ~\anaconda3\envs\py311\Lib\site-packages\pandas\core\indexes\base.py:3732 in get_indexer raise InvalidIndexError(self._requires_unique_msg)

InvalidIndexError: Reindexing only valid with uniquely valued Index objects

Code used including list of symbols, I erased my key:

import pandas as pd import numpy as np

from financetoolkit import Toolkit

API_KEY = "something"

Initialize the Toolkit with company tickers

They can be copied from the listing formula in copy sheet in NT8 export file

companies = Toolkit( ["AAP", "ADM", "ADP", "APA", "ARE", "BXP", "CE", "CF", "CHTR", "CINF", "CMCSA", "CME", "COP", "CTLT", "CVX", "DD", "DOW", "DVN", "EOG", "FANG", "FCX", "FFIV", "FITB", "GNRC", "HBAN", "HES", "HUM", "IEX", "ILMN", "IPGP", "JBHT", "JPM", "LIN", "LNC", "LYB", "MAR", "MET", "MKC", "MOS", "MPC", "MRO", "MTB", "OKE", "OXY", "PAYX", "PNC", "PNR", "POOL", "PRGO", "PRU", "PSX", "PXD", "RF", "STT", "TAP", "TSCO", "TSN", "VLO", "WAB", "WRK"], \ api_key=API_KEY, start_date="2000-01-01" )

Including Sector:

companies.get_profile()

ratios = companies.ratios

ratios.collect_valuation_ratios()

JerBouma commented 1 year ago

Dear Both, I downloaded the package yesterday and it is shown as 1.1.2. I still get the error with a list of symbols. I am not enough into python internals to help out, I'm sorry. Just signaling that it seems the bug is still around. Is there a workaround? Does it depend on the function used? As a start, I would like to get the PE ratio and dividend yield. By the way, it seems to be an awesome project. Just starting with it.

Error traceback: Traceback (most recent call last):

File ~\anaconda3\envs\py311\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals)

File c:\users\ms\mon drive\aktien und anlage, finanzen, rente\software\findatabase\getntvaluations.py:57 ratios = companies.ratios

File ~\anaconda3\envs\py311\Lib\site-packages\financetoolkit\base\toolkit_controller.py:175 in ratios self.get_balance_sheet_statement()

File ~\anaconda3\envs\py311\Lib\site-packages\financetoolkit\base\toolkit_controller.py:570 in get_balance_sheet_statement ) = _get_financial_statements(

File ~\anaconda3\envs\py311\Lib\site-packages\financetoolkit\base\models\fundamentals_model.py:111 in get_financial_statements financial_statement_total = pd.concat(financial_statement_dict, axis=0)

File ~\anaconda3\envs\py311\Lib\site-packages\pandas\core\reshape\concat.py:385 in concat return op.get_result()

File ~\anaconda3\envs\py311\Lib\site-packages\pandas\core\reshape\concat.py:612 in get_result indexers[ax] = obj_labels.get_indexer(new_labels)

File ~\anaconda3\envs\py311\Lib\site-packages\pandas\core\indexes\base.py:3732 in get_indexer raise InvalidIndexError(self._requires_unique_msg)

InvalidIndexError: Reindexing only valid with uniquely valued Index objects

Code used including list of symbols, I erased my key:

import pandas as pd import numpy as np

from financetoolkit import Toolkit

API_KEY = "something"

Initialize the Toolkit with company tickers

They can be copied from the listing formula in copy sheet in NT8 export file

companies = Toolkit( ["AAP", "ADM", "ADP", "APA", "ARE", "BXP", "CE", "CF", "CHTR", "CINF", "CMCSA", "CME", "COP", "CTLT", "CVX", "DD", "DOW", "DVN", "EOG", "FANG", "FCX", "FFIV", "FITB", "GNRC", "HBAN", "HES", "HUM", "IEX", "ILMN", "IPGP", "JBHT", "JPM", "LIN", "LNC", "LYB", "MAR", "MET", "MKC", "MOS", "MPC", "MRO", "MTB", "OKE", "OXY", "PAYX", "PNC", "PNR", "POOL", "PRGO", "PRU", "PSX", "PXD", "RF", "STT", "TAP", "TSCO", "TSN", "VLO", "WAB", "WRK"], \ api_key=API_KEY, start_date="2000-01-01" )

Including Sector:

companies.get_profile()

ratios = companies.ratios

ratios.collect_valuation_ratios()

Hi! This is an older version of the package and meant for Python versions under 3.10. Please update your Python version and update to the latest release (v1.2.0) which has this issue fixed.

EDIT: actually, I believe just updating to the latest version should fix your issue.