aboutsummaryrefslogtreecommitdiff
path: root/components/filings.py
blob: a1e44177da73d7864c904bb16310993fd53dd0d5 (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
"""SEC filings — recent 10-K, 10-Q, 8-K and other forms with direct links."""
import streamlit as st

from services.data_service import get_sec_filings


_FORM_DESCRIPTIONS = {
    "10-K": "Annual report",
    "10-Q": "Quarterly report",
    "8-K": "Material event disclosure",
    "DEF 14A": "Proxy statement",
    "S-1": "IPO registration",
    "S-3": "Securities registration",
    "4": "Insider ownership change",
    "SC 13G": "Beneficial ownership (passive)",
    "SC 13D": "Beneficial ownership (active)",
}

_FORM_COLORS = {
    "10-K": "rgba(79,142,247,0.15)",
    "10-Q": "rgba(130,224,170,0.15)",
    "8-K": "rgba(247,162,79,0.15)",
}


def render_filings(ticker: str):
    with st.spinner("Loading SEC filings…"):
        filings = get_sec_filings(ticker)

    if not filings:
        st.info("No SEC filing data available for this ticker.")
        return

    # yfinance returns: date (datetime.date), type, title, edgarUrl, exhibits (dict)
    form_types = sorted({str(f.get("type", "")).strip() for f in filings if f.get("type")})
    priority = [t for t in ["10-K", "10-Q", "8-K"] if t in form_types]
    other = [t for t in form_types if t not in ("10-K", "10-Q", "8-K")]
    filter_options = ["All"] + priority + other

    filter_col, _ = st.columns([1, 3])
    with filter_col:
        selected_type = st.selectbox("Form type", options=filter_options, index=0, key="filings_filter")

    # Summary counts
    counts = {}
    for f in filings:
        ft = str(f.get("type", "Other")).strip()
        counts[ft] = counts.get(ft, 0) + 1

    if priority:
        cols = st.columns(len(priority))
        for col, ft in zip(cols, priority):
            col.metric(ft, counts.get(ft, 0))
    st.write("")

    filtered = filings if selected_type == "All" else [
        f for f in filings if str(f.get("type", "")).strip() == selected_type
    ]

    if not filtered:
        st.info("No filings match the current filter.")
        return

    for item in filtered[:40]:
        form = str(item.get("type", "—")).strip()
        date = str(item.get("date", ""))[:10]
        title = item.get("title") or _FORM_DESCRIPTIONS.get(form, "")
        edgar_url = item.get("edgarUrl", "")
        exhibits = item.get("exhibits") or {}

        color = _FORM_COLORS.get(form, "rgba(255,255,255,0.05)")

        with st.container():
            left, right = st.columns([5, 1])
            with left:
                st.markdown(
                    f"<div style='background:{color};padding:6px 10px;border-radius:4px;margin-bottom:2px'>"
                    f"<strong>{form}</strong> &nbsp;·&nbsp; "
                    f"<span style='color:#9aa0b0;font-size:0.82rem'>{date}</span><br>"
                    f"<span style='font-size:0.85rem'>{title}</span>"
                    f"</div>",
                    unsafe_allow_html=True,
                )
            with right:
                # Prefer the actual filing doc over the Yahoo index page
                doc_url = exhibits.get(form) or edgar_url
                if doc_url:
                    st.markdown(
                        f"<div style='padding-top:8px'><a href='{doc_url}' target='_blank'>🔗 View</a></div>",
                        unsafe_allow_html=True,
                    )