import { YahooClient } from '../market/YahooClient.js'; const NEWS_QUERIES = ['stock market today', 'earnings report', 'market news']; const MAX_STORIES = 15; const TICKER_REGEX = /^[A-Z]{1,6}$/; export class CatalystAnalyst { constructor({ logger } = {}) { this.client = new YahooClient(); this.logger = logger ?? { write: (msg) => process.stdout.write(msg) }; } async run() { this.logger.write('🔍 Fetching market news...'); const stories = await this._fetchNews(); const tickers = this._extractTickers(stories); this.logger.write(` ${stories.length} stories, ${tickers.length} tickers\n`); return { tickers, stories }; } async _fetchNews() { const seen = new Map(); for (const query of NEWS_QUERIES) { try { const { news = [] } = await this.client.yf.search(query, { newsCount: 8, quotesCount: 0 }); for (const s of news) { if (!seen.has(s.title)) { seen.set(s.title, { title: s.title, publisher: s.publisher, link: s.link, relatedTickers: s.relatedTickers ?? [], }); } } } catch { /* skip failed query */ } } return [...seen.values()].slice(0, MAX_STORIES); } _extractTickers(stories) { const tickers = new Set(); for (const { relatedTickers } of stories) { for (const t of relatedTickers) { const clean = t.split(':')[0].toUpperCase(); if (TICKER_REGEX.test(clean)) tickers.add(clean); } } return [...tickers]; } }