UNPKG

@fin.cx/opendata

Version:

A comprehensive TypeScript library for accessing business data and real-time financial information. Features include German company data management with MongoDB integration, JSONL bulk processing, automated Handelsregister interactions, and real-time stoc

169 lines 14.7 kB
import * as plugins from '../../plugins.js'; export class YahooFinanceProvider { config; name = 'Yahoo Finance'; priority = 100; requiresAuth = false; rateLimit = { requestsPerMinute: 100, // Conservative estimate requestsPerDay: undefined }; logger = console; baseUrl = 'https://query1.finance.yahoo.com'; userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; constructor(config) { this.config = config; } /** * Unified data fetching method */ async fetchData(request) { switch (request.type) { case 'current': return this.fetchCurrentPrice(request); case 'batch': return this.fetchBatchCurrentPrices(request); case 'historical': throw new Error('Yahoo Finance provider does not support historical data. Use Marketstack provider instead.'); case 'intraday': throw new Error('Yahoo Finance provider does not support intraday data yet. Use Marketstack provider instead.'); default: throw new Error(`Unsupported request type: ${request.type}`); } } /** * Fetch current price for a single ticker */ async fetchCurrentPrice(request) { try { const url = `${this.baseUrl}/v8/finance/chart/${request.ticker}`; const response = await plugins.smartrequest.SmartRequest.create() .url(url) .headers({ 'User-Agent': this.userAgent }) .timeout(this.config?.timeout || 10000) .get(); const responseData = await response.json(); if (!responseData?.chart?.result?.[0]) { throw new Error(`No data found for ticker ${request.ticker}`); } const data = responseData.chart.result[0]; const meta = data.meta; if (!meta.regularMarketPrice) { throw new Error(`No price data available for ${request.ticker}`); } const stockPrice = { ticker: request.ticker.toUpperCase(), price: meta.regularMarketPrice, currency: meta.currency || 'USD', change: meta.regularMarketPrice - meta.previousClose, changePercent: ((meta.regularMarketPrice - meta.previousClose) / meta.previousClose) * 100, previousClose: meta.previousClose, timestamp: new Date(meta.regularMarketTime * 1000), provider: this.name, marketState: this.determineMarketState(meta), exchange: meta.exchange, exchangeName: meta.exchangeName, dataType: 'live', // Yahoo provides real-time/near real-time data fetchedAt: new Date() }; return stockPrice; } catch (error) { console.error(`Failed to fetch price for ${request.ticker}:`, error); throw new Error(`Yahoo Finance: Failed to fetch price for ${request.ticker}: ${plugins.getErrorMessage(error)}`); } } /** * Fetch batch current prices */ async fetchBatchCurrentPrices(request) { try { const symbols = request.tickers.join(','); const url = `${this.baseUrl}/v8/finance/spark?symbols=${symbols}&range=1d&interval=5m`; const response = await plugins.smartrequest.SmartRequest.create() .url(url) .headers({ 'User-Agent': this.userAgent }) .timeout(this.config?.timeout || 15000) .get(); const responseData = await response.json(); const prices = []; for (const [ticker, data] of Object.entries(responseData)) { if (!data || typeof data !== 'object') continue; const sparkData = data; if (!sparkData.previousClose || !sparkData.close?.length) { console.warn(`Incomplete data for ${ticker}, skipping`); continue; } const currentPrice = sparkData.close[sparkData.close.length - 1]; const timestamp = sparkData.timestamp?.[sparkData.timestamp.length - 1]; prices.push({ ticker: ticker.toUpperCase(), price: currentPrice, currency: sparkData.currency || 'USD', change: currentPrice - sparkData.previousClose, changePercent: ((currentPrice - sparkData.previousClose) / sparkData.previousClose) * 100, previousClose: sparkData.previousClose, timestamp: timestamp ? new Date(timestamp * 1000) : new Date(), provider: this.name, marketState: sparkData.marketState || 'REGULAR', exchange: sparkData.exchange, exchangeName: sparkData.exchangeName, dataType: 'live', // Yahoo provides real-time/near real-time data fetchedAt: new Date() }); } if (prices.length === 0) { throw new Error('No valid price data received from batch request'); } return prices; } catch (error) { console.error(`Failed to fetch batch prices:`, error); throw new Error(`Yahoo Finance: Failed to fetch batch prices: ${plugins.getErrorMessage(error)}`); } } async isAvailable() { try { // Test with a well-known ticker await this.fetchData({ type: 'current', ticker: 'AAPL' }); return true; } catch (error) { console.warn('Yahoo Finance provider is not available:', error); return false; } } supportsMarket(market) { // Yahoo Finance supports most major markets const supportedMarkets = ['US', 'UK', 'DE', 'FR', 'JP', 'CN', 'HK', 'AU', 'CA']; return supportedMarkets.includes(market.toUpperCase()); } supportsTicker(ticker) { // Basic validation - Yahoo supports most tickers return /^[A-Z0-9\.\-]{1,10}$/.test(ticker.toUpperCase()); } determineMarketState(meta) { const marketState = meta.marketState?.toUpperCase(); switch (marketState) { case 'PRE': return 'PRE'; case 'POST': return 'POST'; case 'REGULAR': return 'REGULAR'; default: // Check if market is currently open based on timestamps const now = Date.now() / 1000; const regularMarketTime = meta.regularMarketTime; const timeDiff = now - regularMarketTime; // If last update was more than 1 hour ago, market is likely closed return timeDiff > 3600 ? 'CLOSED' : 'REGULAR'; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIueWFob28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zdG9ja3MvcHJvdmlkZXJzL3Byb3ZpZGVyLnlhaG9vLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFTNUMsTUFBTSxPQUFPLG9CQUFvQjtJQWFYO0lBWmIsSUFBSSxHQUFHLGVBQWUsQ0FBQztJQUN2QixRQUFRLEdBQUcsR0FBRyxDQUFDO0lBQ04sWUFBWSxHQUFHLEtBQUssQ0FBQztJQUNyQixTQUFTLEdBQUc7UUFDMUIsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLHdCQUF3QjtRQUNoRCxjQUFjLEVBQUUsU0FBUztLQUMxQixDQUFDO0lBRU0sTUFBTSxHQUFHLE9BQU8sQ0FBQztJQUNqQixPQUFPLEdBQUcsa0NBQWtDLENBQUM7SUFDN0MsU0FBUyxHQUFHLGlIQUFpSCxDQUFDO0lBRXRJLFlBQW9CLE1BQXdCO1FBQXhCLFdBQU0sR0FBTixNQUFNLENBQWtCO0lBQUcsQ0FBQztJQUVoRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBMEI7UUFDL0MsUUFBUSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDckIsS0FBSyxTQUFTO2dCQUNaLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3pDLEtBQUssT0FBTztnQkFDVixPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxLQUFLLFlBQVk7Z0JBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyw0RkFBNEYsQ0FBQyxDQUFDO1lBQ2hILEtBQUssVUFBVTtnQkFDYixNQUFNLElBQUksS0FBSyxDQUFDLDhGQUE4RixDQUFDLENBQUM7WUFDbEg7Z0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBOEIsT0FBZSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUUs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