ranaroussi / yfinance

Download market data from Yahoo! Finance's API

Home Page:https://aroussi.com/post/python-yahoo-finance

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Strange behavior with yfinance on Fedora linux machine

brld opened this issue · comments

commented

Describe bug

I am running some simple test code for yfinance on two machines; both machines are running the same version of yahoo finance (0.2.33), one is on Windows 8.1 and one is on Fedora linux. Both are running the same version of python 3.9.7 with the same VSCode environment. The code runs with no problem on the Windows machine but throws errors even for simple test cases such as trying to get the .info of a ticker. I have not been able to identify why this is; the only tangible difference in environment is that the Fedora machine is running the code on a venv to manage dependencies more carefully.

Simple code that reproduces your problem

from datetime import datetime
import yfinance as yf

def new_lows(t: str, offset: int) -> list:
    current_year = datetime.now().year
    hist_raw = yf.Ticker(t).history(start=f"{current_year - offset}-01-01", end=f"{current_year - offset}-12-31", interval="1d").reset_index()
    if hist_raw.empty: # If period is before company founding date
      return [[None,None], None]
    hist_raw['Date'] = hist_raw['Date'].dt.strftime('%Y-%m-%d')
    hist = hist_raw.to_dict("list")["Close"]
    low = hist[0]
    new_lows = 0
    for v in hist[1:]:
      if v < low:
        new_lows += 1
        low = v
    return new_lows

new_lows("AAPL", 2)

The above code should output "22"; on Fedora the history fetch will come up empty and print the following:

AAPL: No price data found, symbol may be delisted (1d 2022-01-01 -> 2022-12-31)

t = yf.Ticker("AAPL")
t.info

The above code should output the relevant company information for AAPL. However on Fedora it will give a TypeError:

TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'str'

Debug log

For code print(t.info):

DEBUG get_raw_json(): https://query2.finance.yahoo.com/v10/finance/quoteSummary/AAPL
DEBUG Entering get()
DEBUG url=https://query2.finance.yahoo.com/v10/finance/quoteSummary/AAPL
DEBUG params={'modules': 'financialData,quoteType,defaultKeyStatistics,assetProfile,summaryDetail', 'ssl': 'true'}
DEBUG Entering _get_cookie_and_crumb()
DEBUG cookie_mode = 'basic'
DEBUG Entering _get_cookie_and_crumb_basic()

Full traceback:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[12], line 22
      4 # def new_lows(t: str, offset: int) -> list:
      5 #     current_year = datetime.now().year
      6 #     hist_raw = yf.Ticker(t).history(start=f"{current_year - offset}-01-01", end=f"{current_year - offset}-12-31", interval="1d").reset_index()
   (...)
     18 
     19 # new_lows("AAPL", 2)
     21 t = yf.Ticker("AAPL")
---> 22 t.info

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/ticker.py:142, in Ticker.info(self)
    140 @property
    141 def info(self) -> dict:
--> 142     return self.get_info()

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/base.py:1736, in TickerBase.get_info(self, proxy)
   1734 def get_info(self, proxy=None) -> dict:
   1735     self._quote.proxy = proxy
-> 1736     data = self._quote.info
   1737     return data

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/scrapers/quote.py:572, in Quote.info(self)
    569 @property
    570 def info(self) -> dict:
    571     if self._info is None:
--> 572         self._fetch(self.proxy)
    573         self._fetch_complementary(self.proxy)
    575     return self._info

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/scrapers/quote.py:602, in Quote._fetch(self, proxy)
    600 modules = ','.join(modules)
    601 params_dict = {"modules": modules, "ssl": "true"}
--> 602 result = self._data.get_raw_json(
    603     _BASIC_URL_ + f"/{self._symbol}", params=params_dict, proxy=proxy
    604 )
    605 result["quoteSummary"]["result"][0]["symbol"] = self._symbol
    606 query1_info = next(
    607     (info for info in result.get("quoteSummary", {}).get("result", []) if info["symbol"] == self._symbol),
    608     None,
    609 )

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/data.py:399, in YfData.get_raw_json(self, url, user_agent_headers, params, proxy, timeout)
    397 def get_raw_json(self, url, user_agent_headers=None, params=None, proxy=None, timeout=30):
    398     utils.get_yf_logger().debug(f'get_raw_json(): {url}')
