89 lines
3.7 KiB
Markdown
89 lines
3.7 KiB
Markdown
# 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 |