Files
market_screener/ui
2026-06-04 22:44:50 -04:00
..
2026-06-04 22:44:50 -04:00
2026-06-04 15:49:49 -04:00
2026-06-04 01:36:28 -04:00
2026-06-04 22:44:50 -04:00
2026-06-04 01:36:28 -04:00
2026-06-04 01:36:28 -04:00
2026-06-04 22:44:50 -04:00
2026-06-04 01:36:28 -04:00

Market Screener UI

SvelteKit 5 dashboard for the Market Screener API. Provides an interactive interface for screening stocks, ETFs, and bonds — and tracking your portfolio with live hold/sell/add advice.


Quick Start

This UI requires the Market Screener API running on port 3000.

# Recommended: start both from the API repo
cd ../market_screener
npm run dev          # starts API (:3000) + this UI (:5173) together

# Or start the UI independently
npm install
npm run dev          # http://localhost:5173

Pages

Screener (/)

  • Enter any tickers (comma or space separated) and click Screen
  • Click 📰 Catalysts to load today's news-driven tickers and screen them automatically (one click)
  • Market context strip shows live benchmarks: 10Y yield, VIX, S&P 500, P/E ratios, rate regime
  • Signal Summary table ranks all assets by signal strength
  • Drill-down tables for Stocks, ETFs, and Bonds with Mkt-Adjusted / Graham tab toggle
  • Ticker column stays pinned while scrolling wide tables

Portfolio (/portfolio)

  • Reads portfolio.json from the API server
  • Shows total value, cost basis, and unrealised G/L
  • Per-holding advice: Hold & Add, 🟡 Reduce, 🔴 Sell
  • If SimpleFIN is configured: net worth, account balances, 30-day spending breakdown

Signals Explained

Signal Meaning
Strong Buy Passes both Market-Adjusted AND Fundamental gates
Momentum Passes market-adjusted, holds fundamentally
⚠️ Speculation Passes market-adjusted, fails fundamental — priced for perfection
🔄 Neutral Hold territory in one or both lenses
Avoid Fails both gates

The Mkt-Adjusted tab uses gates derived from live market data (e.g. S&P P/E × 1.5 for the P/E gate). The Graham tab uses strict historical value-investing gates (P/E < 15×, PEG < 1.0).


Tech Stack

Layer Choice
Framework SvelteKit 2 + Svelte 5
Build tool Vite 6
Adapter @sveltejs/adapter-auto
Rendering Client-side only (SSR disabled)
API Proxied via Vite dev server → Fastify on :3000

Project Structure

src/
  app.html             HTML shell
  app.css              Global reset + dark theme base
  routes/
    +layout.js         ssr = false
    +layout.svelte     Nav bar
    +page.svelte       Screener page
    portfolio/
      +page.js         load() → fetches /api/finance/portfolio
      +page.svelte     Portfolio + SimpleFIN page
  lib/
    api.js             All API fetch functions
    SignalBadge.svelte Signal pill component
    MarketContext.svelte Benchmark strip component

vite.config.js         /api proxy → localhost:3000
svelte.config.js       SvelteKit config

Configuration

API URL

In vite.config.js, the Vite dev server proxies /api/* to http://localhost:3000. To point at a different API host, update the proxy target there.

For production, configure your reverse proxy (nginx, Caddy, etc.) to route /api/* to the Fastify server.

CORS

The Fastify API allows http://localhost:5173 by default. If you deploy the UI to a different origin, set CLIENT_ORIGIN in the API's .env:

CLIENT_ORIGIN=https://your-deployed-ui.example.com

Development Notes

  • Uses Svelte 5 runes: $state, $derived, $derived.by, $props
  • onclick={handler} not on:click — Svelte 5 syntax
  • Page data loaded via +page.js load() function, not onMount
  • Global CSS lives in src/app.css — no :global() in component <style> blocks
  • asset.displayMetrics (plain object from API) — never call getDisplayMetrics() in the browser