2023-11-14 16:15:11 +01:00
# @fin.cx/opendata
2025-10-11 15:21:57 +00:00
2025-11-01 11:59:23 +00:00
🚀 **Complete financial intelligence toolkit for TypeScript **
2023-11-14 16:15:11 +01:00
2025-11-01 11:59:23 +00:00
Access real-time stock prices, fundamental financial data, and comprehensive German company information - all through a single, unified API.
2025-10-31 12:12:29 +00:00
2025-07-13 15:08:19 +00:00
## Installation
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
```bash
npm install @fin .cx/opendata
# or
2025-10-11 15:21:57 +00:00
pnpm add @fin .cx/opendata
2025-04-09 08:40:23 +00:00
```
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
## Quick Start
2024-12-31 14:43:08 +01:00
2025-11-01 12:35:53 +00:00
### ✨ Unified Stock Data API (Recommended)
2024-12-31 14:43:08 +01:00
2025-11-01 12:35:53 +00:00
Get complete stock data with automatic enrichment - the elegant way:
2024-12-31 19:58:18 +01:00
2024-12-31 14:43:08 +01:00
```typescript
2025-11-01 12:35:53 +00:00
import { StockDataService, YahooFinanceProvider, SecEdgarProvider } from '@fin .cx/opendata';
2025-10-11 15:21:57 +00:00
2025-11-01 12:35:53 +00:00
// Initialize unified service
const stockData = new StockDataService();
// Register providers
stockData.registerPriceProvider(new YahooFinanceProvider());
stockData.registerFundamentalsProvider(new SecEdgarProvider({
userAgent: 'YourCompany youremail@example .com'
}));
// ✨ Get complete stock data with ONE method call
const apple = await stockData.getStockData('AAPL');
console.log({
company: apple.fundamentals.companyName, // "Apple Inc."
price: apple.price.price, // $270.37
marketCap: apple.fundamentals.marketCap, // $4.13T (auto-calculated!)
peRatio: apple.fundamentals.priceToEarnings, // 28.42 (auto-calculated!)
pbRatio: apple.fundamentals.priceToBook, // 45.12 (auto-calculated!)
eps: apple.fundamentals.earningsPerShareDiluted, // $6.13
revenue: apple.fundamentals.revenue // $385.6B
2025-10-11 15:21:57 +00:00
});
2024-12-31 14:43:08 +01:00
2025-11-01 12:35:53 +00:00
// Batch fetch with automatic enrichment
const stocks = await stockData.getBatchStockData(['AAPL', 'MSFT', 'GOOGL']);
2024-12-31 14:43:08 +01:00
2025-11-01 12:35:53 +00:00
stocks.forEach(stock => {
console.log(`${stock.ticker}: $${stock.price.price.toFixed(2)}, ` +
`P/E ${stock.fundamentals?.priceToEarnings?.toFixed(2)}` );
});
// Output:
// AAPL: $270.37, P/E 28.42
// MSFT: $425.50, P/E 34.21
// GOOGL: $142.15, P/E 25.63
```
**Why use the unified API?**
- ✅ **Single service ** for both prices and fundamentals
- ✅ **Automatic enrichment ** - Market cap, P/E, P/B calculated automatically
- ✅ **One method call ** - No manual `enrichWithPrice()` calls
- ✅ **Simplified code ** - Less boilerplate, more readable
- ✅ **Type-safe ** - Full TypeScript support
### 📈 Price-Only Data (Alternative)
If you only need prices without fundamentals:
2025-10-31 14:00:59 +00:00
2025-11-01 12:35:53 +00:00
```typescript
import { StockDataService, YahooFinanceProvider } from '@fin .cx/opendata';
const stockData = new StockDataService();
stockData.registerPriceProvider(new YahooFinanceProvider());
// Get just the price
const price = await stockData.getPrice('AAPL');
console.log(`${price.ticker}: $${price.price}` );
// Or use StockPriceService directly for more control
import { StockPriceService } from '@fin .cx/opendata';
const stockService = new StockPriceService({ ttl: 60000 });
stockService.register(new YahooFinanceProvider());
const apple = await stockService.getData({ type: 'current', ticker: 'AAPL' });
2025-11-01 11:59:23 +00:00
console.log(`${apple.companyFullName}: $${apple.price}` );
```
2024-12-31 14:43:08 +01:00
2025-11-02 16:34:24 +00:00
### 🪙 Cryptocurrency Prices
Get real-time crypto prices with the CoinGecko provider:
```typescript
import { StockPriceService, CoinGeckoProvider } from '@fin .cx/opendata';
const stockService = new StockPriceService({ ttl: 30000 });
// Optional: Pass API key for higher rate limits
// const provider = new CoinGeckoProvider('your-api-key');
const provider = new CoinGeckoProvider();
stockService.register(provider);
// Fetch single crypto price (using ticker symbol)
const btc = await stockService.getPrice({ ticker: 'BTC' });
console.log(`${btc.ticker}: $${btc.price.toLocaleString()}` );
console.log(`24h Change: ${btc.changePercent.toFixed(2)}%` );
console.log(`24h Volume: $${btc.volume?.toLocaleString()}` );
// Or use CoinGecko ID directly
const ethereum = await stockService.getPrice({ ticker: 'ethereum' });
// Batch fetch multiple cryptos
const cryptos = await stockService.getPrices({
tickers: ['BTC', 'ETH', 'USDT', 'BNB', 'SOL']
});
cryptos.forEach(crypto => {
console.log(`${crypto.ticker}: $${crypto.price.toFixed(2)} (${crypto.changePercent >= 0 ? '+' : ''}${crypto.changePercent.toFixed(2)}%)` );
});
// Historical crypto prices
const history = await stockService.getData({
type: 'historical',
ticker: 'BTC',
from: new Date('2025-01-01'),
to: new Date('2025-01-31')
});
// Intraday crypto prices (hourly)
const intraday = await stockService.getData({
type: 'intraday',
ticker: 'ETH',
interval: '1hour',
limit: 24 // Last 24 hours
});
```
2025-11-01 12:35:53 +00:00
### 💰 Fundamentals-Only Data (Alternative)
2025-11-01 11:59:23 +00:00
2025-11-01 12:35:53 +00:00
If you only need fundamentals without prices:
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
```typescript
2025-11-01 12:35:53 +00:00
import { StockDataService, SecEdgarProvider } from '@fin .cx/opendata';
2025-11-01 11:59:23 +00:00
2025-11-01 12:35:53 +00:00
const stockData = new StockDataService();
stockData.registerFundamentalsProvider(new SecEdgarProvider({
2025-11-01 11:59:23 +00:00
userAgent: 'YourCompany youremail@example .com'
2025-11-01 12:35:53 +00:00
}));
2025-11-01 11:59:23 +00:00
2025-11-01 12:35:53 +00:00
// Get just fundamentals
const fundamentals = await stockData.getFundamentals('AAPL');
2025-11-01 11:59:23 +00:00
console.log({
2025-11-01 12:35:53 +00:00
company: fundamentals.companyName,
eps: fundamentals.earningsPerShareDiluted,
revenue: fundamentals.revenue,
sharesOutstanding: fundamentals.sharesOutstanding
2025-07-13 15:08:19 +00:00
});
2025-10-31 15:05:48 +00:00
2025-11-01 12:35:53 +00:00
// Or use FundamentalsService directly
import { FundamentalsService } from '@fin .cx/opendata';
2025-10-31 15:05:48 +00:00
2025-11-01 12:35:53 +00:00
const fundamentalsService = new FundamentalsService();
fundamentalsService.register(new SecEdgarProvider({
userAgent: 'YourCompany youremail@example .com'
}));
const data = await fundamentalsService.getFundamentals('AAPL');
2024-12-31 14:43:08 +01:00
```
2025-11-01 11:59:23 +00:00
### 🏢 German Business Intelligence
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
Access comprehensive German company data:
2024-12-31 14:43:08 +01:00
2024-12-31 19:58:18 +01:00
```typescript
2025-04-09 06:26:52 +00:00
import { OpenData } from '@fin .cx/opendata';
2025-10-31 12:12:29 +00:00
import * as path from 'path';
2024-12-31 19:58:18 +01:00
2025-11-01 11:59:23 +00:00
// Configure directory paths
2025-10-31 12:12:29 +00:00
const openData = new OpenData({
nogitDir: path.join(process.cwd(), '.nogit'),
downloadDir: path.join(process.cwd(), '.nogit', 'downloads'),
germanBusinessDataDir: path.join(process.cwd(), '.nogit', 'germanbusinessdata')
});
2025-07-13 15:08:19 +00:00
await openData.start();
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
// Search for companies
const results = await openData.handelsregister.searchCompany("Siemens AG");
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
// Get detailed information with documents
const details = await openData.handelsregister.getSpecificCompany({
court: "Munich",
type: "HRB",
number: "6684"
});
2024-12-31 19:58:18 +01:00
```
2025-07-13 15:08:19 +00:00
## Features
2025-04-09 06:26:52 +00:00
2025-11-02 16:34:24 +00:00
### 📊 Stock & Crypto Market Module
2025-04-09 06:26:52 +00:00
2025-11-02 16:34:24 +00:00
- **Real-Time Prices** - Live and EOD prices from Yahoo Finance, Marketstack, and CoinGecko
- **Cryptocurrency Support** - 13M+ crypto tokens with 24/7 market data via CoinGecko
2025-11-01 11:59:23 +00:00
- **Company Names** - Automatic company name extraction (e.g., "Apple Inc (NASDAQ:AAPL)")
- **Historical Data** - Up to 15 years of daily EOD prices with pagination
- **OHLCV Data** - Open, High, Low, Close, Volume for technical analysis
- **Exchange Filtering** - Query specific exchanges via MIC codes (XNAS, XLON, XNYS)
2025-10-31 14:00:59 +00:00
- **Smart Caching** - Data-type aware TTL (historical cached forever, EOD 24h, live 30s)
- **Batch Operations** - Fetch 100+ symbols in one request
2025-11-01 11:59:23 +00:00
- **Type-Safe API** - Full TypeScript support with discriminated unions
- **Multi-Provider** - Automatic fallback between providers
### 💰 Fundamental Data Module
- **SEC EDGAR Integration** - FREE fundamental data directly from SEC filings
- **Comprehensive Metrics** - EPS, Revenue, Assets, Liabilities, Cash Flow, and more
- **All US Public Companies** - Complete coverage of SEC-registered companies
- **Historical Filings** - Data back to ~2009
- **CIK Lookup** - Automatic ticker-to-CIK mapping with smart caching
- **Calculated Ratios** - Market Cap, P/E, P/B ratios when combined with prices
- **No API Key Required** - Direct access to SEC's public API
- **Rate Limit Management** - Built-in 10 req/sec rate limiting
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
### 🇩🇪 German Business Intelligence
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
- **MongoDB Integration** - Scalable data storage for millions of records
- **Bulk JSONL Import** - Process multi-GB datasets efficiently
- **Handelsregister Automation** - Automated document retrieval
- **CRUD Operations** - Full database management with validation
- **Streaming Processing** - Handle large datasets without memory issues
2024-12-31 19:58:18 +01:00
2025-07-13 15:08:19 +00:00
## Advanced Examples
2025-04-09 06:26:52 +00:00
2025-11-01 12:35:53 +00:00
### Combined Market Analysis (Unified API)
2025-11-01 11:59:23 +00:00
2025-11-01 12:35:53 +00:00
Analyze multiple companies with automatic enrichment:
2025-11-01 11:59:23 +00:00
```typescript
2025-11-01 12:35:53 +00:00
import { StockDataService, YahooFinanceProvider, SecEdgarProvider } from '@fin .cx/opendata';
2025-11-01 11:59:23 +00:00
2025-11-01 12:35:53 +00:00
// Setup unified service
const stockData = new StockDataService();
stockData.registerPriceProvider(new YahooFinanceProvider());
stockData.registerFundamentalsProvider(new SecEdgarProvider({
2025-11-01 11:59:23 +00:00
userAgent: 'YourCompany youremail@example .com'
}));
2025-11-01 12:35:53 +00:00
// Analyze multiple companies with ONE call
2025-11-01 11:59:23 +00:00
const tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN'];
2025-11-01 12:35:53 +00:00
const stocks = await stockData.getBatchStockData(tickers);
// All metrics are automatically calculated!
stocks.forEach(stock => {
if (stock.fundamentals) {
console.log(`\n${stock.fundamentals.companyName} (${stock.ticker})` );
console.log(` Price: $${stock.price.price.toFixed(2)}` );
console.log(` Market Cap: $${(stock.fundamentals.marketCap! / 1e9).toFixed(2)}B` );
console.log(` P/E Ratio: ${stock.fundamentals.priceToEarnings!.toFixed(2)}` );
console.log(` Revenue: $${(stock.fundamentals.revenue! / 1e9).toFixed(2)}B` );
console.log(` EPS: $${stock.fundamentals.earningsPerShareDiluted!.toFixed(2)}` );
}
});
2025-11-01 11:59:23 +00:00
2025-11-01 12:35:53 +00:00
// Or analyze one-by-one with automatic enrichment
2025-11-01 11:59:23 +00:00
for (const ticker of tickers) {
2025-11-01 12:35:53 +00:00
const stock = await stockData.getStockData(ticker);
// Everything is already enriched - no manual calculations needed!
console.log(`${ticker}: P/E ${stock.fundamentals?.priceToEarnings?.toFixed(2)}` );
2025-11-01 11:59:23 +00:00
}
```
2025-10-31 14:00:59 +00:00
2025-11-01 12:35:53 +00:00
### Fundamental Data Screening
Screen stocks by financial metrics:
```typescript
// Fetch data for multiple tickers
const tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'META', 'NVDA', 'TSLA'];
const stocks = await stockData.getBatchStockData(tickers);
// Filter by criteria (all metrics auto-calculated!)
const valueStocks = stocks.filter(stock => {
const f = stock.fundamentals;
return f &&
f.priceToEarnings! < 30 && // P/E under 30
f.priceToBook! < 10 && // P/B under 10
f.revenue! > 100_000_000_000; // Revenue > $100B
});
console.log('\n💎 Value Stocks:');
valueStocks.forEach(stock => {
console.log(`${stock.ticker}: P/E ${stock.fundamentals!.priceToEarnings!.toFixed(2)}, ` +
`P/B ${stock.fundamentals!.priceToBook!.toFixed(2)}` );
});
```
2025-11-01 11:59:23 +00:00
### Historical Data Analysis
Fetch and analyze historical price trends:
2025-10-31 14:00:59 +00:00
```typescript
// Get 1 year of historical data
const history = await stockService.getData({
type: 'historical',
ticker: 'AAPL',
from: new Date('2024-01-01'),
to: new Date('2024-12-31'),
2025-11-01 11:59:23 +00:00
sort: 'DESC' // Newest first
2025-10-31 14:00:59 +00:00
});
// Calculate statistics
const prices = history.map(p => p.price);
const high52Week = Math.max(...prices);
const low52Week = Math.min(...prices);
const avgPrice = prices.reduce((a, b) => a + b) / prices.length;
console.log(`52-Week Analysis for AAPL:` );
2025-11-01 11:59:23 +00:00
console.log(` High: $${high52Week.toFixed(2)}` );
console.log(` Low: $${low52Week.toFixed(2)}` );
console.log(` Average: $${avgPrice.toFixed(2)}` );
console.log(` Days: ${history.length}` );
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
// Calculate Simple Moving Average
const calculateSMA = (data: IStockPrice[], period: number) => {
const sma: number[] = [];
for (let i = period - 1; i < data.length; i++) {
const sum = data.slice(i - period + 1, i + 1)
.reduce((acc, p) => acc + p.price, 0);
sma.push(sum / period);
}
return sma;
};
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
const sma20 = calculateSMA(history, 20);
const sma50 = calculateSMA(history, 50);
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
console.log(`\nMoving Averages:` );
console.log(` 20-day SMA: $${sma20[0].toFixed(2)}` );
console.log(` 50-day SMA: $${sma50[0].toFixed(2)}` );
2025-10-31 14:00:59 +00:00
```
2025-11-01 11:59:23 +00:00
### OHLCV Technical Analysis
2025-10-31 14:00:59 +00:00
Use OHLCV data for technical indicators:
```typescript
const history = await stockService.getData({
type: 'historical',
ticker: 'TSLA',
from: new Date('2024-11-01'),
to: new Date('2024-11-30')
});
// Calculate daily trading range
for (const day of history) {
2025-11-01 11:59:23 +00:00
const range = day.high! - day.low!;
const rangePercent = (range / day.low!) * 100;
2025-10-31 14:00:59 +00:00
console.log(`${day.timestamp.toISOString().split('T')[0]}:` );
console.log(` Open: $${day.open}` );
console.log(` High: $${day.high}` );
console.log(` Low: $${day.low}` );
console.log(` Close: $${day.price}` );
console.log(` Volume: ${day.volume?.toLocaleString()}` );
console.log(` Range: $${range.toFixed(2)} (${rangePercent.toFixed(2)}%)` );
}
```
2025-11-01 11:59:23 +00:00
### Fundamental Data Screening
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
Screen stocks based on fundamental metrics:
2025-10-31 14:00:59 +00:00
```typescript
2025-11-01 11:59:23 +00:00
const tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA', 'META', 'NVDA'];
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
// Fetch fundamentals for all tickers
const allFundamentals = await fundamentalsService.getBatchFundamentals(tickers);
2025-10-31 14:00:59 +00:00
2025-11-01 11:59:23 +00:00
// Get current prices
const prices = await stockService.getData({
type: 'batch',
tickers: tickers
2025-10-31 14:00:59 +00:00
});
2025-11-01 11:59:23 +00:00
// Create price map
const priceMap = new Map(prices.map(p => [p.ticker, p.price]));
// Enrich with prices
const enriched = await fundamentalsService.enrichBatchWithPrices(
allFundamentals,
priceMap
);
// Screen for value stocks (P/E < 25, P/B < 5)
const valueStocks = enriched.filter(f =>
f.priceToEarnings && f.priceToEarnings < 25 &&
f.priceToBook && f.priceToBook < 5
);
console.log('Value Stocks:');
valueStocks.forEach(stock => {
console.log(`\n${stock.companyName} (${stock.ticker})` );
console.log(` P/E Ratio: ${stock.priceToEarnings!.toFixed(2)}` );
console.log(` P/B Ratio: ${stock.priceToBook!.toFixed(2)}` );
console.log(` Market Cap: $${(stock.marketCap! / 1e9).toFixed(2)}B` );
});
2025-10-31 14:00:59 +00:00
```
2025-07-13 15:08:19 +00:00
### Market Dashboard
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
Create a comprehensive market overview:
2024-12-31 19:58:18 +01:00
```typescript
2025-07-13 15:08:19 +00:00
const indicators = [
{ ticker: 'AAPL', name: 'Apple' },
{ ticker: 'MSFT', name: 'Microsoft' },
2025-10-11 15:21:57 +00:00
{ ticker: 'GOOGL', name: 'Alphabet' },
{ ticker: 'AMZN', name: 'Amazon' },
{ ticker: 'TSLA', name: 'Tesla' }
2025-07-13 15:08:19 +00:00
];
2024-12-31 14:43:08 +01:00
2025-11-01 11:59:23 +00:00
const prices = await stockService.getData({
type: 'batch',
2025-10-11 15:21:57 +00:00
tickers: indicators.map(i => i.ticker)
2025-07-13 15:08:19 +00:00
});
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
// Display with color-coded changes
prices.forEach(price => {
const indicator = indicators.find(i => i.ticker === price.ticker);
const arrow = price.change >= 0 ? '↑' : '↓';
const color = price.change >= 0 ? '\x1b[32m' : '\x1b[31m';
2025-10-11 15:21:57 +00:00
2025-07-13 15:08:19 +00:00
console.log(
2025-11-01 11:59:23 +00:00
`${price.companyName!.padEnd(25)} $${price.price.toFixed(2).padStart(8)} ` +
2025-07-13 15:08:19 +00:00
`${color}${arrow} ${price.changePercent.toFixed(2)}%\x1b[0m`
);
});
2025-04-09 06:26:52 +00:00
```
2025-11-01 11:59:23 +00:00
### Exchange-Specific Trading
2025-10-11 15:21:57 +00:00
2025-11-01 11:59:23 +00:00
Compare prices across different exchanges:
2025-10-11 15:21:57 +00:00
```typescript
2025-11-01 11:59:23 +00:00
// Vodafone trades on both London and NYSE
const exchanges = [
{ mic: 'XLON', name: 'London Stock Exchange' },
{ mic: 'XNYS', name: 'New York Stock Exchange' }
];
for (const exchange of exchanges) {
try {
const price = await stockService.getData({
type: 'current',
ticker: 'VOD',
exchange: exchange.mic
});
console.log(`${exchange.name}:` );
console.log(` Price: ${price.price} ${price.currency}` );
console.log(` Volume: ${price.volume?.toLocaleString()}` );
console.log(` Exchange: ${price.exchangeName}` );
} catch (error) {
console.log(`${exchange.name}: Not available` );
}
}
2025-10-11 15:21:57 +00:00
```
2025-11-01 11:59:23 +00:00
## Configuration
2024-12-31 14:43:08 +01:00
2025-11-01 11:59:23 +00:00
### Stock Service Options
2024-12-31 14:43:08 +01:00
2024-12-31 19:58:18 +01:00
```typescript
2025-11-01 11:59:23 +00:00
const stockService = new StockPriceService({
ttl: 60000, // Default cache TTL in ms
maxEntries: 10000 // Max cached entries
2025-10-31 12:12:29 +00:00
});
2025-07-13 15:08:19 +00:00
2025-11-01 11:59:23 +00:00
// Marketstack - EOD data (requires API key)
stockService.register(new MarketstackProvider('YOUR_API_KEY'), {
enabled: true,
priority: 100,
timeout: 10000,
retryAttempts: 3,
retryDelay: 1000
2025-07-13 15:08:19 +00:00
});
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
// Yahoo Finance - Real-time data (no API key)
stockService.register(new YahooFinanceProvider(), {
enabled: true,
priority: 50
});
2025-04-09 06:26:52 +00:00
```
2025-11-01 11:59:23 +00:00
### Fundamentals Service Options
2025-04-09 06:26:52 +00:00
```typescript
2025-11-01 11:59:23 +00:00
const fundamentalsService = new FundamentalsService({
ttl: 90 * 24 * 60 * 60 * 1000, // 90 days (quarterly refresh)
maxEntries: 10000
2025-10-31 12:12:29 +00:00
});
2025-10-11 15:21:57 +00:00
2025-11-01 11:59:23 +00:00
// SEC EDGAR provider (FREE - no API key!)
fundamentalsService.register(new SecEdgarProvider({
userAgent: 'YourCompany youremail@example .com',
cikCacheTTL: 30 * 24 * 60 * 60 * 1000, // 30 days
fundamentalsCacheTTL: 90 * 24 * 60 * 60 * 1000, // 90 days
timeout: 30000
}));
2025-04-09 06:26:52 +00:00
```
2025-11-01 11:59:23 +00:00
### Directory Configuration (German Business Data)
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
All directory paths are mandatory when using German business data features:
2025-10-31 12:12:29 +00:00
```typescript
import { OpenData } from '@fin .cx/opendata';
import * as path from 'path';
2025-11-01 11:59:23 +00:00
// Development
2025-10-31 12:12:29 +00:00
const openData = new OpenData({
nogitDir: path.join(process.cwd(), '.nogit'),
downloadDir: path.join(process.cwd(), '.nogit', 'downloads'),
germanBusinessDataDir: path.join(process.cwd(), '.nogit', 'germanbusinessdata')
});
2025-11-01 11:59:23 +00:00
// Production
const openDataProd = new OpenData({
2025-10-31 12:12:29 +00:00
nogitDir: '/var/lib/myapp/data',
downloadDir: '/var/lib/myapp/data/downloads',
germanBusinessDataDir: '/var/lib/myapp/data/germanbusinessdata'
});
```
2025-11-01 11:59:23 +00:00
### Environment Variables
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
Set environment variables for API keys and database:
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
```env
2025-11-01 11:59:23 +00:00
# Marketstack API (for EOD stock data)
MARKETSTACK_COM_TOKEN=your_api_key_here
# MongoDB (for German business data)
2025-07-13 15:08:19 +00:00
MONGODB_URL=mongodb://localhost:27017
MONGODB_NAME=opendata
MONGODB_USER=myuser
MONGODB_PASS=mypass
2025-04-09 06:26:52 +00:00
```
2024-12-31 14:43:08 +01:00
2025-07-13 15:08:19 +00:00
## API Reference
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
### Stock Price Interfaces
2025-04-09 06:26:52 +00:00
```typescript
2025-07-13 15:08:19 +00:00
interface IStockPrice {
ticker: string;
price: number;
currency: string;
change: number;
changePercent: number;
previousClose: number;
timestamp: Date;
provider: string;
marketState: 'PRE' | 'REGULAR' | 'POST' | 'CLOSED';
exchange?: string;
exchangeName?: string;
2025-11-01 11:59:23 +00:00
// OHLCV data
volume?: number;
open?: number;
high?: number;
low?: number;
adjusted?: boolean;
dataType: 'eod' | 'intraday' | 'live';
fetchedAt: Date;
// Company identification
companyName?: string; // "Apple Inc"
companyFullName?: string; // "Apple Inc (NASDAQ:AAPL)"
}
```
### Fundamental Data Interfaces
```typescript
interface IStockFundamentals {
ticker: string;
cik: string;
companyName: string;
provider: string;
timestamp: Date;
fetchedAt: Date;
// Per-share metrics
earningsPerShareBasic?: number;
earningsPerShareDiluted?: number;
sharesOutstanding?: number;
// Income statement (annual USD)
revenue?: number;
netIncome?: number;
operatingIncome?: number;
grossProfit?: number;
// Balance sheet (annual USD)
assets?: number;
liabilities?: number;
stockholdersEquity?: number;
cash?: number;
propertyPlantEquipment?: number;
// Calculated metrics (requires price)
marketCap?: number; // price × sharesOutstanding
priceToEarnings?: number; // price / EPS
priceToBook?: number; // marketCap / stockholdersEquity
// Metadata
fiscalYear?: string;
fiscalQuarter?: string;
filingDate?: Date;
form?: '10-K' | '10-Q' | string;
2025-07-13 15:08:19 +00:00
}
2025-04-09 06:26:52 +00:00
```
2025-07-13 15:08:19 +00:00
### Key Methods
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
**StockPriceService**
2025-11-01 11:59:23 +00:00
- `getData(request)` - Unified method for all stock data (current, historical, batch)
- `getPrice(request)` - Convenience method for single current price
- `getPrices(request)` - Convenience method for batch current prices
2025-10-11 15:21:57 +00:00
- `register(provider, config)` - Add data provider with priority and retry config
- `checkProvidersHealth()` - Test all providers and return health status
- `getProviderStats()` - Get success/error statistics for each provider
2025-07-13 15:08:19 +00:00
- `clearCache()` - Clear price cache
2025-10-11 15:21:57 +00:00
- `setCacheTTL(ttl)` - Update cache TTL dynamically
2025-11-01 11:59:23 +00:00
**FundamentalsService**
- `getFundamentals(ticker)` - Get fundamental data for single ticker
- `getBatchFundamentals(tickers)` - Get fundamentals for multiple tickers
- `enrichWithPrice(fundamentals, price)` - Calculate market cap, P/E, P/B ratios
- `enrichBatchWithPrices(fundamentals, priceMap)` - Batch enrich with prices
- `register(provider, config)` - Add fundamentals provider
- `checkProvidersHealth()` - Test all providers
- `getProviderStats()` - Get success/error statistics
- `clearCache()` - Clear fundamentals cache
**SecEdgarProvider**
- ✅ FREE - No API key required
- ✅ All US public companies
- ✅ Comprehensive US GAAP financial metrics
- ✅ Historical data back to ~2009
- ✅ Direct access to SEC filings (10-K, 10-Q)
- ✅ Smart caching (CIK: 30 days, Fundamentals: 90 days)
- ✅ Rate limiting (10 requests/second)
- ℹ ️ Requires User-Agent header in format: "Company Name Email"
2025-10-11 15:21:57 +00:00
**MarketstackProvider**
2025-11-01 11:59:23 +00:00
- ✅ End-of-Day (EOD) stock prices
- ✅ 500,000+ tickers across 72+ exchanges worldwide
- ✅ Historical data with pagination
- ✅ Batch fetching support
- ✅ OHLCV data (Open, High, Low, Close, Volume)
- ✅ Company names included automatically
2025-10-11 15:21:57 +00:00
- ⚠️ Requires API key (free tier: 100 requests/month)
2025-11-01 11:59:23 +00:00
**YahooFinanceProvider**
- ✅ Real-time stock prices
- ✅ No API key required
- ✅ Global coverage
- ✅ Company names included
- ⚠️ Rate limits may apply
2025-04-09 06:26:52 +00:00
2025-11-02 16:34:24 +00:00
**CoinGeckoProvider**
- ✅ Cryptocurrency prices (Bitcoin, Ethereum, 13M+ tokens)
- ✅ Current, historical, and intraday data
- ✅ 24/7 market data (crypto never closes)
- ✅ OHLCV data with market cap and volume
- ✅ Supports both ticker symbols (BTC, ETH) and CoinGecko IDs (bitcoin, ethereum)
- ✅ 240+ networks, 1600+ exchanges
- ℹ ️ Optional API key (free tier: 30 requests/min, 10K/month)
2025-07-13 15:08:19 +00:00
**OpenData**
- `start()` - Initialize MongoDB connection
- `buildInitialDb()` - Import bulk data
- `CBusinessRecord` - Business record class
2025-11-01 11:59:23 +00:00
- `handelsregister` - German registry automation
2025-04-09 06:26:52 +00:00
2025-10-11 15:21:57 +00:00
## Provider Architecture
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
Add custom data providers easily:
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
```typescript
class MyCustomProvider implements IStockProvider {
name = 'My Provider';
2025-10-11 15:21:57 +00:00
priority = 50;
requiresAuth = true;
2025-11-01 11:59:23 +00:00
rateLimit = { requestsPerMinute: 60 };
async fetchData(request: IStockDataRequest): Promise<IStockPrice | IStockPrice[]> {
// Implement unified data fetching
switch (request.type) {
case 'current':
return this.fetchCurrentPrice(request);
case 'batch':
return this.fetchBatchPrices(request);
case 'historical':
return this.fetchHistoricalPrices(request);
default:
throw new Error(`Unsupported request type` );
}
2025-10-11 15:21:57 +00:00
}
async isAvailable(): Promise<boolean> {
// Health check
2025-11-01 11:59:23 +00:00
return true;
2025-10-11 15:21:57 +00:00
}
supportsMarket(market: string): boolean {
2025-11-01 11:59:23 +00:00
return ['US', 'UK', 'DE'].includes(market);
2025-10-11 15:21:57 +00:00
}
supportsTicker(ticker: string): boolean {
2025-11-01 11:59:23 +00:00
return /^[A-Z]{1,5}$/.test(ticker);
2025-10-11 15:21:57 +00:00
}
2025-07-13 15:08:19 +00:00
}
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
stockService.register(new MyCustomProvider());
2024-12-31 14:43:08 +01:00
```
2025-10-11 15:21:57 +00:00
## Performance
2025-11-01 11:59:23 +00:00
- **Batch Fetching**: Get 100+ prices in one API request
- **Smart Caching**: Data-type aware TTL (historical cached forever, EOD 24h, live 30s)
- **Rate Limit Management**: Automatic retry logic for API limits
- **Concurrent Processing**: Handle 1000+ records/second
2025-10-11 15:21:57 +00:00
- **Streaming**: Process GB-sized datasets without memory issues
2025-11-01 11:59:23 +00:00
- **Provider Fallback**: Automatic failover between data sources
2025-10-11 15:21:57 +00:00
2025-07-13 15:08:19 +00:00
## Testing
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
Run the comprehensive test suite:
2025-04-09 06:26:52 +00:00
2025-07-13 15:08:19 +00:00
```bash
2025-11-01 11:59:23 +00:00
pnpm test
2025-07-13 15:08:19 +00:00
```
2025-04-09 06:26:52 +00:00
2025-11-01 11:59:23 +00:00
Test specific modules:
2024-12-31 14:43:08 +01:00
2025-07-13 15:08:19 +00:00
```bash
2025-11-01 11:59:23 +00:00
# Stock price providers
pnpm tstest test/test.marketstack.node.ts --verbose
pnpm tstest test/test.stocks.ts --verbose
# Fundamental data
pnpm tstest test/test.secedgar.provider.node.ts --verbose
pnpm tstest test/test.fundamentals.service.node.ts --verbose
# German business data
pnpm tstest test/test.handelsregister.ts --verbose
2025-07-13 15:08:19 +00:00
```
2024-12-31 14:43:08 +01:00
2025-11-01 11:59:23 +00:00
## Getting API Keys
2024-12-31 19:58:18 +01:00
2025-11-01 11:59:23 +00:00
### Marketstack (EOD Stock Data)
1. Visit [marketstack.com ](https://marketstack.com )
2. Sign up for a free account (100 requests/month)
3. Get your API key from the dashboard
4. Set environment variable: `MARKETSTACK_COM_TOKEN=your_key_here`
### SEC EDGAR (Fundamental Data)
**No API key required!** SEC EDGAR is completely free and public. Just provide your company name and email in the User-Agent:
```typescript
new SecEdgarProvider({
userAgent: 'YourCompany youremail@example .com'
});
2025-10-11 15:21:57 +00:00
```
2025-01-04 13:40:50 +01:00
## License and Legal Information
2025-10-11 15:21:57 +00:00
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license ](license ) file within this repository.
2025-01-04 13:40:50 +01:00
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
### Company Information
2025-10-11 15:21:57 +00:00
Task Venture Capital GmbH
2025-01-04 13:40:50 +01:00
Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@task .vc.
2025-10-11 15:21:57 +00:00
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.