@fin.cx/opendata 2.0.0 → 2.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.stockservice.d.ts +28 -1
- package/dist_ts/stocks/classes.stockservice.js +147 -9
- package/dist_ts/stocks/interfaces/stockprice.d.ts +51 -0
- package/dist_ts/stocks/providers/provider.marketstack.d.ts +43 -9
- package/dist_ts/stocks/providers/provider.marketstack.js +159 -22
- package/dist_ts/stocks/providers/provider.yahoo.js +7 -3
- package/package.json +1 -1
- package/readme.md +232 -22
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/stocks/classes.stockservice.ts +204 -28
- package/ts/stocks/interfaces/stockprice.ts +73 -0
- package/ts/stocks/providers/provider.marketstack.ts +189 -22
- package/ts/stocks/providers/provider.yahoo.ts +6 -2
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
/**
|
|
3
|
-
* Marketstack API v2 Provider
|
|
4
|
-
* Documentation: https://
|
|
3
|
+
* Marketstack API v2 Provider - Enhanced
|
|
4
|
+
* Documentation: https://docs.apilayer.com/marketstack/docs/marketstack-api-v2-v-2-0-0
|
|
5
5
|
*
|
|
6
6
|
* Features:
|
|
7
|
-
* - End-of-Day (EOD) stock prices
|
|
8
|
-
* -
|
|
7
|
+
* - End-of-Day (EOD) stock prices with historical data
|
|
8
|
+
* - Intraday pricing with multiple intervals (1min, 5min, 15min, 30min, 1hour)
|
|
9
|
+
* - Exchange filtering via MIC codes (XNAS, XNYS, XLON, etc.)
|
|
10
|
+
* - Supports 500,000+ tickers across 72+ exchanges worldwide
|
|
11
|
+
* - OHLCV data (Open, High, Low, Close, Volume)
|
|
12
|
+
* - Pagination for large datasets
|
|
9
13
|
* - Requires API key authentication
|
|
10
14
|
*
|
|
11
15
|
* Rate Limits:
|
|
12
16
|
* - Free Plan: 100 requests/month (EOD only)
|
|
13
17
|
* - Basic Plan: 10,000 requests/month
|
|
14
|
-
* - Professional Plan: 100,000 requests/month
|
|
18
|
+
* - Professional Plan: 100,000 requests/month (intraday access)
|
|
15
19
|
*
|
|
16
|
-
*
|
|
20
|
+
* Phase 1 Enhancements:
|
|
21
|
+
* - Historical data retrieval with date ranges
|
|
22
|
+
* - Exchange filtering
|
|
23
|
+
* - OHLCV data support
|
|
24
|
+
* - Pagination handling
|
|
17
25
|
*/
|
|
18
26
|
export class MarketstackProvider {
|
|
19
27
|
constructor(apiKey, config) {
|
|
@@ -33,11 +41,32 @@ export class MarketstackProvider {
|
|
|
33
41
|
this.apiKey = apiKey;
|
|
34
42
|
}
|
|
35
43
|
/**
|
|
36
|
-
*
|
|
44
|
+
* Unified data fetching method supporting all request types
|
|
37
45
|
*/
|
|
38
|
-
async
|
|
46
|
+
async fetchData(request) {
|
|
47
|
+
switch (request.type) {
|
|
48
|
+
case 'current':
|
|
49
|
+
return this.fetchCurrentPrice(request);
|
|
50
|
+
case 'historical':
|
|
51
|
+
return this.fetchHistoricalPrices(request);
|
|
52
|
+
case 'intraday':
|
|
53
|
+
return this.fetchIntradayPrices(request);
|
|
54
|
+
case 'batch':
|
|
55
|
+
return this.fetchBatchCurrentPrices(request);
|
|
56
|
+
default:
|
|
57
|
+
throw new Error(`Unsupported request type: ${request.type}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fetch current/latest EOD price for a single ticker (new API)
|
|
62
|
+
*/
|
|
63
|
+
async fetchCurrentPrice(request) {
|
|
39
64
|
try {
|
|
40
|
-
|
|
65
|
+
let url = `${this.baseUrl}/tickers/${request.ticker}/eod/latest?access_key=${this.apiKey}`;
|
|
66
|
+
// Add exchange filter if specified
|
|
67
|
+
if (request.exchange) {
|
|
68
|
+
url += `&exchange=${request.exchange}`;
|
|
69
|
+
}
|
|
41
70
|
const response = await plugins.smartrequest.SmartRequest.create()
|
|
42
71
|
.url(url)
|
|
43
72
|
.timeout(this.config?.timeout || 10000)
|
|
@@ -51,20 +80,88 @@ export class MarketstackProvider {
|
|
|
51
80
|
if (!responseData || !responseData.close) {
|
|
52
81
|
throw new Error(`No data found for ticker ${request.ticker}`);
|
|
53
82
|
}
|
|
54
|
-
return this.mapToStockPrice(responseData);
|
|
83
|
+
return this.mapToStockPrice(responseData, 'eod');
|
|
55
84
|
}
|
|
56
85
|
catch (error) {
|
|
57
|
-
this.logger.error(`Failed to fetch price for ${request.ticker}:`, error);
|
|
58
|
-
throw new Error(`Marketstack: Failed to fetch price for ${request.ticker}: ${error.message}`);
|
|
86
|
+
this.logger.error(`Failed to fetch current price for ${request.ticker}:`, error);
|
|
87
|
+
throw new Error(`Marketstack: Failed to fetch current price for ${request.ticker}: ${error.message}`);
|
|
59
88
|
}
|
|
60
89
|
}
|
|
61
90
|
/**
|
|
62
|
-
* Fetch
|
|
91
|
+
* Fetch historical EOD prices for a ticker with date range
|
|
63
92
|
*/
|
|
64
|
-
async
|
|
93
|
+
async fetchHistoricalPrices(request) {
|
|
94
|
+
try {
|
|
95
|
+
const allPrices = [];
|
|
96
|
+
let offset = request.offset || 0;
|
|
97
|
+
const limit = request.limit || 1000; // Max per page
|
|
98
|
+
const maxRecords = 10000; // Safety limit
|
|
99
|
+
while (true) {
|
|
100
|
+
let url = `${this.baseUrl}/eod?access_key=${this.apiKey}`;
|
|
101
|
+
url += `&symbols=${request.ticker}`;
|
|
102
|
+
url += `&date_from=${this.formatDate(request.from)}`;
|
|
103
|
+
url += `&date_to=${this.formatDate(request.to)}`;
|
|
104
|
+
url += `&limit=${limit}`;
|
|
105
|
+
url += `&offset=${offset}`;
|
|
106
|
+
if (request.exchange) {
|
|
107
|
+
url += `&exchange=${request.exchange}`;
|
|
108
|
+
}
|
|
109
|
+
if (request.sort) {
|
|
110
|
+
url += `&sort=${request.sort}`;
|
|
111
|
+
}
|
|
112
|
+
const response = await plugins.smartrequest.SmartRequest.create()
|
|
113
|
+
.url(url)
|
|
114
|
+
.timeout(this.config?.timeout || 15000)
|
|
115
|
+
.get();
|
|
116
|
+
const responseData = await response.json();
|
|
117
|
+
// Check for API errors
|
|
118
|
+
if (responseData.error) {
|
|
119
|
+
throw new Error(`Marketstack API error: ${responseData.error.message || JSON.stringify(responseData.error)}`);
|
|
120
|
+
}
|
|
121
|
+
if (!responseData?.data || !Array.isArray(responseData.data)) {
|
|
122
|
+
throw new Error('Invalid response format from Marketstack API');
|
|
123
|
+
}
|
|
124
|
+
// Map data to stock prices
|
|
125
|
+
for (const data of responseData.data) {
|
|
126
|
+
try {
|
|
127
|
+
allPrices.push(this.mapToStockPrice(data, 'eod'));
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
this.logger.warn(`Failed to parse historical data for ${data.symbol}:`, error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Check if we have more pages
|
|
134
|
+
const pagination = responseData.pagination;
|
|
135
|
+
const hasMore = pagination && offset + limit < pagination.total;
|
|
136
|
+
// Safety check: don't fetch more than maxRecords
|
|
137
|
+
if (!hasMore || allPrices.length >= maxRecords) {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
offset += limit;
|
|
141
|
+
}
|
|
142
|
+
return allPrices;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
this.logger.error(`Failed to fetch historical prices for ${request.ticker}:`, error);
|
|
146
|
+
throw new Error(`Marketstack: Failed to fetch historical prices for ${request.ticker}: ${error.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Fetch intraday prices with specified interval (Phase 2 placeholder)
|
|
151
|
+
*/
|
|
152
|
+
async fetchIntradayPrices(request) {
|
|
153
|
+
throw new Error('Intraday data support coming in Phase 2. For now, use EOD data with type: "current" or "historical"');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Fetch current prices for multiple tickers (new API)
|
|
157
|
+
*/
|
|
158
|
+
async fetchBatchCurrentPrices(request) {
|
|
65
159
|
try {
|
|
66
160
|
const symbols = request.tickers.join(',');
|
|
67
|
-
|
|
161
|
+
let url = `${this.baseUrl}/eod/latest?access_key=${this.apiKey}&symbols=${symbols}`;
|
|
162
|
+
if (request.exchange) {
|
|
163
|
+
url += `&exchange=${request.exchange}`;
|
|
164
|
+
}
|
|
68
165
|
const response = await plugins.smartrequest.SmartRequest.create()
|
|
69
166
|
.url(url)
|
|
70
167
|
.timeout(this.config?.timeout || 15000)
|
|
@@ -80,7 +177,7 @@ export class MarketstackProvider {
|
|
|
80
177
|
const prices = [];
|
|
81
178
|
for (const data of responseData.data) {
|
|
82
179
|
try {
|
|
83
|
-
prices.push(this.mapToStockPrice(data));
|
|
180
|
+
prices.push(this.mapToStockPrice(data, 'eod'));
|
|
84
181
|
}
|
|
85
182
|
catch (error) {
|
|
86
183
|
this.logger.warn(`Failed to parse data for ${data.symbol}:`, error);
|
|
@@ -93,10 +190,32 @@ export class MarketstackProvider {
|
|
|
93
190
|
return prices;
|
|
94
191
|
}
|
|
95
192
|
catch (error) {
|
|
96
|
-
this.logger.error(`Failed to fetch batch prices:`, error);
|
|
97
|
-
throw new Error(`Marketstack: Failed to fetch batch prices: ${error.message}`);
|
|
193
|
+
this.logger.error(`Failed to fetch batch current prices:`, error);
|
|
194
|
+
throw new Error(`Marketstack: Failed to fetch batch current prices: ${error.message}`);
|
|
98
195
|
}
|
|
99
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Legacy: Fetch latest EOD price for a single ticker
|
|
199
|
+
* @deprecated Use fetchData with IStockDataRequest instead
|
|
200
|
+
*/
|
|
201
|
+
async fetchPrice(request) {
|
|
202
|
+
// Map legacy request to new format
|
|
203
|
+
return this.fetchCurrentPrice({
|
|
204
|
+
type: 'current',
|
|
205
|
+
ticker: request.ticker
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Legacy: Fetch latest EOD prices for multiple tickers
|
|
210
|
+
* @deprecated Use fetchData with IStockDataRequest instead
|
|
211
|
+
*/
|
|
212
|
+
async fetchPrices(request) {
|
|
213
|
+
// Map legacy request to new format
|
|
214
|
+
return this.fetchBatchCurrentPrices({
|
|
215
|
+
type: 'batch',
|
|
216
|
+
tickers: request.tickers
|
|
217
|
+
});
|
|
218
|
+
}
|
|
100
219
|
/**
|
|
101
220
|
* Check if the Marketstack API is available and accessible
|
|
102
221
|
*/
|
|
@@ -141,7 +260,7 @@ export class MarketstackProvider {
|
|
|
141
260
|
/**
|
|
142
261
|
* Map Marketstack API response to IStockPrice interface
|
|
143
262
|
*/
|
|
144
|
-
mapToStockPrice(data) {
|
|
263
|
+
mapToStockPrice(data, dataType = 'eod') {
|
|
145
264
|
if (!data.close) {
|
|
146
265
|
throw new Error('Missing required price data');
|
|
147
266
|
}
|
|
@@ -149,11 +268,12 @@ export class MarketstackProvider {
|
|
|
149
268
|
// EOD data: previous close is typically open price of the same day
|
|
150
269
|
// For better accuracy, we'd need previous day's close, but that requires another API call
|
|
151
270
|
const currentPrice = data.close;
|
|
152
|
-
const previousClose = data.open;
|
|
271
|
+
const previousClose = data.open || currentPrice;
|
|
153
272
|
const change = currentPrice - previousClose;
|
|
154
273
|
const changePercent = previousClose !== 0 ? (change / previousClose) * 100 : 0;
|
|
155
274
|
// Parse timestamp
|
|
156
275
|
const timestamp = data.date ? new Date(data.date) : new Date();
|
|
276
|
+
const fetchedAt = new Date();
|
|
157
277
|
const stockPrice = {
|
|
158
278
|
ticker: data.symbol.toUpperCase(),
|
|
159
279
|
price: currentPrice,
|
|
@@ -165,9 +285,26 @@ export class MarketstackProvider {
|
|
|
165
285
|
provider: this.name,
|
|
166
286
|
marketState: 'CLOSED', // EOD data is always for closed markets
|
|
167
287
|
exchange: data.exchange,
|
|
168
|
-
exchangeName: data.exchange_code || data.name
|
|
288
|
+
exchangeName: data.exchange_code || data.name,
|
|
289
|
+
// Phase 1 enhancements: OHLCV data
|
|
290
|
+
volume: data.volume,
|
|
291
|
+
open: data.open,
|
|
292
|
+
high: data.high,
|
|
293
|
+
low: data.low,
|
|
294
|
+
adjusted: data.adj_close !== undefined, // If adj_close exists, price is adjusted
|
|
295
|
+
dataType: dataType,
|
|
296
|
+
fetchedAt: fetchedAt
|
|
169
297
|
};
|
|
170
298
|
return stockPrice;
|
|
171
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Format date to YYYY-MM-DD for API requests
|
|
302
|
+
*/
|
|
303
|
+
formatDate(date) {
|
|
304
|
+
const year = date.getFullYear();
|
|
305
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
306
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
307
|
+
return `${year}-${month}-${day}`;
|
|
308
|
+
}
|
|
172
309
|
}
|
|
173
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIubWFya2V0c3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zdG9ja3MvcHJvdmlkZXJzL3Byb3ZpZGVyLm1hcmtldHN0YWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFJNUM7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQWE5QixZQUFZLE1BQWMsRUFBVSxNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQVpyRCxTQUFJLEdBQUcsYUFBYSxDQUFDO1FBQ3JCLGFBQVEsR0FBRyxFQUFFLENBQUMsQ0FBQyw4REFBOEQ7UUFDcEUsaUJBQVksR0FBRyxJQUFJLENBQUM7UUFDcEIsY0FBUyxHQUFHO1lBQzFCLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxnQ0FBZ0M7WUFDOUQsY0FBYyxFQUFFLFNBQVMsQ0FBQyxpQkFBaUI7U0FDNUMsQ0FBQztRQUVNLFdBQU0sR0FBRyxPQUFPLENBQUM7UUFDakIsWUFBTyxHQUFHLGdDQUFnQyxDQUFDO1FBSWpELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUEyQjtRQUNqRCxJQUFJLENBQUM7WUFDSCxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLFlBQVksT0FBTyxDQUFDLE1BQU0sMEJBQTBCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUU3RixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtpQkFDOUQsR0FBRyxDQUFDLEdBQUcsQ0FB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
|
|
310
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIubWFya2V0c3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zdG9ja3MvcHJvdmlkZXJzL3Byb3ZpZGVyLm1hcmtldHN0YWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFlNUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQWE5QixZQUFZLE1BQWMsRUFBVSxNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQVpyRCxTQUFJLEdBQUcsYUFBYSxDQUFDO1FBQ3JCLGFBQVEsR0FBRyxFQUFFLENBQUMsQ0FBQyw4REFBOEQ7UUFDcEUsaUJBQVksR0FBRyxJQUFJLENBQUM7UUFDcEIsY0FBUyxHQUFHO1lBQzFCLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxnQ0FBZ0M7WUFDOUQsY0FBYyxFQUFFLFNBQVMsQ0FBQyxpQkFBaUI7U0FDNUMsQ0FBQztRQUVNLFdBQU0sR0FBRyxPQUFPLENBQUM7UUFDakIsWUFBTyxHQUFHLGdDQUFnQyxDQUFDO1FBSWpELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUEwQjtRQUMvQyxRQUFRLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNyQixLQUFLLFNBQVM7Z0JBQ1osT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekMsS0FBSyxZQUFZO2dCQUNmLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdDLEtBQUssVUFBVTtnQkFDYixPQUFP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
|
|
@@ -43,7 +43,9 @@ export class YahooFinanceProvider {
|
|
|
43
43
|
provider: this.name,
|
|
44
44
|
marketState: this.determineMarketState(meta),
|
|
45
45
|
exchange: meta.exchange,
|
|
46
|
-
exchangeName: meta.exchangeName
|
|
46
|
+
exchangeName: meta.exchangeName,
|
|
47
|
+
dataType: 'live', // Yahoo provides real-time/near real-time data
|
|
48
|
+
fetchedAt: new Date()
|
|
47
49
|
};
|
|
48
50
|
return stockPrice;
|
|
49
51
|
}
|
|
@@ -86,7 +88,9 @@ export class YahooFinanceProvider {
|
|
|
86
88
|
provider: this.name,
|
|
87
89
|
marketState: sparkData.marketState || 'REGULAR',
|
|
88
90
|
exchange: sparkData.exchange,
|
|
89
|
-
exchangeName: sparkData.exchangeName
|
|
91
|
+
exchangeName: sparkData.exchangeName,
|
|
92
|
+
dataType: 'live', // Yahoo provides real-time/near real-time data
|
|
93
|
+
fetchedAt: new Date()
|
|
90
94
|
});
|
|
91
95
|
}
|
|
92
96
|
if (prices.length === 0) {
|
|
@@ -138,4 +142,4 @@ export class YahooFinanceProvider {
|
|
|
138
142
|
}
|
|
139
143
|
}
|
|
140
144
|
}
|
|
141
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
145
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIueWFob28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zdG9ja3MvcHJvdmlkZXJzL3Byb3ZpZGVyLnlhaG9vLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFJNUMsTUFBTSxPQUFPLG9CQUFvQjtJQWEvQixZQUFvQixNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQVpyQyxTQUFJLEdBQUcsZUFBZSxDQUFDO1FBQ3ZCLGFBQVEsR0FBRyxHQUFHLENBQUM7UUFDTixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixjQUFTLEdBQUc7WUFDMUIsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLHdCQUF3QjtZQUNoRCxjQUFjLEVBQUUsU0FBUztTQUMxQixDQUFDO1FBRU0sV0FBTSxHQUFHLE9BQU8sQ0FBQztRQUNqQixZQUFPLEdBQUcsa0NBQWtDLENBQUM7UUFDN0MsY0FBUyxHQUFHLGlIQUFpSCxDQUFDO0lBRXZGLENBQUM7SUFFekMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUEyQjtRQUNqRCxJQUFJLENBQUM7WUFDSCxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLHFCQUFxQixPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakUsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7aUJBQzlELEdBQUcsQ0FBQyxHQUFHLENBQUM7aUJBQ1IsT0FBTyxDQUFDO2dCQUNQLFlBQVksRUFBRSxJQUFJLENBQUMsU0FBUzthQUM3QixDQUFDO2lCQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sSUFBSSxLQUFLLENBQUM7aUJBQ3RDLEdBQUcsRUFBRSxDQUFDO1lBRVQsTUFBTSxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFTLENBQUM7WUFF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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fin.cx/opendata",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.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",
|
package/readme.md
CHANGED
|
@@ -4,7 +4,49 @@
|
|
|
4
4
|
|
|
5
5
|
Access live stock prices, cryptocurrencies, forex, commodities AND comprehensive German company data - all through a single, unified API.
|
|
6
6
|
|
|
7
|
-
## ⚠️ Breaking
|
|
7
|
+
## ⚠️ Breaking Changes
|
|
8
|
+
|
|
9
|
+
### v2.1 - Enhanced Stock Market API (Current)
|
|
10
|
+
|
|
11
|
+
**The stock market API has been significantly enhanced with a new unified request system.**
|
|
12
|
+
|
|
13
|
+
**What Changed:**
|
|
14
|
+
- New discriminated union request types (`IStockDataRequest`)
|
|
15
|
+
- Enhanced `IStockPrice` interface with OHLCV data and metadata
|
|
16
|
+
- New `getData()` method replaces legacy `getPrice()` and `getPrices()`
|
|
17
|
+
- Historical data support with date ranges
|
|
18
|
+
- Exchange filtering via MIC codes
|
|
19
|
+
- Smart caching with data-type aware TTL
|
|
20
|
+
|
|
21
|
+
**Migration:**
|
|
22
|
+
```typescript
|
|
23
|
+
// OLD (v2.0 and earlier)
|
|
24
|
+
const price = await service.getPrice({ ticker: 'AAPL' });
|
|
25
|
+
const prices = await service.getPrices({ tickers: ['AAPL', 'MSFT'] });
|
|
26
|
+
|
|
27
|
+
// NEW (v2.1+) - Unified API
|
|
28
|
+
const price = await service.getData({ type: 'current', ticker: 'AAPL' });
|
|
29
|
+
const prices = await service.getData({ type: 'batch', tickers: ['AAPL', 'MSFT'] });
|
|
30
|
+
|
|
31
|
+
// NEW - Historical data
|
|
32
|
+
const history = await service.getData({
|
|
33
|
+
type: 'historical',
|
|
34
|
+
ticker: 'AAPL',
|
|
35
|
+
from: new Date('2024-01-01'),
|
|
36
|
+
to: new Date('2024-12-31')
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// NEW - Exchange filtering
|
|
40
|
+
const price = await service.getData({
|
|
41
|
+
type: 'current',
|
|
42
|
+
ticker: 'VOD',
|
|
43
|
+
exchange: 'XLON' // London Stock Exchange
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Note:** Legacy `getPrice()` and `getPrices()` methods still work but are deprecated.
|
|
48
|
+
|
|
49
|
+
### v2.0 - Directory Configuration
|
|
8
50
|
|
|
9
51
|
**Directory paths are now MANDATORY when using German business data features.** The package no longer creates `.nogit/` directories automatically. You must explicitly configure all directory paths when instantiating `OpenData`:
|
|
10
52
|
|
|
@@ -28,17 +70,17 @@ pnpm add @fin.cx/opendata
|
|
|
28
70
|
|
|
29
71
|
## Quick Start
|
|
30
72
|
|
|
31
|
-
### 📈 Stock Market Data
|
|
73
|
+
### 📈 Stock Market Data (v2.1+ Enhanced)
|
|
32
74
|
|
|
33
|
-
Get market data with EOD
|
|
75
|
+
Get comprehensive market data with EOD, historical, and OHLCV data:
|
|
34
76
|
|
|
35
77
|
```typescript
|
|
36
78
|
import { StockPriceService, MarketstackProvider } from '@fin.cx/opendata';
|
|
37
79
|
|
|
38
|
-
// Initialize the service with caching
|
|
80
|
+
// Initialize the service with smart caching
|
|
39
81
|
const stockService = new StockPriceService({
|
|
40
|
-
ttl: 60000,
|
|
41
|
-
maxEntries:
|
|
82
|
+
ttl: 60000, // Default cache TTL (historical data cached forever)
|
|
83
|
+
maxEntries: 10000 // Increased for historical data
|
|
42
84
|
});
|
|
43
85
|
|
|
44
86
|
// Register Marketstack provider with API key
|
|
@@ -47,18 +89,38 @@ stockService.register(new MarketstackProvider('YOUR_API_KEY'), {
|
|
|
47
89
|
retryAttempts: 3
|
|
48
90
|
});
|
|
49
91
|
|
|
50
|
-
// Get
|
|
51
|
-
const apple = await stockService.
|
|
92
|
+
// Get current price (new unified API)
|
|
93
|
+
const apple = await stockService.getData({ type: 'current', ticker: 'AAPL' });
|
|
52
94
|
console.log(`Apple: $${apple.price} (${apple.changePercent.toFixed(2)}%)`);
|
|
95
|
+
console.log(`OHLCV: O=${apple.open} H=${apple.high} L=${apple.low} V=${apple.volume}`);
|
|
96
|
+
|
|
97
|
+
// Get historical data (1 year of daily prices)
|
|
98
|
+
const history = await stockService.getData({
|
|
99
|
+
type: 'historical',
|
|
100
|
+
ticker: 'AAPL',
|
|
101
|
+
from: new Date('2024-01-01'),
|
|
102
|
+
to: new Date('2024-12-31'),
|
|
103
|
+
sort: 'DESC' // Newest first
|
|
104
|
+
});
|
|
105
|
+
console.log(`Fetched ${history.length} trading days`);
|
|
53
106
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
107
|
+
// Exchange-specific data (London vs NYSE)
|
|
108
|
+
const vodLondon = await stockService.getData({
|
|
109
|
+
type: 'current',
|
|
110
|
+
ticker: 'VOD',
|
|
111
|
+
exchange: 'XLON' // London Stock Exchange
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const vodNYSE = await stockService.getData({
|
|
115
|
+
type: 'current',
|
|
116
|
+
ticker: 'VOD',
|
|
117
|
+
exchange: 'XNYS' // New York Stock Exchange
|
|
57
118
|
});
|
|
58
119
|
|
|
59
|
-
//
|
|
60
|
-
const
|
|
61
|
-
|
|
120
|
+
// Batch current prices
|
|
121
|
+
const prices = await stockService.getData({
|
|
122
|
+
type: 'batch',
|
|
123
|
+
tickers: ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA']
|
|
62
124
|
});
|
|
63
125
|
```
|
|
64
126
|
|
|
@@ -100,15 +162,18 @@ await openData.buildInitialDb();
|
|
|
100
162
|
|
|
101
163
|
## Features
|
|
102
164
|
|
|
103
|
-
### 🎯 Stock Market Module
|
|
165
|
+
### 🎯 Stock Market Module (v2.1 Enhanced)
|
|
104
166
|
|
|
105
|
-
- **
|
|
106
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **Smart
|
|
109
|
-
- **
|
|
110
|
-
- **
|
|
111
|
-
- **
|
|
167
|
+
- **Historical Data** - Up to 15 years of daily EOD prices with automatic pagination
|
|
168
|
+
- **Exchange Filtering** - Query specific exchanges via MIC codes (XNAS, XLON, XNYS, etc.)
|
|
169
|
+
- **OHLCV Data** - Open, High, Low, Close, Volume for comprehensive analysis
|
|
170
|
+
- **Smart Caching** - Data-type aware TTL (historical cached forever, EOD 24h, live 30s)
|
|
171
|
+
- **Marketstack API** - 500,000+ tickers across 72+ exchanges worldwide
|
|
172
|
+
- **Batch Operations** - Fetch 100+ symbols in one request
|
|
173
|
+
- **Unified API** - Discriminated union types for type-safe requests
|
|
174
|
+
- **Extensible Providers** - Easy to add new data sources
|
|
175
|
+
- **Retry Logic** - Configurable attempts and delays
|
|
176
|
+
- **Type-Safe** - Full TypeScript support with detailed interfaces
|
|
112
177
|
|
|
113
178
|
### 🇩🇪 German Business Intelligence
|
|
114
179
|
|
|
@@ -120,6 +185,151 @@ await openData.buildInitialDb();
|
|
|
120
185
|
|
|
121
186
|
## Advanced Examples
|
|
122
187
|
|
|
188
|
+
### Phase 1: Historical Data Analysis
|
|
189
|
+
|
|
190
|
+
Fetch and analyze historical price data:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// Get 1 year of historical data
|
|
194
|
+
const history = await stockService.getData({
|
|
195
|
+
type: 'historical',
|
|
196
|
+
ticker: 'AAPL',
|
|
197
|
+
from: new Date('2024-01-01'),
|
|
198
|
+
to: new Date('2024-12-31'),
|
|
199
|
+
sort: 'DESC' // Newest first (default)
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Calculate statistics
|
|
203
|
+
const prices = history.map(p => p.price);
|
|
204
|
+
const high52Week = Math.max(...prices);
|
|
205
|
+
const low52Week = Math.min(...prices);
|
|
206
|
+
const avgPrice = prices.reduce((a, b) => a + b) / prices.length;
|
|
207
|
+
|
|
208
|
+
console.log(`52-Week Analysis for AAPL:`);
|
|
209
|
+
console.log(`High: $${high52Week.toFixed(2)}`);
|
|
210
|
+
console.log(`Low: $${low52Week.toFixed(2)}`);
|
|
211
|
+
console.log(`Average: $${avgPrice.toFixed(2)}`);
|
|
212
|
+
console.log(`Days: ${history.length}`);
|
|
213
|
+
|
|
214
|
+
// Calculate daily returns
|
|
215
|
+
for (let i = 0; i < history.length - 1; i++) {
|
|
216
|
+
const todayPrice = history[i].price;
|
|
217
|
+
const yesterdayPrice = history[i + 1].price;
|
|
218
|
+
const dailyReturn = ((todayPrice - yesterdayPrice) / yesterdayPrice) * 100;
|
|
219
|
+
console.log(`${history[i].timestamp.toISOString().split('T')[0]}: ${dailyReturn.toFixed(2)}%`);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Phase 1: Exchange-Specific Trading
|
|
224
|
+
|
|
225
|
+
Compare prices across different exchanges:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Vodafone trades on both London and NYSE
|
|
229
|
+
const exchanges = [
|
|
230
|
+
{ mic: 'XLON', name: 'London Stock Exchange' },
|
|
231
|
+
{ mic: 'XNYS', name: 'New York Stock Exchange' }
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
for (const exchange of exchanges) {
|
|
235
|
+
try {
|
|
236
|
+
const price = await stockService.getData({
|
|
237
|
+
type: 'current',
|
|
238
|
+
ticker: 'VOD',
|
|
239
|
+
exchange: exchange.mic
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
console.log(`${exchange.name}:`);
|
|
243
|
+
console.log(` Price: ${price.price} ${price.currency}`);
|
|
244
|
+
console.log(` Volume: ${price.volume?.toLocaleString()}`);
|
|
245
|
+
console.log(` Exchange: ${price.exchangeName}`);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.log(`${exchange.name}: Not available`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Phase 1: OHLCV Technical Analysis
|
|
253
|
+
|
|
254
|
+
Use OHLCV data for technical indicators:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const history = await stockService.getData({
|
|
258
|
+
type: 'historical',
|
|
259
|
+
ticker: 'TSLA',
|
|
260
|
+
from: new Date('2024-11-01'),
|
|
261
|
+
to: new Date('2024-11-30')
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Calculate daily trading range
|
|
265
|
+
for (const day of history) {
|
|
266
|
+
const range = day.high - day.low;
|
|
267
|
+
const rangePercent = (range / day.low) * 100;
|
|
268
|
+
|
|
269
|
+
console.log(`${day.timestamp.toISOString().split('T')[0]}:`);
|
|
270
|
+
console.log(` Open: $${day.open}`);
|
|
271
|
+
console.log(` High: $${day.high}`);
|
|
272
|
+
console.log(` Low: $${day.low}`);
|
|
273
|
+
console.log(` Close: $${day.price}`);
|
|
274
|
+
console.log(` Volume: ${day.volume?.toLocaleString()}`);
|
|
275
|
+
console.log(` Range: $${range.toFixed(2)} (${rangePercent.toFixed(2)}%)`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Calculate Simple Moving Average (SMA)
|
|
279
|
+
const calculateSMA = (data: IStockPrice[], period: number) => {
|
|
280
|
+
const sma: number[] = [];
|
|
281
|
+
for (let i = period - 1; i < data.length; i++) {
|
|
282
|
+
const sum = data.slice(i - period + 1, i + 1)
|
|
283
|
+
.reduce((acc, p) => acc + p.price, 0);
|
|
284
|
+
sma.push(sum / period);
|
|
285
|
+
}
|
|
286
|
+
return sma;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const sma20 = calculateSMA(history, 20);
|
|
290
|
+
const sma50 = calculateSMA(history, 50);
|
|
291
|
+
|
|
292
|
+
console.log(`20-day SMA: $${sma20[0].toFixed(2)}`);
|
|
293
|
+
console.log(`50-day SMA: $${sma50[0].toFixed(2)}`);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Phase 1: Smart Caching Performance
|
|
297
|
+
|
|
298
|
+
Leverage smart caching for efficiency:
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
// Historical data is cached FOREVER (never changes)
|
|
302
|
+
console.time('First historical fetch');
|
|
303
|
+
const history1 = await stockService.getData({
|
|
304
|
+
type: 'historical',
|
|
305
|
+
ticker: 'AAPL',
|
|
306
|
+
from: new Date('2024-01-01'),
|
|
307
|
+
to: new Date('2024-12-31')
|
|
308
|
+
});
|
|
309
|
+
console.timeEnd('First historical fetch');
|
|
310
|
+
// Output: First historical fetch: 2341ms
|
|
311
|
+
|
|
312
|
+
console.time('Second historical fetch (cached)');
|
|
313
|
+
const history2 = await stockService.getData({
|
|
314
|
+
type: 'historical',
|
|
315
|
+
ticker: 'AAPL',
|
|
316
|
+
from: new Date('2024-01-01'),
|
|
317
|
+
to: new Date('2024-12-31')
|
|
318
|
+
});
|
|
319
|
+
console.timeEnd('Second historical fetch (cached)');
|
|
320
|
+
// Output: Second historical fetch (cached): 2ms (1000x faster!)
|
|
321
|
+
|
|
322
|
+
// EOD data cached for 24 hours
|
|
323
|
+
const currentPrice = await stockService.getData({
|
|
324
|
+
type: 'current',
|
|
325
|
+
ticker: 'MSFT'
|
|
326
|
+
});
|
|
327
|
+
// Subsequent calls within 24h served from cache
|
|
328
|
+
|
|
329
|
+
// Cache statistics
|
|
330
|
+
console.log(`Cache size: ${stockService['cache'].size} entries`);
|
|
331
|
+
```
|
|
332
|
+
|
|
123
333
|
### Market Dashboard
|
|
124
334
|
|
|
125
335
|
Create an EOD market overview:
|