@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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/stocks/classes.fundamentalsservice.d.ts +104 -0
- package/dist_ts/stocks/classes.fundamentalsservice.js +298 -0
- package/dist_ts/stocks/index.d.ts +3 -0
- package/dist_ts/stocks/index.js +5 -2
- package/dist_ts/stocks/interfaces/fundamentals.d.ts +82 -0
- package/dist_ts/stocks/interfaces/fundamentals.js +6 -0
- package/dist_ts/stocks/providers/provider.secedgar.d.ts +102 -0
- package/dist_ts/stocks/providers/provider.secedgar.js +343 -0
- package/package.json +1 -1
- package/readme.md +382 -404
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/stocks/classes.fundamentalsservice.ts +404 -0
- package/ts/stocks/index.ts +5 -2
- package/ts/stocks/interfaces/fundamentals.ts +102 -0
- package/ts/stocks/providers/provider.secedgar.ts +429 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@fin.cx/opendata',
|
|
6
|
-
version: '3.
|
|
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';
|
package/dist_ts/stocks/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// Export all interfaces
|
|
2
2
|
export * from './interfaces/stockprice.js';
|
|
3
3
|
export * from './interfaces/provider.js';
|
|
4
|
-
|
|
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
|
-
|
|
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
|
+
}
|