Skip to content

Commit 0a00b3e

Browse files
committed
0.7614 - better Yahoo Finance stock price fetch handling
1 parent 1278635 commit 0a00b3e

File tree

1 file changed

+70
-16
lines changed

1 file changed

+70
-16
lines changed

src/api_get_stock_prices_yfinance.py

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99

1010
import yfinance as yf
11+
import requests
1112
import logging
1213
import sys
1314
import asyncio
@@ -20,27 +21,80 @@
2021
if not logging.getLogger().hasHandlers():
2122
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
2223

23-
# Search for stock symbol (Using yfinance for direct data fetching)
2424
async def search_stock_symbol(keyword):
2525
logging.info(f"Searching stock symbol for keyword: {keyword}")
26-
# yfinance doesn't have a direct search function like some APIs.
27-
# We often rely on Ticker() working or failing.
28-
# For a more robust search, you might need another library or API,
29-
# but Ticker() often works well with common names/symbols.
26+
27+
# 1) First try using the exact Ticker approach:
3028
try:
3129
ticker = yf.Ticker(keyword)
32-
# Attempt to access some data to validate the ticker
33-
if not ticker.info:
34-
# If .info is empty, try fetching history as another check
35-
hist_check = ticker.history(period="1d")
36-
if hist_check.empty:
37-
logging.info(f"No valid data found for keyword: {keyword} using yf.Ticker.")
38-
return "No matches found."
39-
logging.debug(f"Ticker info potentially found for {keyword}: {ticker.info.get('symbol', 'N/A')}")
40-
return ticker
30+
hist_check = ticker.history(period="1d")
31+
if not hist_check.empty:
32+
# We have data => success
33+
return ticker
34+
# If hist is empty, keep going
4135
except Exception as e:
42-
logging.error(f"Error attempting to validate ticker for keyword '{keyword}': {e}")
43-
return "Error during symbol search."
36+
logging.error(f"Error attempting to validate ticker for '{keyword}': {e}")
37+
38+
# 2) If the direct Ticker() attempt fails or is empty, fallback to a Yahoo search
39+
logging.info(f"No direct Ticker() data. Attempting fallback search for: {keyword}")
40+
symbols_found = yahoo_finance_search(keyword) # see function below
41+
42+
if symbols_found:
43+
# If you want to automatically pick the best match (the first or so):
44+
best_candidate = symbols_found[0] # or rank them somehow
45+
logging.info(f"Found possible symbol: {best_candidate}. Verifying with yf.Ticker()")
46+
ticker = yf.Ticker(best_candidate)
47+
hist_check = ticker.history(period="1d")
48+
if not hist_check.empty:
49+
return ticker
50+
else:
51+
logging.info(f"Fallback candidate {best_candidate} has no history.")
52+
# 3) If we still don’t get a valid ticker, just bail out
53+
return "No matches found."
54+
55+
def yahoo_finance_search(query):
56+
"""
57+
Use the (unofficial) Yahoo Finance search endpoint to find possible symbols.
58+
Returns a list of symbols (strings) if any are found, empty list if not.
59+
"""
60+
url = "https://query2.finance.yahoo.com/v1/finance/search"
61+
params = {"q": query, "quotesCount": 5} # maybe fetch top 5
62+
resp = requests.get(url, params=params)
63+
if resp.status_code != 200:
64+
return []
65+
data = resp.json()
66+
if "quotes" not in data:
67+
return []
68+
69+
symbols = []
70+
for item in data["quotes"]:
71+
# each item might have "symbol", "longname", etc.
72+
sym = item.get("symbol")
73+
if sym:
74+
symbols.append(sym)
75+
return symbols
76+
77+
# # Search for stock symbol (Using yfinance for direct data fetching)
78+
# async def search_stock_symbol(keyword):
79+
# logging.info(f"Searching stock symbol for keyword: {keyword}")
80+
# # yfinance doesn't have a direct search function like some APIs.
81+
# # We often rely on Ticker() working or failing.
82+
# # For a more robust search, you might need another library or API,
83+
# # but Ticker() often works well with common names/symbols.
84+
# try:
85+
# ticker = yf.Ticker(keyword)
86+
# # Attempt to access some data to validate the ticker
87+
# if not ticker.info:
88+
# # If .info is empty, try fetching history as another check
89+
# hist_check = ticker.history(period="1d")
90+
# if hist_check.empty:
91+
# logging.info(f"No valid data found for keyword: {keyword} using yf.Ticker.")
92+
# return "No matches found."
93+
# logging.debug(f"Ticker info potentially found for {keyword}: {ticker.info.get('symbol', 'N/A')}")
94+
# return ticker
95+
# except Exception as e:
96+
# logging.error(f"Error attempting to validate ticker for keyword '{keyword}': {e}")
97+
# return "Error during symbol search."
4498

4599
# format conversion (currently not in use)
46100
def format_float(value):

0 commit comments

Comments
 (0)