Files
market_screener/bin/screen.ts
T
2026-06-06 22:55:43 -04:00

85 lines
2.5 KiB
TypeScript

/**
* 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<void> {
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);