From 3e1324eff69e4b121f85223758b872c7fb5dc027 Mon Sep 17 00:00:00 2001 From: Tyler Date: Sun, 29 Mar 2026 15:41:42 -0700 Subject: Migrate insiders and filings from FMP to yfinance FMP v3 insider-trading and sec_filings endpoints are legacy-gated. Switch to yfinance (t.insider_transactions, t.sec_filings) which provides the same data for free with no API key required. Co-Authored-By: Claude Sonnet 4.6 --- services/data_service.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'services') diff --git a/services/data_service.py b/services/data_service.py index 0399c58..5ac8573 100644 --- a/services/data_service.py +++ b/services/data_service.py @@ -145,6 +145,32 @@ def get_next_earnings_date(ticker: str) -> str | None: return None +@st.cache_data(ttl=3600) +def get_insider_transactions(ticker: str) -> pd.DataFrame: + """Return insider transactions from yfinance. + Columns: Shares, URL, Text, Insider, Position, Transaction, Start Date, Ownership, Value + """ + try: + t = yf.Ticker(ticker.upper()) + df = t.insider_transactions + return df if df is not None and not df.empty else pd.DataFrame() + except Exception: + return pd.DataFrame() + + +@st.cache_data(ttl=3600) +def get_sec_filings(ticker: str) -> list[dict]: + """Return SEC filings from yfinance. + Each dict has: date, type, title, edgarUrl, exhibits. + """ + try: + t = yf.Ticker(ticker.upper()) + filings = t.sec_filings + return filings if filings else [] + except Exception: + return [] + + @st.cache_data(ttl=3600) def get_free_cash_flow_series(ticker: str) -> pd.Series: """Return annual Free Cash Flow series (most recent first).""" -- cgit v1.3-2-g0d8e