import { ProviderConfig } from '../services/provider-registry.service'; import { getLogger } from '@stock-bot/logger'; const logger = getLogger('quotemedia-provider'); export const quotemediaProvider: ProviderConfig = { name: 'quotemedia', service: 'market-data', operations: { 'live-data': async (payload: { symbol: string; fields?: string[] }) => { logger.info('Fetching live data from QuoteMedia', { symbol: payload.symbol }); // Simulate QuoteMedia API call const mockData = { symbol: payload.symbol, price: Math.random() * 1000 + 100, volume: Math.floor(Math.random() * 1000000), change: (Math.random() - 0.5) * 20, changePercent: (Math.random() - 0.5) * 5, timestamp: new Date().toISOString(), source: 'quotemedia', fields: payload.fields || ['price', 'volume', 'change'] }; // Simulate network delay await new Promise(resolve => setTimeout(resolve, 100 + Math.random() * 200)); return mockData; }, 'historical-data': async (payload: { symbol: string; from: Date; to: Date; interval?: string; fields?: string[]; }) => { logger.info('Fetching historical data from QuoteMedia', { symbol: payload.symbol, from: payload.from, to: payload.to, interval: payload.interval || '1d' }); // Generate mock historical data const days = Math.ceil((payload.to.getTime() - payload.from.getTime()) / (1000 * 60 * 60 * 24)); const data = []; for (let i = 0; i < Math.min(days, 100); i++) { const date = new Date(payload.from.getTime() + i * 24 * 60 * 60 * 1000); data.push({ date: date.toISOString().split('T')[0], open: Math.random() * 1000 + 100, high: Math.random() * 1000 + 100, low: Math.random() * 1000 + 100, close: Math.random() * 1000 + 100, volume: Math.floor(Math.random() * 1000000), source: 'quotemedia' }); } // Simulate network delay await new Promise(resolve => setTimeout(resolve, 200 + Math.random() * 300)); return { symbol: payload.symbol, interval: payload.interval || '1d', data, source: 'quotemedia', totalRecords: data.length }; }, 'batch-quotes': async (payload: { symbols: string[]; fields?: string[] }) => { logger.info('Fetching batch quotes from QuoteMedia', { symbols: payload.symbols, count: payload.symbols.length }); const quotes = payload.symbols.map(symbol => ({ symbol, price: Math.random() * 1000 + 100, volume: Math.floor(Math.random() * 1000000), change: (Math.random() - 0.5) * 20, timestamp: new Date().toISOString(), source: 'quotemedia' })); // Simulate network delay await new Promise(resolve => setTimeout(resolve, 300 + Math.random() * 200)); return { quotes, source: 'quotemedia', timestamp: new Date().toISOString(), totalSymbols: payload.symbols.length }; }, 'company-profile': async (payload: { symbol: string }) => { logger.info('Fetching company profile from QuoteMedia', { symbol: payload.symbol }); // Simulate company profile data const profile = { symbol: payload.symbol, companyName: `${payload.symbol} Corporation`, sector: 'Technology', industry: 'Software', description: `${payload.symbol} is a leading technology company.`, marketCap: Math.floor(Math.random() * 1000000000000), employees: Math.floor(Math.random() * 100000), website: `https://www.${payload.symbol.toLowerCase()}.com`, source: 'quotemedia' }; await new Promise(resolve => setTimeout(resolve, 150 + Math.random() * 100)); return profile; }, 'options-chain': async (payload: { symbol: string; expiration?: string }) => { logger.info('Fetching options chain from QuoteMedia', { symbol: payload.symbol, expiration: payload.expiration }); // Generate mock options data const strikes = Array.from({ length: 20 }, (_, i) => 100 + i * 5); const calls = strikes.map(strike => ({ strike, bid: Math.random() * 10, ask: Math.random() * 10 + 0.5, volume: Math.floor(Math.random() * 1000), openInterest: Math.floor(Math.random() * 5000) })); const puts = strikes.map(strike => ({ strike, bid: Math.random() * 10, ask: Math.random() * 10 + 0.5, volume: Math.floor(Math.random() * 1000), openInterest: Math.floor(Math.random() * 5000) })); await new Promise(resolve => setTimeout(resolve, 400 + Math.random() * 300)); return { symbol: payload.symbol, expiration: payload.expiration || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], calls, puts, source: 'quotemedia' }; } }, scheduledJobs: [ // { // type: 'quotemedia-premium-refresh', // operation: 'batch-quotes', // payload: { symbols: ['AAPL', 'GOOGL', 'MSFT'] }, // cronPattern: '*/2 * * * *', // Every 2 minutes // priority: 7, // description: 'Refresh premium quotes with detailed market data' // }, // { // type: 'quotemedia-options-update', // operation: 'options-chain', // payload: { symbol: 'SPY' }, // cronPattern: '*/10 * * * *', // Every 10 minutes // priority: 5, // description: 'Update options chain data for SPY ETF' // }, // { // type: 'quotemedia-profiles', // operation: 'company-profile', // payload: { symbol: 'AAPL' }, // cronPattern: '0 9 * * 1-5', // Weekdays at 9 AM // priority: 3, // description: 'Update company profile data' // } ] };