From 425874931ffd3e3cef60262f7f0b7cb678629278 Mon Sep 17 00:00:00 2001 From: Tyler Date: Sun, 29 Mar 2026 18:04:14 -0700 Subject: Add yfinance fallback for historical ratios when FMP quota is exhausted FMP free tier caps at 250 req/day; hitting the limit caused the Historical Ratios tab to show an error. get_historical_ratios_yfinance now computes margins, ROE, ROA, D/E, P/E, P/B, P/S, and EV/EBITDA directly from yfinance income statements, balance sheets, and price history. FMP functions fall back to this automatically when they receive an empty response. Co-Authored-By: Claude Sonnet 4.6 --- services/fmp_service.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'services/fmp_service.py') diff --git a/services/fmp_service.py b/services/fmp_service.py index bba6c85..3bfa5c1 100644 --- a/services/fmp_service.py +++ b/services/fmp_service.py @@ -3,7 +3,7 @@ import os import requests import streamlit as st from dotenv import load_dotenv -from services.data_service import get_company_info +from services.data_service import get_company_info, get_historical_ratios_yfinance load_dotenv() @@ -121,16 +121,24 @@ def get_company_news(ticker: str, limit: int = 20) -> list[dict]: @st.cache_data(ttl=86400) def get_historical_ratios(ticker: str, limit: int = 10) -> list[dict]: - """Annual historical valuation ratios (P/E, P/B, P/S, EV/EBITDA, etc.).""" + """Annual historical valuation ratios (P/E, P/B, P/S, EV/EBITDA, etc.). + Falls back to yfinance-computed ratios if FMP returns empty (e.g. rate limit).""" data = _get(STABLE_BASE, "/ratios", params={"symbol": ticker.upper(), "limit": limit}) - return data if isinstance(data, list) else [] + if isinstance(data, list) and data: + return data + return get_historical_ratios_yfinance(ticker.upper()) @st.cache_data(ttl=86400) def get_historical_key_metrics(ticker: str, limit: int = 10) -> list[dict]: - """Annual historical key metrics (ROE, ROA, margins, debt/equity, etc.).""" + """Annual historical key metrics (ROE, ROA, margins, debt/equity, etc.). + Falls back to yfinance-computed metrics if FMP returns empty (e.g. rate limit).""" data = _get(STABLE_BASE, "/key-metrics", params={"symbol": ticker.upper(), "limit": limit}) - return data if isinstance(data, list) else [] + if isinstance(data, list) and data: + return data + # yfinance fallback already covers all key metrics — return empty to avoid duplication + # (get_historical_ratios will have already provided the full merged dataset) + return [] @st.cache_data(ttl=3600) -- cgit v1.3-2-g0d8e