About This Dashboard

How Buy-Son works under the hood

What This Is

Buy-Son is a serverless stock-evaluation dashboard built around a "value investing" lens — it pulls multi-year price history, company fundamentals, and full balance sheets for any US-listed ticker and renders them as interactive Plotly charts in your browser.

Nothing is precomputed. When you select a ticker, a request goes out to AWS, which then queries third-party data sources live and returns a single JSON payload. The charts are rendered client-side, so panning, zooming, and tooltips are instant once data arrives.

Architecture at a Glance

1. DNS lookup 2. HTTPS (static) 2a. static files (cached) 3. HTTPS (/api/*) 4. invoke / JSON response 5a. prices + info 5b. 10-K filings 5c. tickers (read / write) DNS Lookup Route 53 (S3/static) AWS DNS (API Gateway) Your Browser HTML / CSS / JS + Plotly.js CloudFront CDN HTTPS + edge caching API Gateway HTTP API, /api/* S3 Bucket Static frontend files AWS Lambda Python 3.11, ARM64 yfinance Yahoo Finance API SEC EDGAR data.sec.gov DynamoDB Saved ticker list
Client AWS edge / routing Compute Storage External data

Every line is bidirectional — requests go out, responses return the same way. DNS lookups happen once at page load (Route 53 resolves the custom domain to CloudFront; AWS-managed DNS resolves the API Gateway domain). API calls bypass CloudFront entirely, so Lambda responses travel back as: Lambda → API Gateway → Browser.

What Happens When You Click "Add Symbol & Run"

  1. The browser sends an HTTPS request to /api/stock/{ticker} with your selected start and end years.
  2. The request goes directly to API Gateway, not through CloudFront — the API Gateway URL is baked into config.js at deploy time. API Gateway then invokes the Lambda function. (Static files like HTML, CSS, and JS take a separate path: browser → CloudFront → S3, edge-cached, and never reach Lambda.)
  3. Lambda fans out to two external sources in parallel: yfinance (Yahoo Finance) for daily OHLC prices and current company info, and SEC EDGAR for 10+ years of annual financial statements and balance sheets pulled directly from SEC filings.
  4. Lambda computes 50-day and 200-day moving averages on the price series, normalizes fields across the two providers, and merges everything into a single JSON response.
  5. The browser receives the payload and hands it to Plotly.js, which renders five interactive charts: price + moving averages, volume, financial timeline, company info panel, and a balance sheet (bar chart + sunburst).
  6. Saved tickers in the dropdown come from a separate /api/tickers call that reads a single record out of DynamoDB.

Where the Computation Happens

Almost all of the heavy lifting happens in two places:

The dashboard intentionally does not store historical price data. Every chart you see was fetched live from the source within the last few seconds.

Where the Data Comes From

Data Source Notes
Daily prices (OHLC + volume) Yahoo Finance via yfinance Adjusted for splits and dividends
Moving averages (50-day, 200-day) Computed in Lambda Rolling mean over the price series
Company info, market cap, P/E ratios Yahoo Finance via yfinance Trailing + forward P/E, EBITDA, debt
Annual financial statements (10+ years) SEC EDGAR (data.sec.gov) Pulled directly from 10-K filings
Balance sheets SEC EDGAR Detailed line items for sunburst chart
Saved ticker dropdown DynamoDB Single record keyed by PK = "TICKERS"

Tech Stack

Layer Tools
Frontend Vanilla HTML / CSS / JavaScript, Plotly.js
Backend runtime Python 3.11 on AWS Lambda (ARM64 / Graviton)
Data libraries yfinance, requests (SEC EDGAR), pandas, numpy
API layer AWS API Gateway (HTTP API)
Storage Amazon DynamoDB (on-demand), Amazon S3
CDN / DNS / TLS CloudFront, Route 53, AWS Certificate Manager
Infrastructure as code AWS CDK (Python) — three stacks: Storage, Api, Frontend
Testing pytest, moto (DynamoDB mocking), ruff, mypy

Hosting & Cost

The entire stack runs comfortably within AWS free-tier limits at the dashboard's expected usage (single-digit requests per day). Estimated cost: ~$0/month, with ECR image storage being the only meaningful charge after free-tier expiration (~$0.02/month for the ~200 MB Lambda container image).

Because the architecture is serverless, there are no servers to keep running between requests — Lambda spins up on demand and tears down when idle.

Source Code

Everything that powers this site is open source: github.com/JackVance/stock-eval-dashboard