fix: add exponential backoff retry for yfinance rate limits (#426)

This commit is contained in:
Yijia-Xiao
2026-03-22 22:11:08 +00:00
parent bd9b1e5efa
commit 7cca9c924e
2 changed files with 42 additions and 17 deletions
+15 -15
View File
@@ -3,7 +3,7 @@ from datetime import datetime
from dateutil.relativedelta import relativedelta
import yfinance as yf
import os
from .stockstats_utils import StockstatsUtils, _clean_dataframe
from .stockstats_utils import StockstatsUtils, _clean_dataframe, yf_retry
def get_YFin_data_online(
symbol: Annotated[str, "ticker symbol of the company"],
@@ -18,7 +18,7 @@ def get_YFin_data_online(
ticker = yf.Ticker(symbol.upper())
# Fetch historical data for the specified date range
data = ticker.history(start=start_date, end=end_date)
data = yf_retry(lambda: ticker.history(start=start_date, end=end_date))
# Check if data is empty
if data.empty:
@@ -234,14 +234,14 @@ def _get_stock_stats_bulk(
if os.path.exists(data_file):
data = pd.read_csv(data_file, on_bad_lines="skip")
else:
data = yf.download(
data = yf_retry(lambda: yf.download(
symbol,
start=start_date_str,
end=end_date_str,
multi_level_index=False,
progress=False,
auto_adjust=True,
)
))
data = data.reset_index()
data.to_csv(data_file, index=False)
@@ -300,7 +300,7 @@ def get_fundamentals(
"""Get company fundamentals overview from yfinance."""
try:
ticker_obj = yf.Ticker(ticker.upper())
info = ticker_obj.info
info = yf_retry(lambda: ticker_obj.info)
if not info:
return f"No fundamentals data found for symbol '{ticker}'"
@@ -358,11 +358,11 @@ def get_balance_sheet(
"""Get balance sheet data from yfinance."""
try:
ticker_obj = yf.Ticker(ticker.upper())
if freq.lower() == "quarterly":
data = ticker_obj.quarterly_balance_sheet
data = yf_retry(lambda: ticker_obj.quarterly_balance_sheet)
else:
data = ticker_obj.balance_sheet
data = yf_retry(lambda: ticker_obj.balance_sheet)
if data.empty:
return f"No balance sheet data found for symbol '{ticker}'"
@@ -388,11 +388,11 @@ def get_cashflow(
"""Get cash flow data from yfinance."""
try:
ticker_obj = yf.Ticker(ticker.upper())
if freq.lower() == "quarterly":
data = ticker_obj.quarterly_cashflow
data = yf_retry(lambda: ticker_obj.quarterly_cashflow)
else:
data = ticker_obj.cashflow
data = yf_retry(lambda: ticker_obj.cashflow)
if data.empty:
return f"No cash flow data found for symbol '{ticker}'"
@@ -418,11 +418,11 @@ def get_income_statement(
"""Get income statement data from yfinance."""
try:
ticker_obj = yf.Ticker(ticker.upper())
if freq.lower() == "quarterly":
data = ticker_obj.quarterly_income_stmt
data = yf_retry(lambda: ticker_obj.quarterly_income_stmt)
else:
data = ticker_obj.income_stmt
data = yf_retry(lambda: ticker_obj.income_stmt)
if data.empty:
return f"No income statement data found for symbol '{ticker}'"
@@ -446,7 +446,7 @@ def get_insider_transactions(
"""Get insider transactions data from yfinance."""
try:
ticker_obj = yf.Ticker(ticker.upper())
data = ticker_obj.insider_transactions
data = yf_retry(lambda: ticker_obj.insider_transactions)
if data is None or data.empty:
return f"No insider transactions data found for symbol '{ticker}'"