@fin.cx/opendata 3.0.0 → 3.1.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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/opendata',
6
- version: '3.0.0',
6
+ version: '3.1.0',
7
7
  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.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHVTQUF1UztDQUNyVCxDQUFBIn0=
@@ -0,0 +1,104 @@
1
+ import type { IFundamentalsProvider, IFundamentalsProviderConfig, IFundamentalsProviderRegistry, IStockFundamentals, IFundamentalsRequest } from './interfaces/fundamentals.js';
2
+ /**
3
+ * Service for managing fundamental data providers and caching
4
+ * Parallel to StockPriceService but for fundamental data instead of prices
5
+ */
6
+ export declare class FundamentalsService implements IFundamentalsProviderRegistry {
7
+ private providers;
8
+ private cache;
9
+ private logger;
10
+ private cacheConfig;
11
+ constructor(cacheConfig?: {
12
+ ttl?: number;
13
+ maxEntries?: number;
14
+ });
15
+ /**
16
+ * Register a fundamentals provider
17
+ */
18
+ register(provider: IFundamentalsProvider, config?: IFundamentalsProviderConfig): void;
19
+ /**
20
+ * Unregister a provider
21
+ */
22
+ unregister(providerName: string): void;
23
+ /**
24
+ * Get a specific provider by name
25
+ */
26
+ getProvider(name: string): IFundamentalsProvider | undefined;
27
+ /**
28
+ * Get all registered providers
29
+ */
30
+ getAllProviders(): IFundamentalsProvider[];
31
+ /**
32
+ * Get enabled providers sorted by priority
33
+ */
34
+ getEnabledProviders(): IFundamentalsProvider[];
35
+ /**
36
+ * Get fundamental data for a single ticker
37
+ */
38
+ getFundamentals(ticker: string): Promise<IStockFundamentals>;
39
+ /**
40
+ * Get fundamental data for multiple tickers
41
+ */
42
+ getBatchFundamentals(tickers: string[]): Promise<IStockFundamentals[]>;
43
+ /**
44
+ * Unified data fetching method
45
+ */
46
+ getData(request: IFundamentalsRequest): Promise<IStockFundamentals | IStockFundamentals[]>;
47
+ /**
48
+ * Enrich fundamentals with calculated metrics using current price
49
+ */
50
+ enrichWithPrice(fundamentals: IStockFundamentals, price: number): Promise<IStockFundamentals>;
51
+ /**
52
+ * Enrich batch fundamentals with prices
53
+ */
54
+ enrichBatchWithPrices(fundamentalsList: IStockFundamentals[], priceMap: Map<string, number>): Promise<IStockFundamentals[]>;
55
+ /**
56
+ * Check health of all providers
57
+ */
58
+ checkProvidersHealth(): Promise<Map<string, boolean>>;
59
+ /**
60
+ * Get provider statistics
61
+ */
62
+ getProviderStats(): Map<string, {
63
+ successCount: number;
64
+ errorCount: number;
65
+ lastError?: string;
66
+ lastErrorTime?: Date;
67
+ }>;
68
+ /**
69
+ * Clear all cached data
70
+ */
71
+ clearCache(): void;
72
+ /**
73
+ * Set cache TTL
74
+ */
75
+ setCacheTTL(ttl: number): void;
76
+ /**
77
+ * Get cache statistics
78
+ */
79
+ getCacheStats(): {
80
+ size: number;
81
+ maxEntries: number;
82
+ ttl: number;
83
+ };
84
+ /**
85
+ * Fetch with retry logic
86
+ */
87
+ private fetchWithRetry;
88
+ /**
89
+ * Generate cache key for request
90
+ */
91
+ private getCacheKey;
92
+ /**
93
+ * Get from cache if not expired
94
+ */
95
+ private getFromCache;
96
+ /**
97
+ * Add to cache with TTL
98
+ */
99
+ private addToCache;
100
+ /**
101
+ * Get human-readable request description
102
+ */
103
+ private getRequestDescription;
104
+ }
@@ -0,0 +1,298 @@
1
+ import * as plugins from '../plugins.js';
2
+ /**
3
+ * Service for managing fundamental data providers and caching
4
+ * Parallel to StockPriceService but for fundamental data instead of prices
5
+ */
6
+ export class FundamentalsService {
7
+ constructor(cacheConfig) {
8
+ this.providers = new Map();
9
+ this.cache = new Map();
10
+ this.logger = console;
11
+ this.cacheConfig = {
12
+ ttl: 90 * 24 * 60 * 60 * 1000, // 90 days default (fundamentals change quarterly)
13
+ maxEntries: 10000
14
+ };
15
+ if (cacheConfig) {
16
+ this.cacheConfig = { ...this.cacheConfig, ...cacheConfig };
17
+ }
18
+ }
19
+ /**
20
+ * Register a fundamentals provider
21
+ */
22
+ register(provider, config) {
23
+ const defaultConfig = {
24
+ enabled: true,
25
+ priority: provider.priority,
26
+ timeout: 30000, // Longer timeout for fundamental data
27
+ retryAttempts: 2,
28
+ retryDelay: 1000,
29
+ cacheTTL: this.cacheConfig.ttl
30
+ };
31
+ const mergedConfig = { ...defaultConfig, ...config };
32
+ this.providers.set(provider.name, {
33
+ provider,
34
+ config: mergedConfig,
35
+ successCount: 0,
36
+ errorCount: 0
37
+ });
38
+ console.log(`Registered fundamentals provider: ${provider.name}`);
39
+ }
40
+ /**
41
+ * Unregister a provider
42
+ */
43
+ unregister(providerName) {
44
+ this.providers.delete(providerName);
45
+ console.log(`Unregistered fundamentals provider: ${providerName}`);
46
+ }
47
+ /**
48
+ * Get a specific provider by name
49
+ */
50
+ getProvider(name) {
51
+ return this.providers.get(name)?.provider;
52
+ }
53
+ /**
54
+ * Get all registered providers
55
+ */
56
+ getAllProviders() {
57
+ return Array.from(this.providers.values()).map(entry => entry.provider);
58
+ }
59
+ /**
60
+ * Get enabled providers sorted by priority
61
+ */
62
+ getEnabledProviders() {
63
+ return Array.from(this.providers.values())
64
+ .filter(entry => entry.config.enabled)
65
+ .sort((a, b) => (b.config.priority || 0) - (a.config.priority || 0))
66
+ .map(entry => entry.provider);
67
+ }
68
+ /**
69
+ * Get fundamental data for a single ticker
70
+ */
71
+ async getFundamentals(ticker) {
72
+ const result = await this.getData({
73
+ type: 'fundamentals-current',
74
+ ticker
75
+ });
76
+ return result;
77
+ }
78
+ /**
79
+ * Get fundamental data for multiple tickers
80
+ */
81
+ async getBatchFundamentals(tickers) {
82
+ const result = await this.getData({
83
+ type: 'fundamentals-batch',
84
+ tickers
85
+ });
86
+ return result;
87
+ }
88
+ /**
89
+ * Unified data fetching method
90
+ */
91
+ async getData(request) {
92
+ const cacheKey = this.getCacheKey(request);
93
+ const cached = this.getFromCache(cacheKey);
94
+ if (cached) {
95
+ console.log(`Cache hit for ${this.getRequestDescription(request)}`);
96
+ return cached;
97
+ }
98
+ const providers = this.getEnabledProviders();
99
+ if (providers.length === 0) {
100
+ throw new Error('No fundamentals providers available');
101
+ }
102
+ let lastError;
103
+ for (const provider of providers) {
104
+ const entry = this.providers.get(provider.name);
105
+ try {
106
+ const result = await this.fetchWithRetry(() => provider.fetchData(request), entry.config);
107
+ entry.successCount++;
108
+ // Use provider-specific cache TTL or default
109
+ const ttl = entry.config.cacheTTL || this.cacheConfig.ttl;
110
+ this.addToCache(cacheKey, result, ttl);
111
+ console.log(`Successfully fetched ${this.getRequestDescription(request)} from ${provider.name}`);
112
+ return result;
113
+ }
114
+ catch (error) {
115
+ entry.errorCount++;
116
+ entry.lastError = error;
117
+ entry.lastErrorTime = new Date();
118
+ lastError = error;
119
+ console.warn(`Provider ${provider.name} failed for ${this.getRequestDescription(request)}: ${error.message}`);
120
+ }
121
+ }
122
+ throw new Error(`Failed to fetch ${this.getRequestDescription(request)} from all providers. Last error: ${lastError?.message}`);
123
+ }
124
+ /**
125
+ * Enrich fundamentals with calculated metrics using current price
126
+ */
127
+ async enrichWithPrice(fundamentals, price) {
128
+ const enriched = { ...fundamentals };
129
+ // Calculate market cap: price × shares outstanding
130
+ if (fundamentals.sharesOutstanding) {
131
+ enriched.marketCap = price * fundamentals.sharesOutstanding;
132
+ }
133
+ // Calculate P/E ratio: price / EPS
134
+ if (fundamentals.earningsPerShareDiluted && fundamentals.earningsPerShareDiluted > 0) {
135
+ enriched.priceToEarnings = price / fundamentals.earningsPerShareDiluted;
136
+ }
137
+ // Calculate price-to-book: market cap / stockholders equity
138
+ if (enriched.marketCap && fundamentals.stockholdersEquity && fundamentals.stockholdersEquity > 0) {
139
+ enriched.priceToBook = enriched.marketCap / fundamentals.stockholdersEquity;
140
+ }
141
+ return enriched;
142
+ }
143
+ /**
144
+ * Enrich batch fundamentals with prices
145
+ */
146
+ async enrichBatchWithPrices(fundamentalsList, priceMap) {
147
+ return Promise.all(fundamentalsList.map(fundamentals => {
148
+ const price = priceMap.get(fundamentals.ticker);
149
+ if (price) {
150
+ return this.enrichWithPrice(fundamentals, price);
151
+ }
152
+ return Promise.resolve(fundamentals);
153
+ }));
154
+ }
155
+ /**
156
+ * Check health of all providers
157
+ */
158
+ async checkProvidersHealth() {
159
+ const health = new Map();
160
+ for (const [name, entry] of this.providers) {
161
+ if (!entry.config.enabled) {
162
+ health.set(name, false);
163
+ continue;
164
+ }
165
+ try {
166
+ const isAvailable = await entry.provider.isAvailable();
167
+ health.set(name, isAvailable);
168
+ }
169
+ catch (error) {
170
+ health.set(name, false);
171
+ console.error(`Health check failed for ${name}:`, error);
172
+ }
173
+ }
174
+ return health;
175
+ }
176
+ /**
177
+ * Get provider statistics
178
+ */
179
+ getProviderStats() {
180
+ const stats = new Map();
181
+ for (const [name, entry] of this.providers) {
182
+ stats.set(name, {
183
+ successCount: entry.successCount,
184
+ errorCount: entry.errorCount,
185
+ lastError: entry.lastError?.message,
186
+ lastErrorTime: entry.lastErrorTime
187
+ });
188
+ }
189
+ return stats;
190
+ }
191
+ /**
192
+ * Clear all cached data
193
+ */
194
+ clearCache() {
195
+ this.cache.clear();
196
+ console.log('Fundamentals cache cleared');
197
+ }
198
+ /**
199
+ * Set cache TTL
200
+ */
201
+ setCacheTTL(ttl) {
202
+ this.cacheConfig.ttl = ttl;
203
+ console.log(`Fundamentals cache TTL set to ${ttl}ms`);
204
+ }
205
+ /**
206
+ * Get cache statistics
207
+ */
208
+ getCacheStats() {
209
+ return {
210
+ size: this.cache.size,
211
+ maxEntries: this.cacheConfig.maxEntries,
212
+ ttl: this.cacheConfig.ttl
213
+ };
214
+ }
215
+ /**
216
+ * Fetch with retry logic
217
+ */
218
+ async fetchWithRetry(fetchFn, config) {
219
+ const maxAttempts = config.retryAttempts || 1;
220
+ let lastError;
221
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
222
+ try {
223
+ return await fetchFn();
224
+ }
225
+ catch (error) {
226
+ lastError = error;
227
+ if (attempt < maxAttempts) {
228
+ const delay = (config.retryDelay || 1000) * attempt;
229
+ console.log(`Retry attempt ${attempt} after ${delay}ms`);
230
+ await plugins.smartdelay.delayFor(delay);
231
+ }
232
+ }
233
+ }
234
+ throw lastError || new Error('Unknown error during fetch');
235
+ }
236
+ /**
237
+ * Generate cache key for request
238
+ */
239
+ getCacheKey(request) {
240
+ switch (request.type) {
241
+ case 'fundamentals-current':
242
+ return `fundamentals:${request.ticker}`;
243
+ case 'fundamentals-batch':
244
+ const tickers = request.tickers.sort().join(',');
245
+ return `fundamentals-batch:${tickers}`;
246
+ default:
247
+ return `unknown:${JSON.stringify(request)}`;
248
+ }
249
+ }
250
+ /**
251
+ * Get from cache if not expired
252
+ */
253
+ getFromCache(key) {
254
+ const entry = this.cache.get(key);
255
+ if (!entry) {
256
+ return null;
257
+ }
258
+ // Check if cache entry has expired
259
+ const age = Date.now() - entry.timestamp.getTime();
260
+ if (entry.ttl !== Infinity && age > entry.ttl) {
261
+ this.cache.delete(key);
262
+ return null;
263
+ }
264
+ return entry.fundamentals;
265
+ }
266
+ /**
267
+ * Add to cache with TTL
268
+ */
269
+ addToCache(key, fundamentals, ttl) {
270
+ // Enforce max entries limit
271
+ if (this.cache.size >= this.cacheConfig.maxEntries) {
272
+ // Remove oldest entry
273
+ const oldestKey = this.cache.keys().next().value;
274
+ if (oldestKey) {
275
+ this.cache.delete(oldestKey);
276
+ }
277
+ }
278
+ this.cache.set(key, {
279
+ fundamentals,
280
+ timestamp: new Date(),
281
+ ttl: ttl || this.cacheConfig.ttl
282
+ });
283
+ }
284
+ /**
285
+ * Get human-readable request description
286
+ */
287
+ getRequestDescription(request) {
288
+ switch (request.type) {
289
+ case 'fundamentals-current':
290
+ return `fundamentals for ${request.ticker}`;
291
+ case 'fundamentals-batch':
292
+ return `fundamentals for ${request.tickers.length} tickers`;
293
+ default:
294
+ return 'fundamentals data';
295
+ }
296
+ }
297
+ }
298
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mdW5kYW1lbnRhbHNzZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc3RvY2tzL2NsYXNzZXMuZnVuZGFtZW50YWxzc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQXdCekM7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQVU5QixZQUFZLFdBQW1EO1FBVHZELGNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBMEIsQ0FBQztRQUM5QyxVQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7UUFDdkMsV0FBTSxHQUFHLE9BQU8sQ0FBQztRQUVqQixnQkFBVyxHQUFHO1lBQ3BCLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLGtEQUFrRDtZQUNqRixVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDO1FBR0EsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLFFBQVEsQ0FBQyxRQUErQixFQUFFLE1BQW9DO1FBQ25GLE1BQU0sYUFBYSxHQUFnQztZQUNqRCxPQUFPLEVBQUUsSUFBSTtZQUNiLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUTtZQUMzQixPQUFPLEVBQUUsS0FBSyxFQUFFLHNDQUFzQztZQUN0RCxhQUFhLEVBQUUsQ0FBQztZQUNoQixVQUFVLEVBQUUsSUFBSTtZQUNoQixRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHO1NBQy9CLENBQUM7UUFFRixNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsYUFBYSxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFFckQsSUFBSSxD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
@@ -1,5 +1,8 @@
1
1
  export * from './interfaces/stockprice.js';
