shawnkim1997 b2acda81ee feat: add Atlas Terminal — Next.js 14 + FastAPI full-stack migration
Complete migration from Streamlit to Next.js 14 App Router + FastAPI backend.

Frontend (Next.js 14):
- 10 pages: Overview, Research, Valuation, Technical, Markets, Earnings, News, Portfolio, Filings, Settings
- Terminal Noir dark theme with custom Tailwind config
- TradingView Lightweight Charts for candlestick/volume
- Valuation: DCF, Sensitivity Matrix, Monte Carlo, Tornado, Reverse DCF
- Financial Statements table with YoY growth badges and margin rows
- SEC EDGAR inline filing viewer with section tabs
- News split-view with iframe article embedding
- Technical Analysis with RSI, MACD, Bollinger, Fibonacci, Moving Averages
- Earnings beat/miss visualization
- AI Copilot chat panel with Gemini integration

Backend (FastAPI):
- 13 routers: market_data, financials, valuation, technical, earnings, insider, edgar, news, portfolio, analysis, chat, estimates, fx
- Services: DCF engine, Monte Carlo simulation, sensitivity analysis, risk metrics, SEC parser, technical indicators
- yfinance + yahooquery data sources with fallback pattern
- SQLite caching layer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 02:10:10 +00:00

ATLAS Terminal — All-in-One Financial Analysis Dashboard

A cost-effective, institutional-grade financial analysis platform built with Streamlit. Combines qualitative AI-driven insights from SEC 10-K filings with quantitative valuation models in a single unified workflow.

Hybrid architecture: Google Gemini powers qualitative narrative analysis (MD&A, Risk Factors); all numbers—DCF inputs, peer multiples, technical indicators—come from yfinance and yahooquery, keeping API costs low and numerical accuracy high.


Live Demo

streamlit run app.py --server.port 8501

Open: http://localhost:8501


Seven-Tab Layout

Tab Purpose
1. 10-K & MD&A Insights SEC EDGAR 10-K → Item 7 (MD&A) + Item 1A (Risk Factors) → Gemini streaming analysis. DuPont, Altman Z-Score, red flags, YoY ratios; Piotroski F-Score; sector-specific KPIs; Sankey & Radar charts. Native SEC/DART filing HTML viewer.
2. DCF Valuation 5-year 2-stage DCF with Bull/Base/Bear scenarios. Smart defaults from Beta/CAPM. Damodaran sector WACC reference panel. Analyst consensus, FCFF/FCFE bridge, sensitivity table.
3. Industry Comps Peer multiples (Forward P/E, EV/EBITDA, P/B) with green/red conditional formatting. Gemini-powered industry outlook (1218 month macro trends).
4. News Feed Real-time Google News RSS feed filtered by company.
5. Markets & FX Live FX rates (USD/KRW, GBP/USD, EUR/USD, USD/JPY). S&P 500 sector performance heatmap (XLK, XLV, XLF …).
6. Crypto Live prices for 12 major cryptocurrencies (BTC, ETH, SOL, XRP …) with 24h change and market cap.
7. Technical & Risk RSI(14), SMA(50/200), Golden/Death Cross signals, 52-week range, support/resistance. Quantitative risk matrix with estimated EPS impact per risk factor.

Key Features

AI & Qualitative Analysis (Tab 1)

  • Gemini streaming for Item 7 (Management Strategy) and Item 1A (Risk Factors) — results appear word-by-word in real time
  • Forensic audit (Item 3 & 9A) runs automatically alongside Risk Factor analysis
  • Native SEC Filing Viewer: renders original SEC HTML directly in-app via streamlit.components.v1.html() — no redirect, no loss of formatting
  • Filing type selector: 10-K, 10-Q, 8-K, 20-F, 6-K — backend dynamically fetches the correct form from EDGAR
  • Korean DART direct links for Korean-listed companies
  • Sector-aware Non-GAAP KPI extraction: Gemini identifies industry-specific metrics (ARR/NDR for SaaS, Same-Store Sales for Retail, Rule of 40 for Tech)

