@fin.cx/opendata 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ import type { IStockPrice } from './stockprice.js';
2
+ import type { IStockFundamentals } from './fundamentals.js';
3
+ /**
4
+ * Combined stock data with price and fundamentals
5
+ * All calculated metrics (market cap, P/E, P/B) are automatically included
6
+ */
7
+ export interface IStockData {
8
+ /** Stock ticker symbol */
9
+ ticker: string;
10
+ /** Price information */
11
+ price: IStockPrice;
12
+ /** Fundamental data (optional - may not be available for all stocks) */
13
+ fundamentals?: IStockFundamentals;
14
+ /** When this combined data was fetched */
15
+ fetchedAt: Date;
16
+ }
17
+ /**
18
+ * Configuration for StockDataService
19
+ */
20
+ export interface IStockDataServiceConfig {
21
+ /** Cache configuration */
22
+ cache?: {
23
+ /** TTL for price data (default: 24 hours) */
24
+ priceTTL?: number;
25
+ /** TTL for fundamentals data (default: 90 days) */
26
+ fundamentalsTTL?: number;
27
+ /** Max cache entries (default: 10000) */
28
+ maxEntries?: number;
29
+ };
30
+ /** Provider timeouts */
31
+ timeout?: {
32
+ /** Timeout for price providers (default: 10000ms) */
33
+ price?: number;
34
+ /** Timeout for fundamentals providers (default: 30000ms) */
35
+ fundamentals?: number;
36
+ };
37
+ }
38
+ /**
39
+ * Request type for getting complete stock data
40
+ */
41
+ export interface ICompleteStockDataRequest {
42
+ ticker: string;
43
+ /** Whether to include fundamentals (default: true) */
44
+ includeFundamentals?: boolean;
45
+ /** Whether to enrich fundamentals with price calculations (default: true) */
46
+ enrichFundamentals?: boolean;
47
+ }
48
+ /**
49
+ * Batch request for multiple stocks
50
+ */
51
+ export interface ICompleteStockDataBatchRequest {
52
+ tickers: string[];
53
+ /** Whether to include fundamentals (default: true) */
54
+ includeFundamentals?: boolean;
55
+ /** Whether to enrich fundamentals with price calculations (default: true) */
56
+ enrichFundamentals?: boolean;
57
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvY2tkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3RvY2tzL2ludGVyZmFjZXMvc3RvY2tkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,102 @@
1
+ import type { IFundamentalsProvider, IStockFundamentals, IFundamentalsRequest } from '../interfaces/fundamentals.js';
2
+ /**
3
+ * Configuration for SEC EDGAR provider
4
+ */
5
+ export interface ISecEdgarConfig {
6
+ userAgent: string;
7
+ cikCacheTTL?: number;
8
+ fundamentalsCacheTTL?: number;
9
+ timeout?: number;
10
+ }
11
+ /**
12
+ * SEC EDGAR Fundamental Data Provider
13
+ *
14
+ * Features:
15
+ * - Free public access (no API key required)
16
+ * - All US public companies
17
+ * - Financial data from 10-K/10-Q filings
18
+ * - US GAAP standardized metrics
19
+ * - Historical data back to ~2009
20
+ * - < 1 minute filing delay
21
+ *
22
+ * Documentation: https://www.sec.gov/edgar/sec-api-documentation
23
+ *
24
+ * Rate Limits:
25
+ * - 10 requests per second (enforced by SEC)
26
+ * - Requires User-Agent header in format: "Company Name Email"
27
+ *
28
+ * Data Sources:
29
+ * - Company Facts API: /api/xbrl/companyfacts/CIK##########.json
30
+ * - Ticker Lookup: /files/company_tickers.json
31
+ */
32
+ export declare class SecEdgarProvider implements IFundamentalsProvider {
33
+ name: string;
34
+ priority: number;
35
+ readonly requiresAuth = false;
36
+ readonly rateLimit: {
37
+ requestsPerMinute: number;
38
+ requestsPerDay: any;
39
+ };
40
+ private logger;
41
+ private baseUrl;
42
+ private tickersUrl;
43
+ private userAgent;
44
+ private config;
45
+ private cikCache;
46
+ private tickerListCache;
47
+ private rateLimiter;
48
+ constructor(config: ISecEdgarConfig);
49
+ /**
50
+ * Unified data fetching method
51
+ */
52
+ fetchData(request: IFundamentalsRequest): Promise<IStockFundamentals | IStockFundamentals[]>;
53
+ /**
54
+ * Fetch fundamental data for a single ticker
55
+ */
56
+ private fetchFundamentals;
57
+ /**
58
+ * Fetch fundamental data for multiple tickers
59
+ */
60
+ private fetchBatchFundamentals;
61
+ /**
62
+ * Get CIK (Central Index Key) for a ticker symbol
63
+ * Uses SEC's public ticker-to-CIK mapping file
64
+ */
65
+ private getCIK;
66
+ /**
67
+ * Fetch the SEC ticker-to-CIK mapping list
68
+ * Cached for 24 hours (list updates daily)
69
+ */
70
+ private fetchTickerList;
71
+ /**
72
+ * Fetch company facts from SEC EDGAR
73
+ */
74
+ private fetchCompanyFacts;
75
+ /**
76
+ * Parse SEC company facts into structured fundamental data
77
+ */
78
+ private parseCompanyFacts;
79
+ /**
80
+ * Get the latest value for a US GAAP metric
81
+ */
82
+ private getLatestValue;
83
+ /**
84
+ * Get metadata from the latest data point
85
+ */
86
+ private getLatestMetadata;
87
+ /**
88
+ * Check if SEC EDGAR API is available
89
+ */
90
+ isAvailable(): Promise<boolean>;
91
+ /**
92
+ * Get cache statistics
93
+ */
94
+ getCacheStats(): {
95
+ cikCacheSize: number;
96
+ hasTickerList: boolean;
97
+ };
98
+ /**
99
+ * Clear all caches
100
+ */
101
+ clearCache(): void;
102
+ }
@@ -0,0 +1,343 @@
1
+ import * as plugins from '../../plugins.js';
2
+ /**
3
+ * Rate limiter for SEC EDGAR API
4
+ * SEC requires: 10 requests per second maximum
5
+ */
6
+ class RateLimiter {
7
+ constructor() {
8
+ this.requestTimes = [];
9
+ this.maxRequestsPerSecond = 10;
10
+ }
11
+ async waitForSlot() {
12
+ const now = Date.now();
13
+ const oneSecondAgo = now - 1000;
14
+ // Remove requests older than 1 second
15
+ this.requestTimes = this.requestTimes.filter(time => time > oneSecondAgo);
16
+ // If we've hit the limit, wait
17
+ if (this.requestTimes.length >= this.maxRequestsPerSecond) {
18
+ const oldestRequest = this.requestTimes[0];
19
+ const waitTime = 1000 - (now - oldestRequest) + 10; // +10ms buffer
20
+ await plugins.smartdelay.delayFor(waitTime);
21
+ return this.waitForSlot(); // Recursively check again
22
+ }
23
+ // Record this request
24
+ this.requestTimes.push(now);
25
+ }
26
+ }
27
+ /**
28
+ * SEC EDGAR Fundamental Data Provider
29
+ *
30
+ * Features:
31
+ * - Free public access (no API key required)
32
+ * - All US public companies
33
+ * - Financial data from 10-K/10-Q filings
34
+ * - US GAAP standardized metrics
35
+ * - Historical data back to ~2009
36
+ * - < 1 minute filing delay
37
+ *
38
+ * Documentation: https://www.sec.gov/edgar/sec-api-documentation
39
+ *
40
+ * Rate Limits:
41
+ * - 10 requests per second (enforced by SEC)
42
+ * - Requires User-Agent header in format: "Company Name Email"
43
+ *
44
+ * Data Sources:
45
+ * - Company Facts API: /api/xbrl/companyfacts/CIK##########.json
46
+ * - Ticker Lookup: /files/company_tickers.json
47
+ */
48
+ export class SecEdgarProvider {
49
+ constructor(config) {
50
+ this.name = 'SEC EDGAR';
51
+ this.priority = 100; // High priority - free, authoritative, comprehensive
52
+ this.requiresAuth = false; // No API key needed!
53
+ this.rateLimit = {
54
+ requestsPerMinute: 600, // 10 requests/second = 600/minute
55
+ requestsPerDay: undefined // No daily limit
56
+ };
57
+ this.logger = console;
58
+ this.baseUrl = 'https://data.sec.gov/api/xbrl';
59
+ this.tickersUrl = 'https://www.sec.gov/files/company_tickers.json';
60
+ // Caching
61
+ this.cikCache = new Map();
62
+ this.tickerListCache = null;
63
+ // Rate limiting
64
+ this.rateLimiter = new RateLimiter();
65
+ // Validate User-Agent
66
+ if (!config.userAgent) {
67
+ throw new Error('User-Agent is required for SEC EDGAR provider (format: "Company Name Email")');
68
+ }
69
+ // Validate User-Agent format (must contain space and @ symbol)
70
+ if (!config.userAgent.includes(' ') || !config.userAgent.includes('@')) {
71
+ throw new Error('Invalid User-Agent format. Required: "Company Name Email" (e.g., "fin.cx info@fin.cx")');
72
+ }
73
+ this.userAgent = config.userAgent;
74
+ this.config = {
75
+ userAgent: config.userAgent,
76
+ cikCacheTTL: config.cikCacheTTL || 30 * 24 * 60 * 60 * 1000, // 30 days
77
+ fundamentalsCacheTTL: config.fundamentalsCacheTTL || 90 * 24 * 60 * 60 * 1000, // 90 days
78
+ timeout: config.timeout || 30000
79
+ };
80
+ }
81
+ /**
82
+ * Unified data fetching method
83
+ */
84
+ async fetchData(request) {
85
+ switch (request.type) {
86
+ case 'fundamentals-current':
87
+ return this.fetchFundamentals(request);
88
+ case 'fundamentals-batch':
89
+ return this.fetchBatchFundamentals(request);
90
+ default:
91
+ throw new Error(`Unsupported request type: ${request.type}`);
92
+ }
93
+ }
94
+ /**
95
+ * Fetch fundamental data for a single ticker
96
+ */
97
+ async fetchFundamentals(request) {
98
+ try {
99
+ // 1. Get CIK for ticker (with caching)
100
+ const cik = await this.getCIK(request.ticker);
101
+ // 2. Fetch company facts from SEC (with rate limiting)
102
+ const companyFacts = await this.fetchCompanyFacts(cik);
103
+ // 3. Parse facts into structured fundamental data
104
+ return this.parseCompanyFacts(request.ticker, cik, companyFacts);
105
+ }
106
+ catch (error) {
107
+ this.logger.error(`Failed to fetch fundamentals for ${request.ticker}:`, error);
108
+ throw new Error(`SEC EDGAR: Failed to fetch fundamentals for ${request.ticker}: ${error.message}`);
109
+ }
110
+ }
111
+ /**
112
+ * Fetch fundamental data for multiple tickers
113
+ */
114
+ async fetchBatchFundamentals(request) {
115
+ const results = [];
116
+ const errors = [];
117
+ for (const ticker of request.tickers) {
118
+ try {
119
+ const fundamentals = await this.fetchFundamentals({
120
+ type: 'fundamentals-current',
121
+ ticker
122
+ });
123
+ results.push(fundamentals);
124
+ }
125
+ catch (error) {
126
+ this.logger.warn(`Failed to fetch fundamentals for ${ticker}:`, error);
127
+ errors.push(`${ticker}: ${error.message}`);
128
+ // Continue with other tickers
129
+ }
130
+ }
131
+ if (results.length === 0) {
132
+ throw new Error(`Failed to fetch fundamentals for all tickers. Errors: ${errors.join(', ')}`);
133
+ }
134
+ return results;
135
+ }
136
+ /**
137
+ * Get CIK (Central Index Key) for a ticker symbol
138
+ * Uses SEC's public ticker-to-CIK mapping file
139
+ */
140
+ async getCIK(ticker) {
141
+ const tickerUpper = ticker.toUpperCase();
142
+ // Check cache first
143
+ const cached = this.cikCache.get(tickerUpper);
144
+ if (cached) {
145
+ const age = Date.now() - cached.timestamp.getTime();
146
+ if (age < this.config.cikCacheTTL) {
147
+ return cached.cik;
148
+ }
149
+ // Cache expired, remove it
150
+ this.cikCache.delete(tickerUpper);
151
+ }
152
+ // Fetch ticker list (with caching at list level)
153
+ const tickers = await this.fetchTickerList();
154
+ // Find ticker in list (case-insensitive)
155
+ const entry = Object.values(tickers).find((t) => t.ticker === tickerUpper);
156
+ if (!entry) {
157
+ throw new Error(`CIK not found for ticker ${ticker}`);
158
+ }
159
+ const cik = String(entry.cik_str);
160
+ // Cache the result
161
+ this.cikCache.set(tickerUpper, {
162
+ cik,
163
+ timestamp: new Date()
164
+ });
165
+ return cik;
166
+ }
167
+ /**
168
+ * Fetch the SEC ticker-to-CIK mapping list
169
+ * Cached for 24 hours (list updates daily)
170
+ */
171
+ async fetchTickerList() {
172
+ // Check cache
173
+ if (this.tickerListCache) {
174
+ const age = Date.now() - this.tickerListCache.timestamp.getTime();
175
+ if (age < 24 * 60 * 60 * 1000) { // 24 hours
176
+ return this.tickerListCache.data;
177
+ }
178
+ }
179
+ // Wait for rate limit slot
180
+ await this.rateLimiter.waitForSlot();
181
+ // Fetch from SEC
182
+ const response = await plugins.smartrequest.SmartRequest.create()
183
+ .url(this.tickersUrl)
184
+ .headers({
185
+ 'User-Agent': this.userAgent,
186
+ 'Accept': 'application/json'
187
+ })
188
+ .timeout(this.config.timeout)
189
+ .get();
190
+ const data = await response.json();
191
+ // Cache the list
192
+ this.tickerListCache = {
193
+ data,
194
+ timestamp: new Date()
195
+ };
196
+ return data;
197
+ }
198
+ /**
199
+ * Fetch company facts from SEC EDGAR
200
+ */
201
+ async fetchCompanyFacts(cik) {
202
+ // Pad CIK to 10 digits
203
+ const paddedCIK = cik.padStart(10, '0');
204
+ const url = `${this.baseUrl}/companyfacts/CIK${paddedCIK}.json`;
205
+ // Wait for rate limit slot
206
+ await this.rateLimiter.waitForSlot();
207
+ // Fetch from SEC
208
+ const response = await plugins.smartrequest.SmartRequest.create()
209
+ .url(url)
210
+ .headers({
211
+ 'User-Agent': this.userAgent,
212
+ 'Accept': 'application/json',
213
+ 'Accept-Encoding': 'gzip, deflate',
214
+ 'Host': 'data.sec.gov'
215
+ })
216
+ .timeout(this.config.timeout)
217
+ .get();
218
+ const data = await response.json();
219
+ // Validate response
220
+ if (!data || !data.facts) {
221
+ throw new Error('Invalid response from SEC EDGAR API');
222
+ }
223
+ return data;
224
+ }
225
+ /**
226
+ * Parse SEC company facts into structured fundamental data
227
+ */
228
+ parseCompanyFacts(ticker, cik, data) {
229
+ const usGaap = data.facts?.['us-gaap'];
230
+ if (!usGaap) {
231
+ throw new Error('No US GAAP data available');
232
+ }
233
+ // Extract latest values for key metrics
234
+ const fundamentals = {
235
+ ticker: ticker.toUpperCase(),
236
+ cik: cik,
237
+ companyName: data.entityName,
238
+ provider: this.name,
239
+ timestamp: new Date(),
240
+ fetchedAt: new Date(),
241
+ // Per-share metrics
242
+ earningsPerShareBasic: this.getLatestValue(usGaap, 'EarningsPerShareBasic'),
243
+ earningsPerShareDiluted: this.getLatestValue(usGaap, 'EarningsPerShareDiluted'),
244
+ sharesOutstanding: this.getLatestValue(usGaap, 'CommonStockSharesOutstanding'),
245
+ weightedAverageSharesOutstanding: this.getLatestValue(usGaap, 'WeightedAverageNumberOfSharesOutstandingBasic'),
246
+ // Income statement
247
+ revenue: this.getLatestValue(usGaap, 'Revenues') ||
248
+ this.getLatestValue(usGaap, 'RevenueFromContractWithCustomerExcludingAssessedTax'),
249
+ netIncome: this.getLatestValue(usGaap, 'NetIncomeLoss'),
250
+ operatingIncome: this.getLatestValue(usGaap, 'OperatingIncomeLoss'),
251
+ grossProfit: this.getLatestValue(usGaap, 'GrossProfit'),
252
+ costOfRevenue: this.getLatestValue(usGaap, 'CostOfRevenue'),
253
+ // Balance sheet
254
+ assets: this.getLatestValue(usGaap, 'Assets'),
255
+ liabilities: this.getLatestValue(usGaap, 'Liabilities'),
256
+ stockholdersEquity: this.getLatestValue(usGaap, 'StockholdersEquity'),
257
+ cash: this.getLatestValue(usGaap, 'CashAndCashEquivalentsAtCarryingValue'),
258
+ propertyPlantEquipment: this.getLatestValue(usGaap, 'PropertyPlantAndEquipmentNet'),
259
+ // Metadata (from latest available data point)
260
+ fiscalYear: this.getLatestMetadata(usGaap, 'EarningsPerShareDiluted')?.fy,
261
+ fiscalQuarter: this.getLatestMetadata(usGaap, 'EarningsPerShareDiluted')?.fp,
262
+ filingDate: this.getLatestMetadata(usGaap, 'EarningsPerShareDiluted')?.filed
263
+ ? new Date(this.getLatestMetadata(usGaap, 'EarningsPerShareDiluted').filed)
264
+ : undefined,
265
+ form: this.getLatestMetadata(usGaap, 'EarningsPerShareDiluted')?.form
266
+ };
267
+ return fundamentals;
268
+ }
269
+ /**
270
+ * Get the latest value for a US GAAP metric
271
+ */
272
+ getLatestValue(usGaap, metricName) {
273
+ const metric = usGaap[metricName];
274
+ if (!metric?.units) {
275
+ return undefined;
276
+ }
277
+ // Get the first unit type (USD, shares, etc.)
278
+ const unitType = Object.keys(metric.units)[0];
279
+ const values = metric.units[unitType];
280
+ if (!values || !Array.isArray(values) || values.length === 0) {
281
+ return undefined;
282
+ }
283
+ // Get the latest value (last in array)
284
+ const latest = values[values.length - 1];
285
+ return latest?.val;
286
+ }
287
+ /**
288
+ * Get metadata from the latest data point
289
+ */
290
+ getLatestMetadata(usGaap, metricName) {
291
+ const metric = usGaap[metricName];
292
+ if (!metric?.units) {
293
+ return undefined;
294
+ }
295
+ const unitType = Object.keys(metric.units)[0];
296
+ const values = metric.units[unitType];
297
+ if (!values || !Array.isArray(values) || values.length === 0) {
298
+ return undefined;
299
+ }
300
+ return values[values.length - 1];
301
+ }
302
+ /**
303
+ * Check if SEC EDGAR API is available
304
+ */
305
+ async isAvailable() {
306
+ try {
307
+ // Test with Apple's well-known CIK
308
+ const url = `${this.baseUrl}/companyfacts/CIK0000320193.json`;
309
+ const response = await plugins.smartrequest.SmartRequest.create()
310
+ .url(url)
311
+ .headers({
312
+ 'User-Agent': this.userAgent,
313
+ 'Accept': 'application/json'
314
+ })
315
+ .timeout(5000)
316
+ .get();
317
+ const data = await response.json();
318
+ return data && data.facts !== undefined;
319
+ }
320
+ catch (error) {
321
+ this.logger.warn('SEC EDGAR provider is not available:', error);
322
+ return false;
323
+ }
324
+ }
325
+ /**
326
+ * Get cache statistics
327
+ */
328
+ getCacheStats() {
329
+ return {
330
+ cikCacheSize: this.cikCache.size,
331
+ hasTickerList: this.tickerListCache !== null
332
+ };
333
+ }
334
+ /**
335
+ * Clear all caches
336
+ */
337
+ clearCache() {
338
+ this.cikCache.clear();
339
+ this.tickerListCache = null;
340
+ this.logger.log('SEC EDGAR cache cleared');
341
+ }
342
+ }
343
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuc2VjZWRnYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zdG9ja3MvcHJvdmlkZXJzL3Byb3ZpZGVyLnNlY2VkZ2FyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFtQjVDOzs7R0FHRztBQUNILE1BQU0sV0FBVztJQUFqQjtRQUNVLGlCQUFZLEdBQWEsRUFBRSxDQUFDO1FBQ25CLHlCQUFvQixHQUFHLEVBQUUsQ0FBQztJQW9CN0MsQ0FBQztJQWxCUSxLQUFLLENBQUMsV0FBVztRQUN0QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkIsTUFBTSxZQUFZLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQztRQUVoQyxzQ0FBc0M7UUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxZQUFZLENBQUMsQ0FBQztRQUUxRSwrQkFBK0I7UUFDL0IsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUMxRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxlQUFlO1lBQ25FLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDNUMsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQywwQkFBMEI7UUFDdkQsQ0FBQztRQUVELHNCQUFzQjtRQUN0QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fin.cx/opendata",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "private": false,
5
5
  "description": "A comprehensive TypeScript library for accessing business data and real-time financial information. Features include German company data management with MongoDB integration, JSONL bulk processing, automated Handelsregister interactions, and real-time stock market data from multiple providers.",
6
6
  "main": "dist_ts/index.js",