@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.
@@ -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) || minutes < marketOpenMinutes || (minutes >= marketOpenMinutes && minutes < marketCloseMinutes)) {
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') { // sandbox mode
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') { // test mode, can only use ticker FAKEPACA
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 { // production
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).map(([symbol, bars]) => `${symbol}: ${bars.length}`).join(', ');
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).map(([symbol, bars]) => `${symbol}: ${bars.length}`).join(', ');
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).map(([symbol, trades]) => `${symbol}: ${trades.length}`).join(', ');
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 ? { include_content: mergedParams.include_content.toString() } : {}),
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}`;