@fin.cx/opendata 2.1.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/classes.stockservice.d.ts +16 -7
- package/dist_ts/stocks/classes.stockservice.js +17 -98
- 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/interfaces/provider.d.ts +2 -3
- package/dist_ts/stocks/interfaces/stockprice.d.ts +2 -10
- package/dist_ts/stocks/interfaces/stockprice.js +2 -2
- package/dist_ts/stocks/providers/provider.marketstack.d.ts +6 -11
- package/dist_ts/stocks/providers/provider.marketstack.js +32 -24
- package/dist_ts/stocks/providers/provider.secedgar.d.ts +102 -0
- package/dist_ts/stocks/providers/provider.secedgar.js +343 -0
- package/dist_ts/stocks/providers/provider.yahoo.d.ts +13 -3
- package/dist_ts/stocks/providers/provider.yahoo.js +27 -4
- package/package.json +1 -1
- package/readme.md +383 -388
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/stocks/classes.fundamentalsservice.ts +404 -0
- package/ts/stocks/classes.stockservice.ts +28 -140
- package/ts/stocks/index.ts +5 -2
- package/ts/stocks/interfaces/fundamentals.ts +102 -0
- package/ts/stocks/interfaces/provider.ts +5 -6
- package/ts/stocks/interfaces/stockprice.ts +4 -19
- package/ts/stocks/providers/provider.marketstack.ts +39 -30
- package/ts/stocks/providers/provider.secedgar.ts +429 -0
- package/ts/stocks/providers/provider.yahoo.ts +33 -4
|
@@ -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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
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IStockProvider, IProviderConfig } from '../interfaces/provider.js';
|
|
2
|
-
import type { IStockPrice,
|
|
2
|
+
import type { IStockPrice, IStockDataRequest } from '../interfaces/stockprice.js';
|
|
3
3
|
export declare class YahooFinanceProvider implements IStockProvider {
|
|
4
4
|
private config?;
|
|
5
5
|
name: string;
|
|
@@ -13,8 +13,18 @@ export declare class YahooFinanceProvider implements IStockProvider {
|
|
|
13
13
|
private baseUrl;
|
|
14
14
|
private userAgent;
|
|
15
15
|
constructor(config?: IProviderConfig);
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Unified data fetching method
|
|
18
|
+
*/
|
|
19
|
+
fetchData(request: IStockDataRequest): Promise<IStockPrice | IStockPrice[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Fetch current price for a single ticker
|
|
22
|
+
*/
|
|
23
|
+
private fetchCurrentPrice;
|
|
24
|
+
/**
|
|
25
|
+
* Fetch batch current prices
|
|
26
|
+
*/
|
|
27
|
+
private fetchBatchCurrentPrices;
|
|
18
28
|
isAvailable(): Promise<boolean>;
|
|
19
29
|
supportsMarket(market: string): boolean;
|
|
20
30
|
supportsTicker(ticker: string): boolean;
|
|
@@ -13,7 +13,27 @@ export class YahooFinanceProvider {
|
|
|
13
13
|
this.baseUrl = 'https://query1.finance.yahoo.com';
|
|
14
14
|
this.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Unified data fetching method
|
|
18
|
+
*/
|
|
19
|
+
async fetchData(request) {
|
|
20
|
+
switch (request.type) {
|
|
21
|
+
case 'current':
|
|
22
|
+
return this.fetchCurrentPrice(request);
|
|
23
|
+
case 'batch':
|
|
24
|
+
return this.fetchBatchCurrentPrices(request);
|
|
25
|
+
case 'historical':
|
|
26
|
+
throw new Error('Yahoo Finance provider does not support historical data. Use Marketstack provider instead.');
|
|
27
|
+
case 'intraday':
|
|
28
|
+
throw new Error('Yahoo Finance provider does not support intraday data yet. Use Marketstack provider instead.');
|
|
29
|
+
default:
|
|
30
|
+
throw new Error(`Unsupported request type: ${request.type}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Fetch current price for a single ticker
|
|
35
|
+
*/
|
|
36
|
+
async fetchCurrentPrice(request) {
|
|
17
37
|
try {
|
|
18
38
|
const url = `${this.baseUrl}/v8/finance/chart/${request.ticker}`;
|
|
19
39
|
const response = await plugins.smartrequest.SmartRequest.create()
|
|
@@ -54,7 +74,10 @@ export class YahooFinanceProvider {
|
|
|
54
74
|
throw new Error(`Yahoo Finance: Failed to fetch price for ${request.ticker}: ${error.message}`);
|
|
55
75
|
}
|
|
56
76
|
}
|
|
57
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Fetch batch current prices
|
|
79
|
+
*/
|
|
80
|
+
async fetchBatchCurrentPrices(request) {
|
|
58
81
|
try {
|
|
59
82
|
const symbols = request.tickers.join(',');
|
|
60
83
|
const url = `${this.baseUrl}/v8/finance/spark?symbols=${symbols}&range=1d&interval=5m`;
|
|
@@ -106,7 +129,7 @@ export class YahooFinanceProvider {
|
|
|
106
129
|
async isAvailable() {
|
|
107
130
|
try {
|
|
108
131
|
// Test with a well-known ticker
|
|
109
|
-
await this.
|
|
132
|
+
await this.fetchData({ type: 'current', ticker: 'AAPL' });
|
|
110
133
|
return true;
|
|
111
134
|
}
|
|
112
135
|
catch (error) {
|
|
@@ -142,4 +165,4 @@ export class YahooFinanceProvider {
|
|
|
142
165
|
}
|
|
143
166
|
}
|
|
144
167
|
}
|
|
145
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
168
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIueWFob28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zdG9ja3MvcHJvdmlkZXJzL3Byb3ZpZGVyLnlhaG9vLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFTNUMsTUFBTSxPQUFPLG9CQUFvQjtJQWEvQixZQUFvQixNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQVpyQyxTQUFJLEdBQUcsZUFBZSxDQUFDO1FBQ3ZCLGFBQVEsR0FBRyxHQUFHLENBQUM7UUFDTixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixjQUFTLEdBQUc7WUFDMUIsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLHdCQUF3QjtZQUNoRCxjQUFjLEVBQUUsU0FBUztTQUMxQixDQUFDO1FBRU0sV0FBTSxHQUFHLE9BQU8sQ0FBQztRQUNqQixZQUFPLEdBQUcsa0NBQWtDLENBQUM7UUFDN0MsY0FBUyxHQUFHLGlIQUFpSCxDQUFDO0lBRXZGLENBQUM7SUFFaEQ7O09BRUc7SUFDSSxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQTBCO1FBQy9DLFFBQVEsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3JCLEtBQUssU0FBUztnQkFDWixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QyxLQUFLLE9BQU87Z0JBQ1YsT0FBTyxJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0MsS0FBSyxZQUFZO2dCQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsNEZBQTRGLENBQUMsQ0FBQztZQUNoSCxLQUFLLFVBQVU7Z0JBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyw4RkFBOEYsQ0FBQyxDQUFDO1lBQ2xIO2dCQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQThCLE9BQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLENB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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fin.cx/opendata",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.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",
|