UNPKG

candlestick-chart-generator

Version:

A Node.js library for generating candlestick chart screenshots using financial data

96 lines (81 loc) 3.54 kB
const yahooFinance = require('yahoo-finance2').default; class DataFetcher { constructor() { // Suppress the deprecation notice for historical API yahooFinance.suppressNotices(['ripHistorical']); } /** * Fetch historical OHLC data for a given symbol and interval * @param {string} symbol - The ticker symbol (e.g., 'AAPL', 'BTC-USD', 'EURUSD=X') * @param {string} interval - The time interval ('1m', '1h', '1d', etc.) * @param {string|Date} startDate - Start date for historical data * @param {string|Date} endDate - End date for historical data * @returns {Promise<Array>} Array of OHLC data formatted for Lightweight Charts */ async fetchHistoricalData(symbol, interval, startDate, endDate) { try { // Convert interval to yahoo-finance2 format const yahooInterval = this._convertInterval(interval); // Prepare query options for chart API const queryOptions = { period1: startDate ? new Date(startDate) : new Date(Date.now() - 365 * 24 * 60 * 60 * 1000), // Default to 1 year ago period2: endDate ? new Date(endDate) : new Date(), // Default to now interval: yahooInterval }; // Use chart API instead of historical (which is deprecated) const result = await yahooFinance.chart(symbol, queryOptions); if (!result || !result.quotes || result.quotes.length === 0) { throw new Error(`No data found for symbol: ${symbol}`); } // Transform data to Lightweight Charts format return this._transformChartData(result.quotes); } catch (error) { throw new Error(`Failed to fetch data for ${symbol}: ${error.message}`); } } /** * Convert interval string to yahoo-finance2 format * @param {string} interval - Input interval (e.g., '1m', '1h', '1d') * @returns {string} Yahoo Finance interval format */ _convertInterval(interval) { const intervalMap = { '1m': '1m', '2m': '2m', '5m': '5m', '15m': '15m', '30m': '30m', '60m': '60m', '90m': '90m', '1h': '1h', '1d': '1d', '5d': '5d', '1wk': '1wk', '1mo': '1mo', '3mo': '3mo' }; const yahooInterval = intervalMap[interval]; if (!yahooInterval) { throw new Error(`Unsupported interval: ${interval}. Supported intervals: ${Object.keys(intervalMap).join(', ')}`); } return yahooInterval; } /** * Transform Yahoo Finance chart data to Lightweight Charts format * @param {Array} quotes - Raw quotes data from Yahoo Finance chart API * @returns {Array} Transformed data for Lightweight Charts */ _transformChartData(quotes) { return quotes .filter(quote => quote.open !== null && quote.high !== null && quote.low !== null && quote.close !== null) .map(quote => ({ time: Math.floor(quote.date.getTime() / 1000), // Convert to Unix timestamp open: parseFloat(quote.open), high: parseFloat(quote.high), low: parseFloat(quote.low), close: parseFloat(quote.close) })) .sort((a, b) => a.time - b.time); // Ensure chronological order } } module.exports = DataFetcher;