GrahamScreener
02Running

Running GrahamScreener

Dev Mode

npm run dev

Opens at http://localhost:3000 with hot-reload. All API routes and pages are available immediately.

Production Build

npm run build   # Compiles Next.js (takes ~60–90s)
npm start        # Serves production build on port 3000

To use a custom port:

npx next start -p 8080

Snapshot CLI

Batch-fetch fundamentals for the entire 200-ticker universe (or a subset) into the SQLite cache:

npm run snapshot                          # All 4 exchanges (200 tickers)
npm run snapshot ASX                      # ASX only (50 tickers)
npm run snapshot ASX US                   # ASX + US (100 tickers)
npm run snapshot -- --limit 20            # First 20 tickers only
npm run snapshot -- --tickers AAPL,CBA.AX # Specific tickers
npm run snapshot -- --watchlist-only       # Only watchlist tickers (~5)

Progress prints as . (success) or x (failed) per ticker, with a summary line every 10 tickers showing counts and elapsed time. A full 200-ticker run takes 6–10 minutes due to built-in rate-limit protection.

Rate-limit handling: Requests are processed sequentially (no parallelism) with 1.5–2.5s random jitter between each. On a 429 response, the script backs off exponentially (30s → 60s → 120s). After 3 consecutive 429s, it pauses for 5 minutes before resuming.

The snapshot cache is used by the screener (24h freshness) and stock detail page (6h freshness) to avoid hitting Yahoo on every page load.

Keyboard Shortcuts

ShortcutAction
Cmd+K / Ctrl+KOpen command palette (global ticker search + page jump)
g then dGo to Dashboard
g then sGo to Screener
g then wGo to Watchlist
g then pGo to Portfolio
g then aGo to Alerts

The g prefix is a Vim-style two-key sequence — press g, then press the target key within 700ms. These shortcuts are disabled when focus is inside an input or textarea.

URL Map

URLPageDescription
/DashboardHero search, feature cards, formula overview, snapshot panel
/stock/[ticker]Stock DetailPrice chart, fundamentals table, 4 valuation cards, MoS bar
/screenerScreenerExchange picker, Graham filters, sortable results table
/watchlistWatchlistAll watched tickers with thesis, targets, actions
/portfolioPortfolioTrade log, FIFO positions, P&L summary
/alertsAlertsPrice alert management (create, pause, delete)
/healthHealthDB size, cache freshness, snapshot status per exchange

API Routes

RouteMethodDescription
/api/yahoo/search?q=CBAGETSearch tickers via Yahoo Finance
/api/yahoo/quote?ticker=CBA.AXGETFetch fundamentals (cached 6h)
/api/yahoo/chart?ticker=CBA.AX&range=1yGETPrice chart data
/api/watchlistGETList all watchlist items
/api/watchlistPOSTAdd/update a watchlist item
/api/watchlist?ticker=CBA.AXDELETERemove from watchlist
/api/portfolioGETList all trades
/api/portfolioPOSTRecord a trade
/api/portfolio?id=1DELETEDelete a trade
/api/screenerGETGet the ticker universe
/api/screenerPOSTRun screener with filters
/api/snapshotGETSnapshot cache status
/api/snapshotPOSTTrigger snapshot refresh
/api/seedPOSTSeed watchlist with 5 samples
/api/healthGETSystem health: DB size, cache stats, snapshot status
/api/settingsGETCurrent valuation settings + defaults
/api/settingsPUTUpdate valuation settings (WACC, tax, yield)
/api/fxGETFX rates for portfolio currency conversion
/api/fxPUTUpdate base currency preference
/api/portfolio/importPOSTBulk-import trades from CSV
/api/alertsGETList all alerts
/api/alertsPOSTCreate a new alert
/api/alerts/[id]PATCHUpdate an alert (pause, edit)
/api/alerts/[id]DELETEDelete an alert
/api/cron/check-alertsGETCron: evaluate active alerts, send emails

Test Email CLI

Send a sample price alert email to verify your Resend setup:

RESEND_API_KEY=re_xxxxx ALERT_FROM_EMAIL=onboarding@resend.dev TEST_EMAIL=you@gmail.com npm run test-email

Environment Variables (Alerts)

VariableRequiredDescription
RESEND_API_KEYYes (for alerts)Resend API key
ALERT_FROM_EMAILNoSender address (default: alerts@grahamscreener.com)
CRON_SECRETYes (for cron)Vercel cron auth token
TEST_EMAILNoYour email for npm run test-email

Last updated: 2026-05-10 by Claude Cowork