47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import YahooFinance from 'yahoo-finance2';
|
|
import type { YahooNewsItem, YahooSearchOptions, YahooFinanceLib } from '../types';
|
|
import { YAHOO_MODULES } from '../config/constants';
|
|
|
|
export class YahooFinanceClient {
|
|
private lib: YahooFinanceLib;
|
|
|
|
constructor() {
|
|
this.lib = new (YahooFinance as unknown as new (_opts: object) => YahooFinanceLib)({
|
|
suppressNotices: ['yahooSurvey'],
|
|
});
|
|
}
|
|
|
|
/** Normalise ticker before hitting Yahoo: BRK.B → BRK-B */
|
|
private static normalise(ticker: string): string {
|
|
return ticker.toUpperCase().replace(/\./g, '-');
|
|
}
|
|
|
|
async fetchSummary(ticker: string, retries = 3, backoff = 1000): Promise<any> {
|
|
const normalised = YahooFinanceClient.normalise(ticker);
|
|
for (let attempt = 0; attempt < retries; attempt++) {
|
|
try {
|
|
return await this.lib.quoteSummary(normalised, { modules: YAHOO_MODULES });
|
|
} catch (error) {
|
|
if (attempt === retries - 1) throw error;
|
|
await new Promise<void>((resolve) => setTimeout(resolve, backoff * (attempt + 1)));
|
|
}
|
|
}
|
|
}
|
|
|
|
async fetchCalendarEvents(ticker: string): Promise<any | null> {
|
|
try {
|
|
const result = await this.lib.quoteSummary(YahooFinanceClient.normalise(ticker), {
|
|
modules: ['calendarEvents'],
|
|
});
|
|
return result.calendarEvents ?? null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async search(query: string, opts: YahooSearchOptions = {}): Promise<YahooNewsItem[]> {
|
|
const { news = [] } = await this.lib.search(query, opts);
|
|
return news;
|
|
}
|
|
}
|