2
2
  export * from './interfaces/provider.js';
3
+ export * from './interfaces/fundamentals.js';
3
4
  export * from './classes.stockservice.js';
5
+ export * from './classes.fundamentalsservice.js';
4
6
  export * from './providers/provider.yahoo.js';
5
7
  export * from './providers/provider.marketstack.js';
8
+ export * from './providers/provider.secedgar.js';
@@ -1,9 +1,12 @@
1
1
  // Export all interfaces
2
2
  export * from './interfaces/stockprice.js';
3
3
  export * from './interfaces/provider.js';
4
- // Export main service
4
+ export * from './interfaces/fundamentals.js';
5
+ // Export main services
5
6
  export * from './classes.stockservice.js';
7
+ export * from './classes.fundamentalsservice.js';
6
8
  // Export providers
7
9
  export * from './providers/provider.yahoo.js';
8
10
  export * from './providers/provider.marketstack.js';
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9zdG9ja3MvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0JBQXdCO0FBQ3hCLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYywwQkFBMEIsQ0FBQztBQUV6QyxzQkFBc0I7QUFDdEIsY0FBYywyQkFBMkIsQ0FBQztBQUUxQyxtQkFBbUI7QUFDbkIsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLHFDQUFxQyxDQUFDIn0=
11
+ export * from './providers/provider.secedgar.js';
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9zdG9ja3MvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0JBQXdCO0FBQ3hCLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDhCQUE4QixDQUFDO0FBRTdDLHVCQUF1QjtBQUN2QixjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsa0NBQWtDLENBQUM7QUFFakQsbUJBQW1CO0FBQ25CLGNBQWMsK0JBQStCLENBQUM7QUFDOUMsY0FBYyxxQ0FBcUMsQ0FBQztBQUNwRCxjQUFjLGtDQUFrQyxDQUFDIn0=
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Interfaces for stock fundamental data (financials from SEC filings)
3
+ * Separate from stock price data (OHLCV) to maintain clean architecture
4
+ */
5
+ export interface IFundamentalsCurrentRequest {
6
+ type: 'fundamentals-current';
7
+ ticker: string;
8
+ }
9
+ export interface IFundamentalsBatchRequest {
10
+ type: 'fundamentals-batch';
11
+ tickers: string[];
12
+ }
13
+ export type IFundamentalsRequest = IFundamentalsCurrentRequest | IFundamentalsBatchRequest;
14
+ /**
15
+ * Stock fundamental data from SEC filings (10-K, 10-Q)
16
+ * Contains financial metrics like EPS, Revenue, Assets, etc.
17
+ */
18
+ export interface IStockFundamentals {
19
+ ticker: string;
20
+ cik: string;
21
+ companyName: string;
22
+ provider: string;
23
+ timestamp: Date;
24
+ fetchedAt: Date;
25
+ earningsPerShareBasic?: number;
26
+ earningsPerShareDiluted?: number;
27
+ sharesOutstanding?: number;
28
+ weightedAverageSharesOutstanding?: number;
29
+ revenue?: number;
30
+ netIncome?: number;
31
+ operatingIncome?: number;
32
+ grossProfit?: number;
33
+ costOfRevenue?: number;
34
+ assets?: number;
35
+ liabilities?: number;
36
+ stockholdersEquity?: number;
37
+ cash?: number;
38
+ propertyPlantEquipment?: number;
39
+ marketCap?: number;
40
+ priceToEarnings?: number;
41
+ priceToBook?: number;
42
+ fiscalYear?: string;
43
+ fiscalQuarter?: string;
44
+ filingDate?: Date;
45
+ form?: '10-K' | '10-Q' | string;
46
+ }
47
+ /**
48
+ * Provider interface for fetching fundamental data
49
+ * Parallel to IStockProvider but for fundamentals instead of prices
50
+ */
51
+ export interface IFundamentalsProvider {
52
+ name: string;
53
+ priority: number;
54
+ fetchData(request: IFundamentalsRequest): Promise<IStockFundamentals | IStockFundamentals[]>;
55
+ isAvailable(): Promise<boolean>;
56
+ readonly requiresAuth: boolean;
57
+ readonly rateLimit?: {
58
+ requestsPerMinute: number;
59
+ requestsPerDay?: number;
60
+ };
61
+ }
62
+ /**
63
+ * Configuration for fundamentals providers
64
+ */
65
+ export interface IFundamentalsProviderConfig {
66
+ enabled: boolean;
67
+ priority?: number;
68
+ timeout?: number;
69
+ retryAttempts?: number;
70
+ retryDelay?: number;
71
+ cacheTTL?: number;
72
+ }
73
+ /**
74
+ * Registry for managing fundamental data providers
75
+ */
76
+ export interface IFundamentalsProviderRegistry {
77
+ register(provider: IFundamentalsProvider, config?: IFundamentalsProviderConfig): void;
78
+ unregister(providerName: string): void;
79
+ getProvider(name: string): IFundamentalsProvider | undefined;
80
+ getAllProviders(): IFundamentalsProvider[];
81
+ getEnabledProviders(): IFundamentalsProvider[];
82
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Interfaces for stock fundamental data (financials from SEC filings)
3
+ * Separate from stock price data (OHLCV) to maintain clean architecture
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuZGFtZW50YWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3RvY2tzL2ludGVyZmFjZXMvZnVuZGFtZW50YWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRyJ9
@@ -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
+ }