# OpenData Project Hints ## Stocks Module ### Overview The stocks module provides real-time stock price data and cryptocurrency prices through various provider implementations. Currently supports Yahoo Finance, Marketstack, and CoinGecko with an extensible architecture for additional providers. ### Architecture - **Provider Pattern**: Each stock data source implements the `IStockProvider` interface - **Service Registry**: `StockPriceService` manages providers with priority-based selection - **Caching**: Built-in cache with configurable TTL to reduce API calls - **Fallback Logic**: Automatic failover between providers if one fails ### Yahoo Finance Provider Notes - Uses public API endpoints (no authentication required) - Two main endpoints: - `/v8/finance/chart/{ticker}` - Single ticker with full data - `/v8/finance/spark?symbols={tickers}` - Multiple tickers with basic data - Response data is in `response.body` when using smartrequest - Requires User-Agent header to avoid rate limiting ### Usage Example ```typescript import { StockPriceService, YahooFinanceProvider } from '@fin.cx/opendata'; const stockService = new StockPriceService({ ttl: 60000 }); const yahooProvider = new YahooFinanceProvider(); stockService.register(yahooProvider); const price = await stockService.getPrice({ ticker: 'AAPL' }); console.log(`${price.ticker}: $${price.price}`); ``` ### CoinGecko Provider Notes - Cryptocurrency price provider supporting 13M+ tokens - Three main endpoints: - `/simple/price` - Current prices with market data (batch supported) - `/coins/{id}/market_chart` - Historical and intraday prices with OHLCV - `/coins/list` - Complete coin list for ticker-to-ID mapping - **Rate Limiting**: - Free tier: 5-15 calls/minute (no registration) - Demo plan: 30 calls/minute, 10,000/month (free with registration) - Custom rate limiter tracks requests per minute - **Ticker Resolution**: - Accepts both ticker symbols (BTC, ETH) and CoinGecko IDs (bitcoin, ethereum) - Lazy-loads coin list on first ticker resolution - Caches coin mappings for 24 hours - IDs with hyphens (wrapped-bitcoin) assumed to be CoinGecko IDs - **24/7 Markets**: Crypto markets always return `marketState: 'REGULAR'` - **Optional API Key**: Pass key to constructor for higher rate limits - Demo plan: `x-cg-demo-api-key` header - Paid plans: `x-cg-pro-api-key` header - **Data Granularity**: - Historical: Daily data for date ranges - Intraday: Hourly data only (1-90 days based on `days` param) - Current: Real-time prices with 24h change and volume ### Usage Example (Crypto) ```typescript import { StockPriceService, CoinGeckoProvider } from '@fin.cx/opendata'; const stockService = new StockPriceService({ ttl: 30000 }); const coingeckoProvider = new CoinGeckoProvider(); // or new CoinGeckoProvider('api-key') stockService.register(coingeckoProvider); // Using ticker symbol const btc = await stockService.getPrice({ ticker: 'BTC' }); console.log(`${btc.ticker}: $${btc.price}`); // Using CoinGecko ID const ethereum = await stockService.getPrice({ ticker: 'ethereum' }); // Batch fetch const cryptos = await stockService.getPrices({ tickers: ['BTC', 'ETH', 'USDT'] }); ``` ### Testing - Tests use real API calls (be mindful of rate limits) - Mock invalid ticker 'INVALID_TICKER_XYZ' for error testing - Clear cache between tests to ensure fresh data - The spark endpoint may return fewer results than requested - CoinGecko tests may take longer due to rate limiting (wait between requests) ### Future Providers To add a new provider: 1. Create `ts/stocks/providers/provider.{name}.ts` 2. Implement the `IStockProvider` interface 3. Register with `StockPriceService` 4. No changes needed to existing code