Quantitative Analysis (Tab 1 & 2)

  • DuPont decomposition (3-step ROE: NPM × Asset Turnover × Equity Multiplier)
  • Altman Z-Score (Safe > 2.99, Grey Zone 1.812.99, Distress < 1.81)
  • Piotroski F-Score (9-point checklist; SEC Item 8 + Gemini for US equities, yahooquery/yfinance globally)
  • Sankey chart: Income Statement flow (Revenue → COGS → Gross → OpEx → EBIT → Tax/Interest → Net Income)
  • Radar chart: 5-axis financial health (Profitability, Liquidity, Efficiency, Solvency, Growth)
  • YoY and QoQ ratio changes with coloured trend indicators
  • Sector-specific metrics: Tech (Rule of 40, R&D %), Retail (Inventory Turnover), Financials (ROE, ROA)

DCF & Valuation (Tab 2)

  • Excel-style 5-year DCF: 3 scenarios (Bull/Base/Bear) with probability-weighted expected return
  • Smart defaults: WACC from CAPM (Beta), terminal growth 2.5% (Damodaran-style), FCF growth from consensus estimates
  • Damodaran sector WACC reference panel: Software 8.5%, Retail 7.5%, Hardware 9.0%, Financials 8.0%
  • FCFF/FCFE bridge: detailed waterfall from EBIT → NOPAT → FCFF and Net Income → FCFE
  • DCF sensitivity table: 5×5 grid across WACC and terminal growth rate combinations
  • Analyst consensus embedded next to sliders (target price, recommendation, revenue/earnings growth estimates)

Data Robustness

  • Primary: yahooquery for fundamentals + TTM construction
  • Fallback: yfinance (multi-step: fast_infoinfo → balance sheet)
  • TTM fallback: quarterly sum when annual data is unavailable
  • PyArrow-safe DataFrames: uniform column types to prevent serialization errors
  • @st.cache_data caching: 260 min TTL per function to minimise API calls
  • Search by name in any language (English, Korean, Japanese, etc.) via yahooquery
  • Auto-infers market suffix: .KS/.KQ (Korea), .T (Japan), .L (UK)
  • Last selected company persists across page refresh via local .app_prefs.json

Architecture: Hybrid AI + Quantitative Pipeline

graph TB
    classDef ui fill:#FF4B4B,stroke:#333,stroke-width:2px,color:#fff;
    classDef core fill:#4C51BF,stroke:#333,stroke-width:2px,color:#fff;
    classDef quant fill:#38B2AC,stroke:#333,stroke-width:2px,color:#fff;
    classDef qual fill:#DD6B20,stroke:#333,stroke-width:2px,color:#fff;
    classDef llm fill:#805AD5,stroke:#333,stroke-width:2px,color:#fff;

    User((🧑‍💻 User))

    subgraph Frontend ["🖥️ Frontend Interface"]
        UI[Streamlit Web Dashboard]:::ui
    end

    subgraph Input_Sync ["📷 Portfolio Sync (Bypassing API Limits)"]
        OCR[Gemini Vision OCR Pipeline]:::llm
    end

    subgraph Engine ["⚙️ Core Backend (Python)"]
        Core{Hybrid RAG Architecture <br> Token Cost -80%}:::core
    end

    subgraph Quant_Pipeline ["📊 Quantitative Pipeline (No LLM)"]
        YF[(yfinance API)]:::quant
        BS[(BeautifulSoup Web Scraper)]:::quant
    end

    subgraph Qual_Pipeline ["📝 Qualitative Pipeline (NLP)"]
        SEC[(SEC Filings: Item 7 MD&A)]:::qual
        LLM((Google Gemini LLM Engine)):::llm
    end

    User -- 1. Uploads Portfolio Screenshot --> OCR
    User -- 2. Enters Stock Ticker --> UI

    OCR -- Extracts Tickers & Syncs --> Core
    UI -- Sends Request --> Core
    Core -- Fetch Financials/Prices --> YF
    Core -- Parse Web Data --> BS
    YF -. Raw Data .-> Core
    BS -. Scraped Data .-> Core
    Core -- Fetch SEC Documents --> SEC
    SEC -- Raw Text (MD&A) --> LLM
    LLM -- Sentiment Analysis & Hidden Risks --> Core
    Core -- Aggregated Insights & Valuation --> UI
    UI -- Displays Final Dashboard --> User

