@discomedia/utils 1.0.20 → 1.0.22
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/index-frontend.cjs +45 -32
- package/dist/index-frontend.cjs.map +1 -1
- package/dist/index-frontend.mjs +45 -32
- package/dist/index-frontend.mjs.map +1 -1
- package/dist/index.cjs +93 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +93 -52
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +1 -1
- package/dist/test.js +944 -5020
- package/dist/test.js.map +1 -1
- package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/market-time.d.ts +25 -43
- package/dist/types/market-time.d.ts.map +1 -1
- package/dist/types-frontend/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types-frontend/index.d.ts +4 -0
- package/dist/types-frontend/index.d.ts.map +1 -1
- package/dist/types-frontend/market-time.d.ts +25 -43
- package/dist/types-frontend/market-time.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index-frontend.mjs
CHANGED
|
@@ -13583,7 +13583,7 @@ class MarketCalendar {
|
|
|
13583
13583
|
const yearHolidays = marketHolidays[year];
|
|
13584
13584
|
if (!yearHolidays)
|
|
13585
13585
|
return false;
|
|
13586
|
-
return Object.values(yearHolidays).some(holiday => holiday.date === formattedDate);
|
|
13586
|
+
return Object.values(yearHolidays).some((holiday) => holiday.date === formattedDate);
|
|
13587
13587
|
}
|
|
13588
13588
|
/**
|
|
13589
13589
|
* Checks if a date is an early close day in NY time.
|
|
@@ -13666,7 +13666,9 @@ function getLastFullTradingDateImpl(currentDate = new Date()) {
|
|
|
13666
13666
|
marketCloseMinutes = MARKET_CONFIG.TIMES.EARLY_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.EARLY_CLOSE.minute;
|
|
13667
13667
|
}
|
|
13668
13668
|
// If not a market day, or before open, or during market hours, return previous market day's close
|
|
13669
|
-
if (!calendar.isMarketDay(currentDate) ||
|
|
13669
|
+
if (!calendar.isMarketDay(currentDate) ||
|
|
13670
|
+
minutes < marketOpenMinutes ||
|
|
13671
|
+
(minutes >= marketOpenMinutes && minutes < marketCloseMinutes)) {
|
|
13670
13672
|
const prevMarketDay = calendar.getPreviousMarketDay(currentDate);
|
|
13671
13673
|
let prevCloseMinutes = MARKET_CONFIG.TIMES.MARKET_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.MARKET_CLOSE.minute;
|
|
13672
13674
|
if (calendar.isEarlyCloseDay(prevMarketDay)) {
|
|
@@ -13723,15 +13725,18 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13723
13725
|
stockSubscriptions = { trades: [], quotes: [], bars: [] };
|
|
13724
13726
|
optionSubscriptions = { trades: [], quotes: [], bars: [] };
|
|
13725
13727
|
setMode(mode = 'production') {
|
|
13726
|
-
if (mode === 'sandbox') {
|
|
13728
|
+
if (mode === 'sandbox') {
|
|
13729
|
+
// sandbox mode
|
|
13727
13730
|
this.stockStreamUrl = 'wss://stream.data.sandbox.alpaca.markets/v2/sip';
|
|
13728
13731
|
this.optionStreamUrl = 'wss://stream.data.sandbox.alpaca.markets/v1beta3/options';
|
|
13729
13732
|
}
|
|
13730
|
-
else if (mode === 'test') {
|
|
13733
|
+
else if (mode === 'test') {
|
|
13734
|
+
// test mode, can only use ticker FAKEPACA
|
|
13731
13735
|
this.stockStreamUrl = 'wss://stream.data.alpaca.markets/v2/test';
|
|
13732
13736
|
this.optionStreamUrl = 'wss://stream.data.alpaca.markets/v1beta3/options'; // there's no test mode for options
|
|
13733
13737
|
}
|
|
13734
|
-
else {
|
|
13738
|
+
else {
|
|
13739
|
+
// production
|
|
13735
13740
|
this.stockStreamUrl = 'wss://stream.data.alpaca.markets/v2/sip';
|
|
13736
13741
|
this.optionStreamUrl = 'wss://stream.data.alpaca.markets/v1beta3/options';
|
|
13737
13742
|
}
|
|
@@ -13879,7 +13884,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13879
13884
|
const currentSubscriptions = streamType === 'stock' ? this.stockSubscriptions : this.optionSubscriptions;
|
|
13880
13885
|
Object.entries(subscriptions).forEach(([key, value]) => {
|
|
13881
13886
|
if (value) {
|
|
13882
|
-
currentSubscriptions[key] = (currentSubscriptions[key] || []).filter(s => !value.includes(s));
|
|
13887
|
+
currentSubscriptions[key] = (currentSubscriptions[key] || []).filter((s) => !value.includes(s));
|
|
13883
13888
|
}
|
|
13884
13889
|
});
|
|
13885
13890
|
const unsubMessage = {
|
|
@@ -13942,11 +13947,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13942
13947
|
let pageCount = 0;
|
|
13943
13948
|
let currency = '';
|
|
13944
13949
|
// Initialize bar arrays for each symbol
|
|
13945
|
-
symbols.forEach(symbol => {
|
|
13950
|
+
symbols.forEach((symbol) => {
|
|
13946
13951
|
allBars[symbol] = [];
|
|
13947
13952
|
});
|
|
13948
|
-
log(`Starting historical bars fetch for ${symbolsStr} (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
|
|
13949
|
-
type: 'info'
|
|
13953
|
+
log(`Starting historical bars fetch for ${symbolsStr.length} symbols (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
|
|
13954
|
+
type: 'info',
|
|
13950
13955
|
});
|
|
13951
13956
|
while (hasMorePages) {
|
|
13952
13957
|
pageCount++;
|
|
@@ -13958,7 +13963,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13958
13963
|
};
|
|
13959
13964
|
const response = await this.makeRequest('/stocks/bars', 'GET', requestParams);
|
|
13960
13965
|
if (!response.bars) {
|
|
13961
|
-
log(`No bars data found in response for ${symbolsStr}`, { type: 'warn' });
|
|
13966
|
+
log(`No bars data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
|
|
13962
13967
|
break;
|
|
13963
13968
|
}
|
|
13964
13969
|
// Track currency from first response
|
|
@@ -13974,7 +13979,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13974
13979
|
allBars[symbol] = [...allBars[symbol], ...bars];
|
|
13975
13980
|
pageBarsCount += bars.length;
|
|
13976
13981
|
// Track date range for this page
|
|
13977
|
-
bars.forEach(bar => {
|
|
13982
|
+
bars.forEach((bar) => {
|
|
13978
13983
|
const barDate = new Date(bar.t);
|
|
13979
13984
|
if (!earliestTimestamp || barDate < earliestTimestamp) {
|
|
13980
13985
|
earliestTimestamp = barDate;
|
|
@@ -13993,7 +13998,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13993
13998
|
? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
|
|
13994
13999
|
: 'unknown range';
|
|
13995
14000
|
log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} bars (total: ${totalBarsCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
|
|
13996
|
-
type: 'info'
|
|
14001
|
+
type: 'info',
|
|
13997
14002
|
});
|
|
13998
14003
|
// Prevent infinite loops
|
|
13999
14004
|
if (pageCount > 1000) {
|
|
@@ -14002,9 +14007,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14002
14007
|
}
|
|
14003
14008
|
}
|
|
14004
14009
|
// Final summary
|
|
14005
|
-
const symbolCounts = Object.entries(allBars)
|
|
14010
|
+
const symbolCounts = Object.entries(allBars)
|
|
14011
|
+
.map(([symbol, bars]) => `${symbol}: ${bars.length}`)
|
|
14012
|
+
.join(', ');
|
|
14006
14013
|
log(`Historical bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages (${symbolCounts})`, {
|
|
14007
|
-
type: 'info'
|
|
14014
|
+
type: 'info',
|
|
14008
14015
|
});
|
|
14009
14016
|
return {
|
|
14010
14017
|
bars: allBars,
|
|
@@ -14272,11 +14279,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14272
14279
|
let totalBarsCount = 0;
|
|
14273
14280
|
let pageCount = 0;
|
|
14274
14281
|
// Initialize bar arrays for each symbol
|
|
14275
|
-
symbols.forEach(symbol => {
|
|
14282
|
+
symbols.forEach((symbol) => {
|
|
14276
14283
|
allBars[symbol] = [];
|
|
14277
14284
|
});
|
|
14278
|
-
log(`Starting historical options bars fetch for ${symbolsStr} (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
|
|
14279
|
-
type: 'info'
|
|
14285
|
+
log(`Starting historical options bars fetch for ${symbolsStr.length} symbols (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
|
|
14286
|
+
type: 'info',
|
|
14280
14287
|
});
|
|
14281
14288
|
while (hasMorePages) {
|
|
14282
14289
|
pageCount++;
|
|
@@ -14286,7 +14293,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14286
14293
|
};
|
|
14287
14294
|
const response = await this.makeRequest('/options/bars', 'GET', requestParams, 'v1beta1');
|
|
14288
14295
|
if (!response.bars) {
|
|
14289
|
-
log(`No options bars data found in response for ${symbolsStr}`, { type: 'warn' });
|
|
14296
|
+
log(`No options bars data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
|
|
14290
14297
|
break;
|
|
14291
14298
|
}
|
|
14292
14299
|
// Combine bars for each symbol
|
|
@@ -14298,7 +14305,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14298
14305
|
allBars[symbol] = [...allBars[symbol], ...bars];
|
|
14299
14306
|
pageBarsCount += bars.length;
|
|
14300
14307
|
// Track date range for this page
|
|
14301
|
-
bars.forEach(bar => {
|
|
14308
|
+
bars.forEach((bar) => {
|
|
14302
14309
|
const barDate = new Date(bar.t);
|
|
14303
14310
|
if (!earliestTimestamp || barDate < earliestTimestamp) {
|
|
14304
14311
|
earliestTimestamp = barDate;
|
|
@@ -14317,7 +14324,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14317
14324
|
? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
|
|
14318
14325
|
: 'unknown range';
|
|
14319
14326
|
log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} option bars (total: ${totalBarsCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
|
|
14320
|
-
type: 'info'
|
|
14327
|
+
type: 'info',
|
|
14321
14328
|
});
|
|
14322
14329
|
// Prevent infinite loops
|
|
14323
14330
|
if (pageCount > 1000) {
|
|
@@ -14326,9 +14333,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14326
14333
|
}
|
|
14327
14334
|
}
|
|
14328
14335
|
// Final summary
|
|
14329
|
-
const symbolCounts = Object.entries(allBars)
|
|
14336
|
+
const symbolCounts = Object.entries(allBars)
|
|
14337
|
+
.map(([symbol, bars]) => `${symbol}: ${bars.length}`)
|
|
14338
|
+
.join(', ');
|
|
14330
14339
|
log(`Historical options bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages (${symbolCounts})`, {
|
|
14331
|
-
type: 'info'
|
|
14340
|
+
type: 'info',
|
|
14332
14341
|
});
|
|
14333
14342
|
return {
|
|
14334
14343
|
bars: allBars,
|
|
@@ -14352,11 +14361,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14352
14361
|
let totalTradesCount = 0;
|
|
14353
14362
|
let pageCount = 0;
|
|
14354
14363
|
// Initialize trades arrays for each symbol
|
|
14355
|
-
symbols.forEach(symbol => {
|
|
14364
|
+
symbols.forEach((symbol) => {
|
|
14356
14365
|
allTrades[symbol] = [];
|
|
14357
14366
|
});
|
|
14358
|
-
log(`Starting historical options trades fetch for ${symbolsStr} (${params.start || 'no start'} to ${params.end || 'no end'})`, {
|
|
14359
|
-
type: 'info'
|
|
14367
|
+
log(`Starting historical options trades fetch for ${symbolsStr.length} symbols (${params.start || 'no start'} to ${params.end || 'no end'})`, {
|
|
14368
|
+
type: 'info',
|
|
14360
14369
|
});
|
|
14361
14370
|
while (hasMorePages) {
|
|
14362
14371
|
pageCount++;
|
|
@@ -14366,7 +14375,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14366
14375
|
};
|
|
14367
14376
|
const response = await this.makeRequest('/options/trades', 'GET', requestParams, 'v1beta1');
|
|
14368
14377
|
if (!response.trades) {
|
|
14369
|
-
log(`No options trades data found in response for ${symbolsStr}`, { type: 'warn' });
|
|
14378
|
+
log(`No options trades data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
|
|
14370
14379
|
break;
|
|
14371
14380
|
}
|
|
14372
14381
|
// Combine trades for each symbol
|
|
@@ -14378,7 +14387,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14378
14387
|
allTrades[symbol] = [...allTrades[symbol], ...trades];
|
|
14379
14388
|
pageTradesCount += trades.length;
|
|
14380
14389
|
// Track date range for this page
|
|
14381
|
-
trades.forEach(trade => {
|
|
14390
|
+
trades.forEach((trade) => {
|
|
14382
14391
|
const tradeDate = new Date(trade.t);
|
|
14383
14392
|
if (!earliestTimestamp || tradeDate < earliestTimestamp) {
|
|
14384
14393
|
earliestTimestamp = tradeDate;
|
|
@@ -14396,8 +14405,8 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14396
14405
|
const dateRangeStr = earliestTimestamp && latestTimestamp
|
|
14397
14406
|
? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
|
|
14398
14407
|
: 'unknown range';
|
|
14399
|
-
log(`Page ${pageCount}: Fetched ${pageTradesCount.toLocaleString()} option trades (total: ${totalTradesCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
|
|
14400
|
-
type: 'info'
|
|
14408
|
+
log(`Page ${pageCount}: Fetched ${pageTradesCount.toLocaleString()} option trades (total: ${totalTradesCount.toLocaleString()}) for ${symbolsStr.length} symbols, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
|
|
14409
|
+
type: 'info',
|
|
14401
14410
|
});
|
|
14402
14411
|
// Prevent infinite loops
|
|
14403
14412
|
if (pageCount > 1000) {
|
|
@@ -14406,9 +14415,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14406
14415
|
}
|
|
14407
14416
|
}
|
|
14408
14417
|
// Final summary
|
|
14409
|
-
const symbolCounts = Object.entries(allTrades)
|
|
14418
|
+
const symbolCounts = Object.entries(allTrades)
|
|
14419
|
+
.map(([symbol, trades]) => `${symbol}: ${trades.length}`)
|
|
14420
|
+
.join(', ');
|
|
14410
14421
|
log(`Historical options trades fetch complete: ${totalTradesCount.toLocaleString()} total trades across ${pageCount} pages (${symbolCounts})`, {
|
|
14411
|
-
type: 'info'
|
|
14422
|
+
type: 'info',
|
|
14412
14423
|
});
|
|
14413
14424
|
return {
|
|
14414
14425
|
trades: allTrades,
|
|
@@ -14553,7 +14564,9 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14553
14564
|
...(symbol && { symbols: symbol }),
|
|
14554
14565
|
...(mergedParams.limit && { limit: Math.min(50, maxLimit - fetchedCount).toString() }),
|
|
14555
14566
|
...(mergedParams.sort && { sort: mergedParams.sort }),
|
|
14556
|
-
...(mergedParams.include_content !== undefined
|
|
14567
|
+
...(mergedParams.include_content !== undefined
|
|
14568
|
+
? { include_content: mergedParams.include_content.toString() }
|
|
14569
|
+
: {}),
|
|
14557
14570
|
...(pageToken && { page_token: pageToken }),
|
|
14558
14571
|
});
|
|
14559
14572
|
const url = `${this.v1beta1url}/news?${queryParams}`;
|