UNPKG

@pratiksha90/financial-data-extractors

Version:

Utilities for extracting financial data from various economic calendar websites

169 lines (168 loc) 7.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isBloombergCalendar = isBloombergCalendar; exports.isForexProsToolsCalendar = isForexProsToolsCalendar; exports.extractBloombergIframeUrl = extractBloombergIframeUrl; exports.parseForexProsToolsCalendar = parseForexProsToolsCalendar; exports.extractBloombergData = extractBloombergData; const BLOOMBERG_IFRAME_SOURCE = "https://econcal.forexprostools.com/?features=datepicker,timezone,country_importance,filters&calType=week"; /** * Check if the current page is Bloomberg calendar */ function isBloombergCalendar(url) { return url.includes('bloomberg.com/markets/economic-calendar'); } /** * Check if the current page is ForexProsTools calendar */ function isForexProsToolsCalendar(url) { return url.includes('econcal.forexprostools.com'); } /** * Extract Bloomberg calendar iframe URL */ function extractBloombergIframeUrl(options) { const { document } = options; const iframe = document.querySelector('iframe[title="Economic Calendar Content"]'); if (iframe) { const iframeUrl = iframe.getAttribute('src'); if (iframeUrl) { return iframeUrl; } } const fallbackIframe = document.querySelector('.iframeWrapper__db3b8d9ee8 iframe'); if (fallbackIframe) { const fallbackUrl = fallbackIframe.getAttribute('src'); if (fallbackUrl) { return fallbackUrl; } } // If we can't find the iframe, return the known URL return BLOOMBERG_IFRAME_SOURCE; } /** * Parse ForexProsTools calendar events */ function parseForexProsToolsCalendar(options) { const { document } = options; const events = []; try { // Find the calendar table section const calendarSection = document.querySelector('#ecEventsTable'); if (!calendarSection) { return []; } // Get all day sections const daySections = calendarSection.querySelectorAll('.day-section'); if (daySections.length === 0) { return []; } // Process each day section daySections.forEach(daySection => { var _a; // Get the date const dateHeader = daySection.querySelector('.dateRow h2.theDay'); const date = dateHeader ? ((_a = dateHeader.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '' : 'Unknown Date'; // Get all event items for this day const eventItems = daySection.querySelectorAll('li.item'); // Process each event item eventItems.forEach(item => { var _a, _b, _c, _d, _e, _f, _g; try { // Get the event button containing all the data const eventBtn = item.querySelector('button.calLine'); if (!eventBtn) return; // Extract event ID const eventId = eventBtn.id.replace('eventRowId_', ''); // Extract time const timeElement = eventBtn.querySelector('time.time'); const time = timeElement ? timeElement.getAttribute('datetime') || '' : ''; const displayTime = timeElement ? ((_a = timeElement.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '' : ''; // Extract currency const currencyElement = eventBtn.querySelector('.flagCur'); const currency = currencyElement ? ((_b = currencyElement.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || '' : ''; // Extract country const flagElement = currencyElement === null || currencyElement === void 0 ? void 0 : currencyElement.querySelector('.ceFlags'); const country = flagElement ? flagElement.getAttribute('title') || '' : ''; // Extract importance/sentiment const sentimentElement = eventBtn.querySelector('.sentiment'); const importance = sentimentElement ? sentimentElement.getAttribute('title') || '' : ''; // Extract event name const eventElement = eventBtn.querySelector('.event'); const eventName = eventElement ? ((_c = eventElement.textContent) === null || _c === void 0 ? void 0 : _c.trim()) || '' : ''; // Extract actual value const actualElement = eventBtn.querySelector('.act .event-' + eventId + '-actual'); const actual = actualElement ? ((_d = actualElement.textContent) === null || _d === void 0 ? void 0 : _d.trim()) || '' : ''; // Extract forecast value const forecastElement = eventBtn.querySelector('.fore .event-' + eventId + '-forecast'); const forecast = forecastElement ? ((_e = forecastElement.textContent) === null || _e === void 0 ? void 0 : _e.trim()) || '' : ''; // Extract previous value const previousElement = eventBtn.querySelector('.prev .event-' + eventId + '-previous'); const previous = previousElement ? ((_f = previousElement.textContent) === null || _f === void 0 ? void 0 : _f.trim()) || '' : ''; // Extract revised from info if available const revisedSpan = eventBtn.querySelector('#eventRevisedFromSpan_' + eventId); const revisedFrom = revisedSpan ? ((_g = revisedSpan.getAttribute('title')) === null || _g === void 0 ? void 0 : _g.replace('Revised From ', '')) || null : null; if (eventName) { // Add to events array events.push({ date: date, time: displayTime, country: country, currency: currency, event: eventName, impact: importance, actual: actual, forecast: forecast, previous: previous, revised: revisedFrom, id: eventId }); } } catch (error) { // Continue to next event even if one fails } }); }); return events; } catch (error) { return []; } } /** * Extract Bloomberg calendar data */ function extractBloombergData(options) { const { document } = options; const url = document.URL || ''; // If we're directly on the ForexProsTools page, extract events from current page if (isForexProsToolsCalendar(url)) { const events = parseForexProsToolsCalendar(options); return { metadata: { title: "Economic Calendar", source: url, extractedAt: new Date().toISOString(), totalEvents: events.length, note: "Data extracted directly from ForexProsTools economic calendar" }, events: events }; } // If we're on Bloomberg, get the iframe URL const iframeUrl = extractBloombergIframeUrl(options); // Since we found an iframe URL, return it return { metadata: { title: "Bloomberg Economic Calendar", source: url, iframeSource: iframeUrl, extractedAt: new Date().toISOString(), note: "Bloomberg loads calendar data from ForexProsTools iframe. Use the iframe URL directly for data extraction.", iframeUrl: iframeUrl }, events: [] }; }