/** * bin/screen.ts — Market Screener CLI * * Fetches today's catalyst tickers from Yahoo Finance news, * screens them under both Market-Adjusted and Fundamental lenses, * and saves a full HTML report. * * Usage: * npm start → Yahoo news → catalyst tickers → screen * npm start -- watch → default watchlist * npm start -- AAPL MSFT VOO → specific tickers */ import 'dotenv/config'; import { CatalystAnalyst } from '../server/analyst/CatalystAnalyst.js'; import { ScreenerEngine } from '../server/screener/ScreenerEngine.js'; import { HtmlReporter } from '../server/reporters/HtmlReporter.js'; const DEFAULT_WATCHLIST: string[] = [ 'PLTR', 'AAPL', 'MSFT', 'TSLA', 'O', 'VOO', 'QQQ', 'BND', 'LQD', 'TLT', 'IEF', 'SHY', 'GOVT', 'AGG', 'MUB', ]; async function main(): Promise { const args = process.argv.slice(2); let tickers: string[] = []; if (args.length > 0 && args[0] !== 'watch') { tickers = args.map((t) => t.toUpperCase()); console.log(`📋 Screening: ${tickers.join(', ')}\n`); } else if (args[0] === 'watch') { tickers = DEFAULT_WATCHLIST; console.log(`📋 Screening default watchlist (${tickers.length} tickers)\n`); } else { try { const { tickers: newsTickers, stories } = await new CatalystAnalyst().run(); if (newsTickers.length === 0) { console.warn("⚠ No tickers in today's news — using default watchlist\n"); tickers = DEFAULT_WATCHLIST; } else { tickers = newsTickers; console.log("\n📰 Stories driving today's screen:"); stories.slice(0, 5).forEach((s) => { const tags = s.relatedTickers.slice(0, 3).join(', '); console.log(` • ${s.title}${tags ? ` [${tags}]` : ''}`); }); console.log(`\n📋 Tickers: ${tickers.join(', ')}\n`); } } catch (err) { console.warn( `⚠ Catalyst analysis failed (${(err as Error).message}) — using default watchlist\n`, ); tickers = DEFAULT_WATCHLIST; } } try { const { STOCK, ETF, BOND, ERROR, marketContext } = await new ScreenerEngine().screenWithProgress(tickers); const reportPath = new HtmlReporter().generate( { STOCK, ETF, BOND, ERROR } as any, marketContext, ); console.log(`\n✅ Done — report saved to: ${reportPath}\n`); } catch (err) { console.error('Screener failed:', (err as Error).message); process.exit(1); } } main().catch(console.error);