Files
All-in-one-Financial-Analysis/data/estimates.py
T

89 lines
2.6 KiB
Python
Raw Normal View History

"""
Analyst estimates — earnings & revenue forecasts, consensus targets.
"""
import streamlit as st
import pandas as pd
try:
import yfinance as yf
except ImportError:
yf = None
@st.cache_data(ttl=600)
def get_analyst_estimates(ticker: str) -> dict:
"""Fetch analyst earnings and revenue estimates from yfinance."""
if not yf or not ticker:
return {}
try:
t = yf.Ticker(ticker)
result = {}
# Earnings estimates
ee = getattr(t, "earnings_estimate", None)
if ee is not None and not ee.empty:
result["earnings_estimate"] = ee
# Revenue estimates
re = getattr(t, "revenue_estimate", None)
if re is not None and not re.empty:
result["revenue_estimate"] = re
# EPS trend
et = getattr(t, "eps_trend", None)
if et is not None and not et.empty:
result["eps_trend"] = et
# Earnings history
eh = getattr(t, "earnings_history", None)
if eh is not None and not eh.empty:
result["earnings_history"] = eh
# Growth estimates
ge = getattr(t, "growth_estimates", None)
if ge is not None and not ge.empty:
result["growth_estimates"] = ge
# Price targets
info = t.info or {}
result["targets"] = {
"current": info.get("currentPrice") or info.get("regularMarketPrice"),
"mean": info.get("targetMeanPrice"),
"high": info.get("targetHighPrice"),
"low": info.get("targetLowPrice"),
"median": info.get("targetMedianPrice"),
"recommendation": info.get("recommendationKey", "N/A"),
"num_analysts": info.get("numberOfAnalystOpinions"),
}
return result
except Exception:
return {}
@st.cache_data(ttl=600)
def get_earnings_dates(ticker: str) -> pd.DataFrame:
"""Fetch historical and upcoming earnings dates with surprise data."""
if not yf or not ticker:
return pd.DataFrame()
try:
t = yf.Ticker(ticker)
dates = t.earnings_dates
if dates is not None and not dates.empty:
return dates.head(12)
except Exception:
pass
return pd.DataFrame()
def format_estimate_table(df: pd.DataFrame) -> pd.DataFrame:
"""Format estimate DataFrame for display with proper number formatting."""
if df is None or df.empty:
return pd.DataFrame()
display = df.copy()
for col in display.columns:
display[col] = display[col].apply(
lambda v: f"{v:,.2f}" if isinstance(v, (int, float)) and v == v else "N/A"
)
return display