aboutsummaryrefslogtreecommitdiff
path: root/services/data_service.py
diff options
context:
space:
mode:
authorTyler <tyler@tylerhoang.xyz>2026-03-30 18:19:50 -0700
committerTyler <tyler@tylerhoang.xyz>2026-03-30 18:19:50 -0700
commitf6b21398b8d9d13fa707955852f4e73158d7db19 (patch)
tree7dd49e0f483b2bda9ff4b5db0f10df3a5eef06ca /services/data_service.py
parentfde921603425de36c6cbf583f1ec0e2f2ce034cb (diff)
Add score card, 52W range bar, short interest, options tab, CSV exports
Overview: - Score card: green/yellow/red signals for valuation, growth, profitability, leverage, momentum (vs 52W high), and short interest - 52W high/low visual range bar with current price marker and % context - Short interest metrics row: % of float, days to cover, shares short vs prior month - Replaced static 52W High/Low metrics with volume and avg volume Options tab (new): - Expiry selector across all available expirations - Put/call ratio by volume and open interest with bullish/bearish label - IV smile chart (calls + puts) with ATM marker - Open interest by strike (calls above, puts mirrored below axis) - Full chain table (calls/puts) in expandable section CSV exports: - Download button on each financial statement (income, balance, cash flow) - Download button on earnings history table Also fix top padding cut-off: block-container padding-top 1rem → 3.5rem Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'services/data_service.py')
-rw-r--r--services/data_service.py30
1 files changed, 30 insertions, 0 deletions
diff --git a/services/data_service.py b/services/data_service.py
index f0f981b..3de2484 100644
--- a/services/data_service.py
+++ b/services/data_service.py
@@ -158,6 +158,36 @@ def get_insider_transactions(ticker: str) -> pd.DataFrame:
return pd.DataFrame()
+@st.cache_data(ttl=900)
+def get_options_chain(ticker: str) -> dict:
+ """Return options chain data for the nearest available expirations.
+
+ Returns:
+ {
+ "expirations": [str, ...], # all available expiry dates
+ "chains": [
+ {"expiry": str, "calls": DataFrame, "puts": DataFrame},
+ ...
+ ]
+ }
+ """
+ try:
+ t = yf.Ticker(ticker.upper())
+ expirations = t.options
+ if not expirations:
+ return {}
+ chains = []
+ for exp in expirations[:8]:
+ try:
+ chain = t.option_chain(exp)
+ chains.append({"expiry": exp, "calls": chain.calls, "puts": chain.puts})
+ except Exception:
+ pass
+ return {"expirations": list(expirations), "chains": chains}
+ except Exception:
+ return {}
+
+
@st.cache_data(ttl=3600)
def get_sec_filings(ticker: str) -> list[dict]:
"""Return SEC filings from yfinance.