--> 399     response = self.get(url, user_agent_headers=user_agent_headers, params=params, proxy=proxy, timeout=timeout)
    400     response.raise_for_status()
    401     return response.json()

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/utils.py:108, in log_indent_decorator.<locals>.wrapper(*args, **kwargs)
    105 logger.debug(f'Entering {func.__name__}()')
    107 with IndentationContext():
--> 108     result = func(*args, **kwargs)
    110 logger.debug(f'Exiting {func.__name__}()')
    111 return result

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/data.py:348, in YfData.get(self, url, user_agent_headers, params, proxy, timeout)
    345 if 'crumb' in params:
    346     raise Exception("Don't manually add 'crumb' to params dict, let data.py handle it")
--> 348 cookie, crumb, strategy = self._get_cookie_and_crumb()
    349 if crumb is not None:
    350     crumbs = {'crumb': crumb}

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/utils.py:108, in log_indent_decorator.<locals>.wrapper(*args, **kwargs)
    105 logger.debug(f'Entering {func.__name__}()')
    107 with IndentationContext():
--> 108     result = func(*args, **kwargs)
    110 logger.debug(f'Exiting {func.__name__}()')
    111 return result

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/data.py:324, in YfData._get_cookie_and_crumb(self, proxy, timeout)
    321         cookie, crumb = self._get_cookie_and_crumb_basic(proxy, timeout)
    322 else:
    323     # Fallback strategy
--> 324     cookie, crumb = self._get_cookie_and_crumb_basic(proxy, timeout)
    325     if cookie is None or crumb is None:
    326         # Fail
    327         self._set_cookie_strategy('csrf', have_lock=True)

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/utils.py:108, in log_indent_decorator.<locals>.wrapper(*args, **kwargs)
    105 logger.debug(f'Entering {func.__name__}()')
    107 with IndentationContext():
--> 108     result = func(*args, **kwargs)
    110 logger.debug(f'Exiting {func.__name__}()')
    111 return result

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/data.py:213, in YfData._get_cookie_and_crumb_basic(self, proxy, timeout)
    211 @utils.log_indent_decorator
    212 def _get_cookie_and_crumb_basic(self, proxy, timeout):
--> 213     cookie = self._get_cookie_basic(proxy, timeout)
    214     crumb = self._get_crumb_basic(proxy, timeout)
    215     return cookie, crumb

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/data.py:156, in YfData._get_cookie_basic(self, proxy, timeout)
    153     utils.get_yf_logger().debug('reusing cookie')
    154     return self._cookie
--> 156 self._cookie = self._load_cookie_basic()
    157 if self._cookie is not None:
    158     return self._cookie

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/data.py:142, in YfData._load_cookie_basic(self)
    141 def _load_cookie_basic(self):
--> 142     cookie_dict = cache.get_cookie_cache().lookup('basic')
    143     if cookie_dict is None:
    144         return None

File ~/Documents/local/development/pythonDevelopment/thomas/.venv/lib/python3.9/site-packages/yfinance/cache.py:362, in _CookieCache.lookup(self, strategy)
    360     data =  _CookieSchema.get(_CookieSchema.strategy == strategy)
    361     cookie = _pkl.loads(data.cookie_bytes)
--> 362     return {'cookie':cookie, 'age':_datetime.datetime.now()-data.fetch_date}
    363 except _CookieSchema.DoesNotExist:
    364     return None

TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'str'

For new_lows code:
DEBUG Entering history()
DEBUG AAPL: Yahoo GET parameters: {'period1': '2022-01-01 00:00:00-05:00', 'period2': '2022-12-31 00:00:00-05:00', 'interval': '1d', 'includePrePost': False, 'events': 'div,splits,capitalGains'}
DEBUG Entering get()
DEBUG url=https://query2.finance.yahoo.com/v8/finance/chart/AAPL
DEBUG params=frozendict.frozendict({'period1': 1641013200, 'period2': 1672462800, 'interval': '1d', 'includePrePost': False, 'events': 'div,splits,capitalGains'})
DEBUG Entering _get_cookie_and_crumb()
DEBUG cookie_mode = 'basic'
DEBUG Entering _get_cookie_and_crumb_basic()
ERROR AAPL: No price data found, symbol may be delisted (1d 2022-01-01 -> 2022-12-31)
DEBUG Exiting history()

Bad data proof

No response

yfinance version

0.2.33

Python version

3.9.7

Operating system

Fedora LXDE Linux

You've stumbled on the other difference - each will be using a different cached cookie and crumb. You need 0.2.34, check release notes.