73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import { YahooClient } from '../market/YahooClient.js';
|
|
import type { Logger } from '../types.js';
|
|
|
|
interface Story {
|
|
title: string;
|
|
publisher: string;
|
|
link: string;
|
|
relatedTickers: string[];
|
|
}
|
|
|
|
interface CatalystResult {
|
|
tickers: string[];
|
|
stories: Story[];
|
|
}
|
|
|
|
const NEWS_QUERIES = ['stock market today', 'earnings report', 'market news'];
|
|
const MAX_STORIES = 15;
|
|
const TICKER_REGEX = /^[A-Z]{1,6}$/;
|
|
|
|
export class CatalystAnalyst {
|
|
private client: YahooClient;
|
|
private logger: Pick<Logger, 'write'>;
|
|
|
|
constructor({ logger }: { logger?: Pick<Logger, 'write'> } = {}) {
|
|
this.client = new YahooClient();
|
|
this.logger = logger ?? { write: (msg: string) => process.stdout.write(msg) };
|
|
}
|
|
|
|
async run(): Promise<CatalystResult> {
|
|
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 };
|
|
}
|
|
|
|
private async _fetchNews(): Promise<Story[]> {
|
|
const seen = new Map<string, Story>();
|
|
for (const query of NEWS_QUERIES) {
|
|
try {
|
|
const { news = [] } = await (this.client as any).yf.search(query, {
|
|
newsCount: 8,
|
|
quotesCount: 0,
|
|
});
|
|
for (const s of news as any[]) {
|
|
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);
|
|
}
|
|
|
|
private _extractTickers(stories: Story[]): string[] {
|
|
const tickers = new Set<string>();
|
|
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];
|
|
}
|
|
}
|