Design principle: LLM for text only; Python for numbers. This eliminates hallucination risk on financial figures and keeps API costs to a single Gemini call per session.


Modular Code Architecture (v3.0)

The codebase was refactored from a 3,909-line monolith into 28 focused modules, each under 300 lines, following strict Separation of Concerns.

app.py                      # Thin orchestrator (~118 lines)
│
├── config/
│   ├── constants.py        # Company lists, sector maps, row maps, Damodaran baselines
│   └── theme.py            # Soft Navy CSS theme + header HTML
│
├── utils/
│   ├── prefs.py            # Local preference persistence (.app_prefs.json)
│   ├── formatting.py       # _safe_float, _format_shares_display, _na
│   ├── ticker.py           # get_global_ticker, infer_market_from_ticker
│   ├── dcf.py              # excel_style_dcf, dcf_10y_2stage, _damodaran_wacc_for_sector
│   ├── charts.py           # Sankey, Radar (Plotly) builders
│   └── ui_helpers.py       # Analyst consensus panel, DCF sensitivity table
│
├── data/
│   ├── sec_parser.py       # HTML text extraction, Item section finder (regex)
│   ├── sec_fetcher.py      # EDGAR API fetch (CIK lookup, submissions, HTML cache)
│   ├── sec_downloader.py   # 10-K download via sec-edgar-downloader, section extraction
│   ├── financials.py       # yahooquery + yfinance annual data, TTM construction
│   ├── fundamentals.py     # Sector/industry, 5-year trend, DCF inputs
│   ├── valuation.py        # Analyst consensus, DCF smart defaults, FCFF/FCFE
│   ├── ratios.py           # Comps, DuPont/Altman Z, quarterly momentum/ratios
│   ├── scores.py           # Sankey data, radar metrics, Piotroski, sector metrics
│   ├── scores_ai.py        # AI-derived Sankey/Piotroski/Radar from Gemini extraction
│   └── market.py           # Technical indicators, risk matrix, ticker bar, news RSS
│
├── ai/
│   ├── gemini_core.py      # Model init, retry logic, streaming, chunking, forensic audit
│   ├── gemini_sec.py       # SEC financials LLM, Item 7 strategy stream, Item 1A risk stream
│   └── gemini_insights.py  # MDA chunked insights, comparative analysis, industry outlook
│
└── views/
    ├── sidebar.py          # Company search, API keys, market selector
    ├── tab1_quant.py       # Financial health tables & charts
    ├── tab1_ai.py          # Deep-dive AI streaming analysis
    ├── tab1_filings.py     # SEC/DART native filing HTML viewer
    ├── tab2_dcf.py         # DCF valuation & FCFF/FCFE
    ├── tab3_comps.py       # Industry comps & AI outlook
    ├── tab4_news.py        # News RSS feed
    ├── tab5_markets.py     # FX rates & sector heatmap
    ├── tab6_crypto.py      # Cryptocurrency prices
    └── tab7_technical.py   # Technical indicators & risk matrix

Dependency direction (no circular imports):

app.py → views/ → data/ or ai/
utils/ ← importable from anywhere
data/ ↔ ai/ direct imports are forbidden

Tech Stack

Layer Technology
UI Framework Streamlit
AI / LLM Google Gemini 2.0 Flash (google-generativeai)
Financial Data yahooquery (primary), yfinance (fallback)
SEC Data sec-edgar-downloader, EDGAR public REST API
HTML Parsing BeautifulSoup4, lxml
Charts Plotly (Sankey, Scatterpolar Radar, Line)
Caching @st.cache_data (260 min TTL per function)

Technical Challenges & Solutions

Challenge 1 — 429 Resource Exhausted (LLM Token Overflow)

