A **cost-effective** Streamlit app that unifies **qualitative AI-driven insights** and **quantitative valuation** in a single workflow. **Hybrid architecture:** Gemini powers narrative analysis (10-K MD&A and Risk Factors); all numbers—DCF inputs and peer multiples—come from **yfinance**, keeping API costs low and numerical accuracy high.
- **Error handling:** Try/except for SEC EDGAR, yfinance, and Gemini; clear messages and optional manual overrides.
- **UI:** Sidebar (API key, SEC email, **global company search** via yahooquery—search by name in any language). **Quantitative charts** (Sankey, Radar, F-Score) can use SEC 10-K Item 8 + Gemini extraction (US) or yahooquery/yfinance (global tickers with auto suffix).
The core idea for this all-in-one architecture came during a **quiet walk**. I was deep in thought about the inefficiencies and fragmentation of traditional equity research: narrative buried in 200-page filings, valuation models in separate spreadsheets, and comps scattered across different tools. It became clear that what we need is not more dashboards, but **one seamless workflow**—where qualitative AI insights and quantitative valuation models live in the same place, speak the same language, and serve the same decision. That moment crystallised into the design you see here: **unified, cost-conscious, and built for the analyst who thinks in both words and numbers.**
### The Vision — Commercialization
This repository is a **functional MVP (Minimum Viable Product)** and **demo**. It proves the concept: hybrid architecture works; 10-K + DCF + comps can sit in a single interface; and the unit economics (one Gemini call for narrative, free data for the rest) scale. The code is production-minded but not yet productised—it is the foundation on which a commercial product will be built.
### Future Roadmap
The **ultimate goal** is to launch this as a **fully commercialised B2C/B2B SaaS** application. We aim to serve **retail investors** who want institutional-grade structure without the complexity, and **finance professionals** (equity analysts, portfolio managers, corporate development) who want to move from filing → insight → valuation in one flow. Data-driven, transparent, and built by someone who cares as much about the quality of the analysis as the quality of the code. This project is the first step on that path.
As an undergraduate student, I realised that rather than just learning Excel and basic Python and doing everything manually, **automating the full workflow with AI and programmatic data** is far more powerful. This dashboard is the result: one place for 10-K narrative (Gemini), numbers (yfinance), DCF, and comps, so the analyst can focus on judgment instead of copy-pasting between tools.
A standard 5-year projection is often **too short for practical, real-world corporate analysis**. Many companies have growth that extends beyond five years, and terminal value then dominates the result, which can overstate or misstate value. The **10-year 2-stage model** (Stage 1: Years 1–5 at the chosen FCF growth rate; Stage 2: Years 6–10 with growth **linearly fading** down to the terminal growth rate) is closer to how institutional DCFs are built and avoids absurd valuations for high-growth names.
I regularly read valuation literature and **wanted to integrate Aswath Damodaran's academic baselines directly into the app**. The "Reference: Analyst & Macro Assumptions" panel shows sector WACC benchmarks (e.g. Software 8.5%, Retail 7.5%, Hardware 9.0%, Financials 8.0%), US equity risk premium (~4.6%), and the 10-year risk-free rate (~4.2%), with a link to his data and methodology so users can verify and align their assumptions with established research.
- **Consensus numbers next to the DCF sliders**
Having **analyst consensus data (target price, recommendation, revenue/earnings growth) right next to the DCF sliders** makes it much easier to make informed adjustments. Instead of guessing WACC or growth, the user can compare their inputs to both consensus and Damodaran's macro baselines in one view, like a professional equity research dashboard.
- **Commercialization**
Once the app's **completeness and robustness reach a higher professional standard**, my ultimate goal is to **fully commercialise it** (e.g. B2C/B2B SaaS). The current codebase is built as a production-minded MVP and demo to validate the hybrid architecture and user flow before scaling.
During the initial development of the SEC analysis module, I encountered severe 429 Resource Exhausted errors and extreme latency. The massive size of raw 10-K filings (often exceeding 100k+ tokens) easily breached the LLM’s context window and rate limits.
After consulting with a my friend who is junior software engineer working at MUST Company, I recognised that feeding entire financial documents to an LLM is an anti-pattern. I re-architected the application to a highly optimised Hybrid Data Pipeline, strictly decoupling qualitative reasoning from quantitative data retrieval.
Quantitative (yfinance API): Hard numbers (Revenue, Net Income, OCF) are fetched directly via API. This guarantees 100% deterministic accuracy for financials and prevents the LLM from hallucinating numbers or wasting tokens on dense HTML tables.
Targeted Extraction & Fallback Logic: Engineered a robust Regex-based parser to isolate only Item 7 from SEC EDGAR documents. Implemented safe fallback mechanisms to prevent app crashes when encountering unconventional document structures.
DOM Traversal & Noise Reduction: Before sending the extracted text to Gemini, a preprocessing pipeline (using BeautifulSoup + Regex) strips away HTML tags, inline CSS, repetitive boilerplate, and page numbers, drastically compressing the token footprint.
Context Window Optimization: For exceptionally long MD&A sections, I implemented a Head-Tail Truncation chunking strategy—retaining the executive introduction and concluding remarks—to ensure the most semantically dense information stays within token limits.
In-Memory Caching: Applied Streamlit caching (@st.cache_data) for both parsed SEC documents and LLM responses, eliminating redundant API calls and ensuring instant load times for subsequent queries.
Results & Efficiency:
This architectural shift reduced the token payload by roughly [80]%, completely resolved the 429 errors, dropped rendering latency to under [5] seconds, and achieved zero API cost for fundamental financial data retrieval.
(For full technical notes, code snippets, and architecture diagrams, see TECHNICAL_NOTES.md.)
If you don't have a `venv` folder yet, create it first:
```bash
python3 -m venv venv
source venv/bin/activate # then steps 3 and 4
```
Open the sidebar to set **Google API Key** and **SEC EDGAR Email**, then use the eight tabs (10-K Insights, Heatmap, DCF, Comps, SEC Filings, Earnings, Portfolio, Crypto) as needed.
| **2026-02-18** | **Market Heatmap & FX charts, 10-K 한글/영문:** (1) **Global Markets (Tab 2):** Sector heatmap uses **5d/1mo** data and **per-ticker fallback** so the treemap always renders (weekend/holiday robust). **FX Momentum** section now includes a **normalized 1Y line chart** (GBP/USD, EUR/USD, USD/JPY, KRW) with per-pair fetch fallback. **plotly** and **yfinance** fallback import in the view so charts work after `pip install plotly yfinance` without restart. (2) **10-K & MD&A:** Display language **한글 / 영문** radio; when "한글" is selected, Strategy and Risk analysis results are translated via Gemini (`translate_report_with_gemini`, 24h cache). Gemini API key required for translation. (3) **Requirements:** `plotly` and `yfinance` are required for heatmap and FX charts; install with `pip install plotly yfinance` if missing. |
| **2026-02-17** | **DART, prefs, 10-K tab, run script:** DART fetch timeout 90s; DART report titles in English (cached). SEC & DART tab: per-category iframe viewer (Annual/Quarterly/Other). **Last selected company** persisted in `.app_prefs.json` so it survives page refresh. API key input field no longer masked (type=password removed). Global Markets: time period labels in English; macro/FX use 5d when 1D selected for sparklines. **10-K & MD&A** tab restored in Deep Analysis with Item 7 (Strategy) and Item 1A (Risk) Gemini streaming. Single run script: **`run.sh`** and README state **http://localhost:8501** only. |
| **2025-02-15** | **Multi-currency portfolio & app-wide FX:** (1) **Portfolio (Tab 7):** Per-position **Currency** column (USD, GBP, EUR, KRW, JPY, CNY). **Fractional quantity** support (e.g. 30.395107). **FX-adjusted returns:** user cost/currency → real-time `get_fx_rate(user_curr, stock_curr)` → `adjusted_avg` in asset currency → Total Return % = (current − adjusted_avg) / adjusted_avg. (2) **AI screenshot (Gemini Vision):** Prompt updated to extract **Currency** (from $, £, €, ₩, ¥ → USD/GBP/EUR/KRW/JPY) and **Quantity** with decimals preserved. (3) **App-wide:** `get_currency_for_ticker`, `get_fx_rate`, `get_fx_rate_to_usd` (yfinance FX, TTL 60–120s), `format_price_with_usd` (local + USD e.g. ₩ 181,200 (≈ $ 132.50)). (4) **Valuation Hub:** DCF/Reverse DCF/RIM show ticker currency and USD conversion when non-USD. (5) **Earnings & Estimates:** Analyst targets/price in ticker currency with USD conversion. README restored to English with full changelog and 8-tab layout. |
| **2025-02-14** | **Global company search & README:** Sidebar company search replaced with yahooquery `search()`: type company name (e.g. Samsung, 삼성, Mitsubishi), click "Search Company", select from dropdown `[Exchange] Symbol - Name`. Filter: EQUITY/ETF only (exclude INDEX/MUTUALFUND). Market suffix inferred from symbol (.KS/.KQ, .T, .L). README: Tech Stack (yahooquery, lxml), Features (global search, Item 8 quant), run/push instructions path-agnostic. |
| **2025-02-13** | **Design Rationale & README:** New section "Design Rationale & Interview Notes" (undergrad automation mindset, 10y DCF rationale, Damodaran integration, consensus-panel rationale, commercialization). README Features and tab table updated to reflect 10Y 2-stage DCF, sector analysis, and Wall Street Assumptions panel. Changelog expanded with more detailed entries. |
| **2025-02-13** | **Institutional DCF & Wall Street panel:** (1) **10-year 2-stage DCF:** Stage 1 (Y1–5) at user FCF growth; Stage 2 (Y6–10) linear fade from that rate to terminal growth (avoids absurd valuations for high-growth stocks). TV at Year 10; all FCFs + TV discounted to PV. (2) **Wall Street Assumptions panel** (expander below sliders): **Left column** — Analyst consensus from yfinance: target mean price, recommendation, revenue growth est., earnings growth est. (N/A if missing). **Right column** — Damodaran macro baseline: sector WACC map (Software 8.5%, Retail 7.5%, Hardware 9.0%, Financials 8.0%, etc.), US ERP ~4.6%, 10Y risk-free ~4.2%, plus markdown link to his WACC data page for methodology. Company sector matched via `get_sector_industry` for Damodaran WACC. |
| **2025-02-13** | **Smart DCF defaults:** Slider defaults no longer hardcoded. **WACC:** CAPM approximation using `ticker.info.get('beta')` (default 1.0), Risk-free 4%, MRP 5%; default WACC = 4 + Beta×5, rounded to 1 decimal. **Terminal growth:** Fixed at 2.5% (Damodaran-style, long-term US GDP). **FCF growth:** From `revenueGrowth` or `earningsGrowth` (e.g. 0.15 → 15%); fallback 8%. Caption above sliders: "Slider defaults are auto-generated based on the company's Beta (CAPM) and revenue growth estimates." |
| **2025-02-13** | **Robust DCF data & comps:** (1) **Shares/Debt/Cash:** Multi-step fallback (fast_info → info → balance sheet) so S&P 500 names rarely need manual input. Shares: `fast_info.shares` → `sharesOutstanding` → `impliedSharesOutstanding`; display as "X.XXB Shares (real-time, auto-fetched)". Manual number_input only when all sources fail. (2) **Tab 3 redesign — Top-down sector analysis:** Manual ticker input removed. `SECTORS` dict (e.g. Semiconductors, Software & Cloud, Consumer Retail, Financials, Healthcare) with top 5 tickers each; st.selectbox to choose industry; comps table auto-loads with spinner. yfinance keys fixed to `forwardPE`, `enterpriseToEbitda`, `priceToBook`; missing shown as N/A. Conditional formatting: lowest P/E and EV/EBITDA green, highest red. **Generate Industry Outlook** button: Gemini prompt for macro analyst-style report (12–18 month trends, growth drivers, headwinds/regulatory risks); report rendered in Markdown below table. |
| **2025-02-13** | **Bulletproof DCF & Excel-style logic:** DCF no longer fails when yfinance misses data. Base FCF = OCF − CapEx; if Shares/Debt/Cash missing, st.number_input fallbacks. Three sliders (WACC, Terminal Growth, Projected FCF Growth) drive full DCF; intrinsic value vs current price (from yfinance) and Bull/Base/Bear table. Tab 1: Interest Coverage "nan%" fixed (N/A when Interest Expense 0 or missing). |
| **2025-02-12 15:30** | **Dynamic Sector-Specific Analysis:** DuPont table None/NaN → "N/A". Sector & industry badge (Tab 1). Sector-specific metrics: Tech (Rule of 40, FCF margin, R&D % revenue), Retail (inventory turnover, operating margin), Financials (ROE, ROA). Tab 2 caption for Financials (FCF/EBITDA less relevant). Gemini MD&A: sector/industry passed in; prompt asks for industry-specific Non-GAAP KPIs in a markdown table. |
| **2025-02-12 11:00** | **Data robustness & TTM fallback:** `_get_row_series` try/except; `_na(x)` for display. TTM fallback when annual financials/balance_sheet missing (quarterly sum / latest quarter). `get_sector_industry(ticker)` added. DuPont/Altman return empty dict on exception. |
| **2025-02-12 09:00** | **Hybrid architecture:** Item 7 only to Gemini; yfinance for numbers. HTML cleansing, find_toc.py. Prompt: strategy, risks, sentiment. |
| **2025-02-12 08:45** | Changelog and find_toc.py in Project Structure. |
| **2025-02-12** | **Remember API key & email:** Optional "Remember API key & email (save locally)" checkbox; values stored in `.app_prefs.json` (in .gitignore); prefill on load; uncheck removes file. |
If you use another branch or remote: replace `main` or `origin`. New repo: `git init`, then `git remote add origin <your-repo-url>`.
---
## License and Disclaimer
This project is for learning and portfolio use. Comply with [SEC policy](https://www.sec.gov/os/webmaster-faq#code-support) when using SEC data and with Google's terms for the Gemini API.