aboutsummaryrefslogtreecommitdiff
path: root/components/overview.py
blob: 74077537a553da4a4d37876aae8cd2dd8f1dd082 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""Company overview — header, key stats, and price chart."""
import streamlit as st
import plotly.graph_objects as go
from services.data_service import get_company_info, get_price_history
from utils.formatters import fmt_large, fmt_currency, fmt_pct, fmt_ratio


PERIODS = {"1 Month": "1mo", "3 Months": "3mo", "6 Months": "6mo", "1 Year": "1y", "5 Years": "5y"}


def render_overview(ticker: str):
    info = get_company_info(ticker)
    if not info:
        st.error(f"Could not load data for **{ticker}**. Check the ticker symbol.")
        return

    # ── Company header ──────────────────────────────────────────────────────
    name = info.get("longName") or info.get("shortName", ticker.upper())
    price = info.get("currentPrice") or info.get("regularMarketPrice")
    prev_close = info.get("regularMarketPreviousClose") or info.get("previousClose")

    price_change = None
    price_change_pct = None
    if price and prev_close:
        price_change = price - prev_close
        price_change_pct = price_change / prev_close

    col1, col2 = st.columns([3, 1])
    with col1:
        st.subheader(f"{name} ({ticker.upper()})")
        sector = info.get("sector", "")
        industry = info.get("industry", "")
        if sector:
            st.caption(f"{sector} · {industry}")

    with col2:
        delta_str = None
        if price_change is not None and price_change_pct is not None:
            delta_str = f"{price_change:+.2f} ({price_change_pct * 100:+.2f}%)"
        st.metric(
            label="Price",
            value=fmt_currency(price) if price else "—",
            delta=delta_str,
        )

    # ── Key stats strip ─────────────────────────────────────────────────────
    stats_cols = st.columns(6)
    stats = [
        ("Mkt Cap", fmt_large(info.get("marketCap"))),
        ("P/E (TTM)", fmt_ratio(info.get("trailingPE"))),
        ("EPS (TTM)", fmt_currency(info.get("trailingEps"))),
        ("52W High", fmt_currency(info.get("fiftyTwoWeekHigh"))),
        ("52W Low", fmt_currency(info.get("fiftyTwoWeekLow"))),
        ("Beta", fmt_ratio(info.get("beta"))),
    ]
    for col, (label, val) in zip(stats_cols, stats):
        col.metric(label, val)

    st.divider()

    # ── Price chart ─────────────────────────────────────────────────────────
    period_label = st.radio(
        "Period",
        options=list(PERIODS.keys()),
        index=3,
        horizontal=True,
        label_visibility="collapsed",
    )
    period = PERIODS[period_label]

    hist = get_price_history(ticker, period=period)
    if hist.empty:
        st.warning("No price history available.")
        return

    fig = go.Figure()
    fig.add_trace(
        go.Scatter(
            x=hist.index,
            y=hist["Close"],
            mode="lines",
            name="Close",
            line=dict(color="#4F8EF7", width=2),
            fill="tozeroy",
            fillcolor="rgba(79, 142, 247, 0.08)",
        )
    )
    fig.update_layout(
        margin=dict(l=0, r=0, t=10, b=0),
        xaxis=dict(showgrid=False, zeroline=False),
        yaxis=dict(showgrid=True, gridcolor="rgba(255,255,255,0.05)", zeroline=False),
        plot_bgcolor="rgba(0,0,0,0)",
        paper_bgcolor="rgba(0,0,0,0)",
        hovermode="x unified",
        height=320,
    )
    st.plotly_chart(fig, use_container_width=True)