Problem: Full 10-K filings (200+ pages) caused Gemini 429 errors and rate limits.

Solution: Selective section extraction (Item 7 only → ~80% token reduction), HTML cleansing (BeautifulSoup + regex strips tags/whitespace), smart chunking with head+tail trim, and a 60-second retry decorator.

Challenge 2 — SEC EDGAR HTML Not Rendering

Problem: The filing viewer showed "원본 HTML을 가져오지 못했습니다" because the legacy code used directory.item from the index JSON (now deprecated) instead of the submissions API.

Solution: Rebuilt the EDGAR fetch chain — company_tickers.json → CIK lookup → submissions/CIK{cik}.jsonfilings.recent.primaryDocument[] → direct .htm download. Added streamlit.components.v1.html() for native in-app rendering with an injected CSS reset.

Challenge 3 — PyArrow Serialization in Streamlit

Problem: Mixed-type DataFrame columns (float + string in same column) caused ArrowInvalid errors when passing DataFrames through @st.cache_data.

Solution: Explicitly coerce all display strings before DataFrame construction; keep numeric columns as float, string columns as str throughout the pipeline.

Challenge 4 — 3,909-line Monolith Maintainability

Problem: A single app.py containing all business logic, UI rendering, and data fetching became unmanageable and untestable.

Solution: Full modular refactoring into 28 files across 5 packages (config, utils, data, ai, views). Dependency graph enforced no circular imports. All cache decorators and session state preserved identically. Each file kept under 300 lines.


Project Origin & Vision

The Origin — The Walk

The core idea came during a quiet walk while reflecting on the fragmentation of traditional equity research: narratives buried in 200-page filings, valuation models in separate spreadsheets, and comp tables scattered across different tools. What analysts 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 realisation crystallised into the design you see here: unified, cost-conscious, and built for the analyst who thinks in both words and numbers.

The Vision — Commercialisation

This repository is a functional MVP and technical portfolio piece. It proves the concept: hybrid architecture works, 10-K + DCF + comps can coexist in a single interface, and the unit economics (one Gemini call for narrative, free data for the rest) scale sustainably. The modular codebase is production-minded — each module under 300 lines, no circular imports, explicit error handling — and is the foundation on which a commercial product will be built.

Ultimate goal: Launch as a fully commercialised B2C/B2B SaaS serving retail investors who want institutional-grade structure without complexity, and finance professionals (equity analysts, portfolio managers, corporate development) who want to move from filing → insight → valuation in one flow.


Design Rationale (Interview Notes)

  • Why hybrid (LLM for text, Python for numbers)? LLMs hallucinate financial figures. Separating concerns — Gemini for narrative, yfinance for numbers — gives the best of both: nuanced qualitative analysis with numerically accurate, auditable quantitative data.

  • Why a 5-year 2-stage DCF instead of a simple Gordon Growth model? A single-stage model lets terminal value dominate the result, which overstates value for high-growth companies. The 2-stage model (Stage 1: projected FCF growth; Stage 2: terminal growth) is closer to how institutional DCF models are built and avoids absurd valuations.

  • Why integrate Damodaran's academic baselines? Slider defaults anchored to peer-reviewed data (Damodaran sector WACC, US ERP, 10Y risk-free rate) give users a credible starting point. The reference panel links to his data pages so users can verify and critique the assumptions.

  • Why modular architecture? Single-file Streamlit apps are fast to prototype but impossible to test, maintain, or extend. Separation of concerns — config, utils, data, ai, views — makes each component independently comprehensible, testable, and replaceable without touching the rest of the system.

  • Why yahooquery as primary (not yfinance)? yahooquery's bulk query API returns TTM-constructed financials with cleaner column names. yfinance is kept as a fallback for tickers yahooquery misses and for technical/historical price data.


Requirements

  • Python 3.9+
  • Google API Key (Gemini)
  • An email address for SEC EDGAR programmatic access
  • All Python dependencies in requirements.txt
  • Optional: .env with GOOGLE_API_KEY and SEC_EDGAR_EMAIL

