ranaroussi / yfinance

Download market data from Yahoo! Finance's API
https://aroussi.com/post/python-yahoo-finance
Apache License 2.0
14.96k stars 2.45k forks source link

Index out of range: some Tickers #208

Closed ghost closed 1 year ago

ghost commented 4 years ago

Some Tickers fail on get_info() due to the following error. Is there is a fail safe way to access info.

~\Anaconda3\lib\site-packages\yfinance\base.py in _get_fundamentals(self, kind, proxy) 284 holders = _pd.read_html(url) 285 self._major_holders = holders[0] --> 286 self._institutional_holders = holders[1] 287 if 'Date Reported' in self._institutional_holders: 288 self._institutional_holders['Date Reported'] = _pd.to_datetime(

IndexError: list index out of range

rgex commented 4 years ago

One example:

ticker = yf.Ticker("2222.SR")
print(ticker.info)
rgex commented 4 years ago

There are some PR with fixes such as this one: https://github.com/ranaroussi/yfinance/pull/179 @ranaroussi can you merge it into the master? it would be great! :+1:

anonz322 commented 4 years ago

I tried a few of those PR, without any success (even the 168, which is a bit different than the others (using empty DF instead of just testing len), didn't work for me). Did you have positive results @rgex ? With what PR ?

284         holders = _pd.read_html(url)
285 
--> 286         self._major_holders = _pd.DataFrame()
287         self._institutional_holders = _pd.DataFrame()
288         if len(holders) >= 2:

IndexError: list index out of range
rgex commented 4 years ago

I didn't tried it, but a if len(holders) >= 2: should definitely do it.

anonz322 commented 4 years ago

That’s what I thought too, and what is therefore puzzling me (see my error log, it should work). I tried commenting out the part with holders, but had still the IndexError (pointing to commented lines then 😅), maybe in the parsing (just before)?

Edit : to reproduce (I’m on my phone rn, but afaik, my whole env is up to date, can post versions later):

import yfinance as yf
tk=yf.Ticker(“HSBC”)
tk.info

(Since the interesting part for me was free floating cap, basically removing the rest of the api kinda worked, but quite suboptimal as a solution;)

rgex commented 4 years ago

pip3 install -e git+git://github.com/vonHacht/yfinance.git@master#egg=yfinance this worked for me!

anonz322 commented 4 years ago

Oh yeah, now it works for me too! Thx!

lefig commented 4 years ago

I upgraded today to the latest version but still get this error. I trade UK LSE equities and symbols in my universe such as as msft = yf.Ticker("AAS.L") generate the exception on:

get stock info

msft.info

How wierd and annoying.

But this is a fabulous project. Thank you for all your hard work.

lefig commented 4 years ago

Ah, I think that I know why now, The exception gets thrown internally on attempting to get fundamentals. And I trade mostly funds such as AAS where there is no complete fundamental data sometimes. I will investigate further. Ta

anonz322 commented 4 years ago

Did you try one of the other PR, like previously mentioned (since they are...well, PR and not (yet) merged;) ? Is the exception threw for holders too or another field from the fundamentals ?

lefig commented 4 years ago

Sorry, but what is PR?

anonz322 commented 4 years ago

Sorry, "pull requests" (modifications not (yet) merged into the "official version"), try installing with the following command and post the error message if it's still not working for you !

pip3 install -e git+git://github.com/vonHacht/yfinance.git@master#egg=yfinance

FrancescoJGrechi commented 4 years ago

The above PR doesn't solve the issue when holders = _pd.read_html(url) fails (i.e. pandas cannot find tables in the returned data). My hacky fix was to completely wrap all the code included between the #headers comment to the #sustainability comment in a try-except block. I then correct the returned values in my project code. Would be curious to see if anyone else might have a smarter fix.

Lachlan00 commented 4 years ago

Hey all. I also get this error when pulling data for smaller cap Australian stocks. I'm also using PR pip3 install -e git+git://github.com/vonHacht/yfinance.git@master#egg=yfinance.

ticker = yf.Ticker('MXC.AX')
ticker.info

Error:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-1-df50194bed9e> in <module>
      1 ticker = yf.Ticker('MXC.AX')
----> 2 ticker.info

~/anaconda3/envs/CEO_salary/lib/python3.7/site-packages/yfinance/ticker.py in info(self)
    136     @property
    137     def info(self):
--> 138         return self.get_info()
    139 
    140     @property

~/anaconda3/envs/CEO_salary/lib/python3.7/site-packages/yfinance/base.py in get_info(self, proxy, as_dict, *args, **kwargs)
    413 
    414     def get_info(self, proxy=None, as_dict=False, *args, **kwargs):
--> 415         self._get_fundamentals(proxy)
    416         data = self._info
    417         if as_dict:

~/anaconda3/envs/CEO_salary/lib/python3.7/site-packages/yfinance/base.py in _get_fundamentals(self, kind, proxy)
    284         holders = _pd.read_html(url)
    285         self._major_holders = holders[0]
--> 286         self._institutional_holders = holders[1]
    287         if 'Date Reported' in self._institutional_holders:
    288             self._institutional_holders['Date Reported'] = _pd.to_datetime(

IndexError: list index out of range
Lachlan00 commented 4 years ago

Creating a conditional statement for the offending code (line 286-292 in base.py) fixed the issue for me.

if len(holders) > 1:
    self._institutional_holders = holders[1]
    if 'Date Reported' in self._institutional_holders:
        self._institutional_holders['Date Reported'] = _pd.to_datetime(
            self._institutional_holders['Date Reported'])
    if '% Out' in self._institutional_holders:
        self._institutional_holders['% Out'] = self._institutional_holders[
            '% Out'].str.replace('%', '').astype(float)/100

Works as expected

In [5]: ticker = yf.Ticker('MXC.AX') 
   ...: ticker.info['marketCap']                                                                                                                                                                                                              
Out[5]: 23309042
zxc477181 commented 4 years ago

Lachlan00's method works for me too. I am now able to visit the "marketCab" value for "MMM".

In [176]: ticker = yf.Ticker('MMM')
     ...: ticker.info["marketCap"]
Out[176]: 76964167680
Dave-DigiMim commented 4 years ago

I get an error list index out of range for the following tick=yf.Ticker(NED.JO) on yahoo finance page Nedbank is NED,JO

tick=yf.Ticker(AAPL) works fine

scsanty commented 4 years ago

Creating a conditional statement for the offending code (line 286-292 in base.py) fixed the issue for me.

if len(holders) > 1:
    self._institutional_holders = holders[1]
    if 'Date Reported' in self._institutional_holders:
        self._institutional_holders['Date Reported'] = _pd.to_datetime(
            self._institutional_holders['Date Reported'])
    if '% Out' in self._institutional_holders:
        self._institutional_holders['% Out'] = self._institutional_holders[
            '% Out'].str.replace('%', '').astype(float)/100

Works as expected

In [5]: ticker = yf.Ticker('MXC.AX') 
   ...: ticker.info['marketCap']                                                                                                                                                                                                              
Out[5]: 23309042

@Lachlan00 : Code changes works for me too. Thank you.

j-legit commented 4 years ago

Creating a conditional statement for the offending code (line 286-292 in base.py) fixed the issue for me.

if len(holders) > 1:
    self._institutional_holders = holders[1]
    if 'Date Reported' in self._institutional_holders:
        self._institutional_holders['Date Reported'] = _pd.to_datetime(
            self._institutional_holders['Date Reported'])
    if '% Out' in self._institutional_holders:
        self._institutional_holders['% Out'] = self._institutional_holders[
            '% Out'].str.replace('%', '').astype(float)/100

Works as expected

In [5]: ticker = yf.Ticker('MXC.AX') 
   ...: ticker.info['marketCap']                                                                                                                                                                                                              
Out[5]: 23309042

@Lachlan00 : Works for me as well. Many thanks.

gerardsyd commented 4 years ago

@Lachlan00 solution worked for me too