eugene-intelligence / eugene /resolver.py
Matthew-Anyiam
update to v0.4
3a3a58f
Raw History Blame Contribute Delete
2.68 kB
"""Resolve ticker / CIK / accession → full company identity."""
import re
from eugene.cache import cached
from eugene.sources.sec_api import fetch_tickers, fetch_submissions
ACCESSION_RE = re.compile(r"^\d{10}-\d{2}-\d{6}$")
CIK_RE = re.compile(r"^\d{1,10}$")
@cached(ttl=86400)
def _load_ticker_map() -> dict:
"""Build ticker → {cik, company} lookup from SEC."""
data = fetch_tickers()
result = {}
for entry in data.values():
result[entry["ticker"].upper()] = {
"cik": str(entry["cik_str"]).zfill(10),
"company": entry["title"],
}
return result
def resolve(identifier: str) -> dict:
"""
Resolve any identifier to {ticker, cik, company, sic, fiscal_year_end}.
Accepts:
- Ticker: AAPL
- CIK: 320193 or 0000320193
- Accession: 0000320193-24-000123
"""
identifier = identifier.strip()
# --- Accession number ---
if ACCESSION_RE.match(identifier):
cik = identifier.split("-")[0]
try:
subs = fetch_submissions(cik)
tickers = subs.get("tickers", [])
return {
"ticker": tickers[0] if tickers else None,
"cik": cik,
"company": subs.get("name", ""),
"sic": subs.get("sic", ""),
"fiscal_year_end": subs.get("fiscalYearEnd", ""),
"accession": identifier,
}
except Exception as e:
return {"error": f"Could not resolve accession {identifier}: {e}"}
# --- CIK (pure digits) ---
if CIK_RE.match(identifier):
cik = identifier.zfill(10)
try:
subs = fetch_submissions(cik)
tickers = subs.get("tickers", [])
return {
"ticker": tickers[0] if tickers else None,
"cik": cik,
"company": subs.get("name", ""),
"sic": subs.get("sic", ""),
"fiscal_year_end": subs.get("fiscalYearEnd", ""),
}
except Exception as e:
return {"error": f"Could not resolve CIK {identifier}: {e}"}
# --- Ticker ---
ticker = identifier.upper().replace(" ", "")
ticker_map = _load_ticker_map()
if ticker not in ticker_map:
return {"error": f"Unknown ticker: {ticker}"}
entry = ticker_map[ticker]
cik = entry["cik"]
try:
subs = fetch_submissions(cik)
except Exception:
subs = {}
return {
"ticker": ticker,
"cik": cik,
"company": entry.get("company", subs.get("name", "")),
"sic": subs.get("sic", ""),
"fiscal_year_end": subs.get("fiscalYearEnd", ""),
}