How to Run

# 1. Navigate to project directory
cd "/path/to/your/FQDC Project"

# 2. Activate virtual environment
source venv/bin/activate           # Mac/Linux
# venv\Scripts\Activate.ps1       # Windows PowerShell

# 3. Install dependencies (first time or when requirements change)
pip install -r requirements.txt

# 4. Launch the app
streamlit run app.py --server.port 8501
# or: ./run.sh

Open http://localhost:8501 in your browser.

Set Google API Key and SEC EDGAR Email in the sidebar. Then search for any company by name (any language) and explore the seven tabs.


Update History (Changelog)

Date Update
2026-03-19 Modular refactoring (v3.0) + SEC filing viewer fix: (1) Architecture: 3,909-line app.py refactored into 28 focused modules across config/, utils/, data/, ai/, views/. Each file under 300 lines. Strict unidirectional dependency graph (no circular imports). All @st.cache_data TTLs and st.session_state keys preserved identically. (2) SEC Filing Viewer fixed: Rebuilt EDGAR fetch chain using submissions/CIK{cik}.jsonfilings.recent.primaryDocument[] (replaces deprecated directory.item lookup). Added filing type st.selectbox (10-K, 10-Q, 8-K, 20-F, 6-K) connected to backend dynamically. Native HTML rendered via streamlit.components.v1.html() with injected CSS reset. Errors surfaced explicitly with st.error(). (3) DART links restored for Korean-listed companies.
2026-02-18 Market Heatmap & FX charts: Sector heatmap with 5d/1mo data and per-ticker fallback (weekend/holiday robust). FX Momentum normalized 1Y line chart (GBP/USD, EUR/USD, USD/JPY, KRW). 10-K language toggle (한글/영문) via Gemini translation. plotly/yfinance added to requirements.
2026-02-17 DART, prefs, run script: DART fetch timeout 90s; DART report titles in English (cached). SEC & DART per-category iframe viewer. Last selected company persisted in .app_prefs.json (survives page refresh). Single run script run.sh at port 8501.
2025-02-15 Multi-currency portfolio & FX: Per-position currency (USD/GBP/EUR/KRW/JPY/CNY), fractional quantity, FX-adjusted returns. Gemini Vision AI screenshot import (extracts ticker, price, currency, quantity). App-wide get_currency_for_ticker, get_fx_rate, format_price_with_usd.
2025-02-14 Global company search: yahooquery search() replaces static dropdown. Search by name in any language; filters INDEX/MUTUALFUND; auto-infers .KS/.KQ/.T/.L suffix.
2025-02-13 Design Rationale & 10Y DCF: Design rationale section (undergrad automation mindset, 10Y 2-stage DCF, Damodaran integration). Wall Street Assumptions panel (analyst consensus + Damodaran baselines). Smart DCF defaults from Beta/CAPM.
2025-02-13 Robust data & comps redesign: Multi-step shares/debt/cash fallback (fast_info → info → balance). Top-down sector analysis with SECTORS dict and AI Industry Outlook (Gemini).
2025-02-12 Hybrid architecture: Item 7 only to Gemini; yfinance for all numbers. HTML cleansing pipeline (BeautifulSoup + regex).
2025-02-12 DuPont, Altman Z, Piotroski, sector KPIs, TTM fallback: Full quantitative financial health suite. Sector-specific metrics (Tech: Rule of 40; Retail: Inventory Turnover; Financials: ROE/ROA).
2025-02-12 Preference persistence: "Remember API key & email" checkbox; .app_prefs.json (gitignored).
2025-01-XX Initial release: SEC EDGAR 10-K download, Item 7/8 extraction, Gemini analysis, Streamlit UI.

License and Disclaimer

This project is built for learning, research, and portfolio demonstration. Comply with SEC EDGAR policy when accessing SEC data, and with Google's terms of service for the Gemini API. Nothing in this app constitutes investment advice.

S
Description
No description provided
Readme 1.4 MiB
Languages
Python 68%
TypeScript 31.5%
CSS 0.4%
Shell 0.1%