@adaptic/utils 0.0.925 → 0.0.927

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.
Files changed (39) hide show
  1. package/dist/index.cjs +43 -53
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +43 -53
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/test.js +11 -14
  6. package/dist/test.js.map +1 -1
  7. package/dist/types/alpaca/client.d.ts.map +1 -1
  8. package/dist/types/alpaca/crypto/data.d.ts.map +1 -1
  9. package/dist/types/alpaca/crypto/orders.d.ts.map +1 -1
  10. package/dist/types/alpaca/index.d.ts.map +1 -1
  11. package/dist/types/alpaca/legacy/account.d.ts.map +1 -1
  12. package/dist/types/alpaca/legacy/positions.d.ts.map +1 -1
  13. package/dist/types/alpaca/market-data/bars.d.ts.map +1 -1
  14. package/dist/types/alpaca/market-data/news.d.ts.map +1 -1
  15. package/dist/types/alpaca/market-data/quotes.d.ts.map +1 -1
  16. package/dist/types/alpaca/market-data/trades.d.ts.map +1 -1
  17. package/dist/types/alpaca/options/data.d.ts +1 -1
  18. package/dist/types/alpaca/options/data.d.ts.map +1 -1
  19. package/dist/types/alpaca/options/orders.d.ts.map +1 -1
  20. package/dist/types/alpaca/streams/crypto-stream.d.ts.map +1 -1
  21. package/dist/types/alpaca/streams/option-stream.d.ts +2 -2
  22. package/dist/types/alpaca/streams/option-stream.d.ts.map +1 -1
  23. package/dist/types/alpaca/streams/stock-stream.d.ts.map +1 -1
  24. package/dist/types/alpaca/streams/stream-manager.d.ts.map +1 -1
  25. package/dist/types/alpaca/trading/smart-orders.d.ts.map +1 -1
  26. package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
  27. package/dist/types/asset-allocation-algorithm.d.ts.map +1 -1
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/market-time.d.ts.map +1 -1
  30. package/dist/types/massive.d.ts.map +1 -1
  31. package/dist/types/metrics-calcs.d.ts.map +1 -1
  32. package/dist/types/misc-utils.d.ts +2 -2
  33. package/dist/types/misc-utils.d.ts.map +1 -1
  34. package/dist/types/performance-metrics.d.ts.map +1 -1
  35. package/dist/types/price-utils.d.ts.map +1 -1
  36. package/dist/types/schemas/massive-schemas.d.ts +6 -6
  37. package/dist/types/utils/retry.d.ts +1 -10
  38. package/dist/types/utils/retry.d.ts.map +1 -1
  39. package/package.json +7 -1
package/dist/index.mjs CHANGED
@@ -783,13 +783,11 @@ let fs;
783
783
  let path;
784
784
  if (isNode) {
785
785
  try {
786
- /* eslint-disable @typescript-eslint/no-require-imports */
787
786
  const readline = require("readline");
788
787
  clearLine = readline.clearLine;
789
788
  cursorTo = readline.cursorTo;
790
789
  fs = require("fs");
791
790
  path = require("path");
792
- /* eslint-enable @typescript-eslint/no-require-imports */
793
791
  }
794
792
  catch {
795
793
  // Silently degrade — all operations will be no-ops.
@@ -860,7 +858,7 @@ class DisplayManager {
860
858
  /**
861
859
  * Writes a log entry to a symbol-specific log file
862
860
  */
863
- writeSymbolLog(symbol, date, logMessage, options) {
861
+ writeSymbolLog(symbol, date, logMessage, _options) {
864
862
  if (!fs || !path)
865
863
  return;
866
864
  try {
@@ -876,7 +874,7 @@ class DisplayManager {
876
874
  const filename = `${symbol}-${year}-${month}-${day}.log`;
877
875
  const filePath = path.join("logs", filename);
878
876
  // Strip ANSI color codes from log message
879
- const plainLogMessage = logMessage.replace(/\x1B\[\d+m/g, "");
877
+ const plainLogMessage = logMessage.replace(new RegExp(String.fromCharCode(27) + "\\[\\d+m", "g"), "");
880
878
  // Write to file (append if exists, create if not)
881
879
  fs.appendFileSync(filePath, plainLogMessage + "\n");
882
880
  }
@@ -905,7 +903,7 @@ class DisplayManager {
905
903
  const filename = `${source}-${year}-${month}-${day}.log`;
906
904
  const filePath = path.join("logs", filename);
907
905
  // Strip ANSI color codes from log message
908
- const plainLogMessage = logMessage.replace(/\x1B\[\d+m/g, "");
906
+ const plainLogMessage = logMessage.replace(new RegExp(String.fromCharCode(27) + "\\[\\d+m", "g"), "");
909
907
  // Write to file (append if exists, create if not)
910
908
  fs.appendFileSync(filePath, plainLogMessage + "\n");
911
909
  }
@@ -1461,7 +1459,7 @@ class MarketTimeUtil {
1461
1459
  }
1462
1460
  // In all other cases (during trading hours, before market open, holidays, weekends),
1463
1461
  // we want the last completed trading day
1464
- let lastFullDate = this.getLastMarketDay(nowET);
1462
+ const lastFullDate = this.getLastMarketDay(nowET);
1465
1463
  // Set to midnight ET while preserving the date
1466
1464
  return fromZonedTime(set(lastFullDate, { hours: 0, minutes: 0, seconds: 0, milliseconds: 0 }), this.timezone);
1467
1465
  }
@@ -1601,7 +1599,6 @@ class MarketTimeUtil {
1601
1599
  }
1602
1600
  // Convert end date to specified timezone
1603
1601
  const zonedEndDate = toZonedTime(end, this.timezone);
1604
- let startDate;
1605
1602
  let endDate;
1606
1603
  const isCurrentMarketDay = this.isMarketDayZoned(zonedEndDate);
1607
1604
  const isWithinHours = this.isWithinMarketHoursZoned(zonedEndDate);
@@ -1633,7 +1630,7 @@ class MarketTimeUtil {
1633
1630
  // Now calculate the start date based on the period
1634
1631
  const periodStartDate = this.calculatePeriodStartDate(endDate, period);
1635
1632
  const { start: dayStart } = this.getDayBoundaries(periodStartDate);
1636
- startDate = dayStart;
1633
+ const startDate = dayStart;
1637
1634
  // Convert boundaries back to UTC for final output
1638
1635
  const utcStart = fromZonedTime(startDate, this.timezone);
1639
1636
  const utcEnd = fromZonedTime(endDate, this.timezone);
@@ -2500,7 +2497,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
2500
2497
  async getHistoricalBars(params) {
2501
2498
  const symbols = params.symbols;
2502
2499
  const symbolsStr = symbols.join(",");
2503
- let allBars = {};
2500
+ const allBars = {};
2504
2501
  let pageToken = null;
2505
2502
  let hasMorePages = true;
2506
2503
  let totalBarsCount = 0;
@@ -2814,7 +2811,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
2814
2811
  */
2815
2812
  async getLatestOptionsTrades(params) {
2816
2813
  // Remove limit and page_token as they're not supported by this endpoint
2817
- const { limit, page_token, ...requestParams } = params;
2814
+ const { limit: _limit, page_token: _page_token, ...requestParams } = params;
2818
2815
  return this.makeRequest("/options/trades/latest", "GET", requestParams, "v1beta1");
2819
2816
  }
2820
2817
  /**
@@ -2826,7 +2823,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
2826
2823
  */
2827
2824
  async getLatestOptionsQuotes(params) {
2828
2825
  // Remove limit and page_token as they're not supported by this endpoint
2829
- const { limit, page_token, ...requestParams } = params;
2826
+ const { limit: _limit, page_token: _page_token, ...requestParams } = params;
2830
2827
  return this.makeRequest("/options/quotes/latest", "GET", requestParams, "v1beta1");
2831
2828
  }
2832
2829
  /**
@@ -2840,7 +2837,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
2840
2837
  async getHistoricalOptionsBars(params) {
2841
2838
  const symbols = params.symbols;
2842
2839
  const symbolsStr = symbols.join(",");
2843
- let allBars = {};
2840
+ const allBars = {};
2844
2841
  let pageToken = null;
2845
2842
  let hasMorePages = true;
2846
2843
  let totalBarsCount = 0;
@@ -2924,7 +2921,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
2924
2921
  async getHistoricalOptionsTrades(params) {
2925
2922
  const symbols = params.symbols;
2926
2923
  const symbolsStr = symbols.join(",");
2927
- let allTrades = {};
2924
+ const allTrades = {};
2928
2925
  let pageToken = null;
2929
2926
  let hasMorePages = true;
2930
2927
  let totalTradesCount = 0;
@@ -3007,7 +3004,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
3007
3004
  */
3008
3005
  async getOptionsSnapshot(params) {
3009
3006
  // Remove limit and page_token as they may not be supported by this endpoint
3010
- const { limit, page_token, ...requestParams } = params;
3007
+ const { limit: _limit, page_token: _page_token, ...requestParams } = params;
3011
3008
  return this.makeRequest("/options/snapshots", "GET", requestParams, "v1beta1");
3012
3009
  }
3013
3010
  /**
@@ -5704,11 +5701,12 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
5704
5701
  throw new Error(`Position not found for ${symbolOrAssetId}`);
5705
5702
  }
5706
5703
  // Construct global Alpaca Auth for quote fetching
5707
- const alpacaAuth = {
5704
+ const alpacaAuthData = {
5708
5705
  type: "LIVE",
5709
5706
  alpacaApiKey: process.env.ALPACA_API_KEY,
5710
5707
  alpacaApiSecret: process.env.ALPACA_API_SECRET || process.env.ALPACA_SECRET_KEY,
5711
5708
  };
5709
+ const alpacaAuth = alpacaAuthData;
5712
5710
  const quotesResponse = await getLatestQuotes$1(alpacaAuth, {
5713
5711
  symbols: [symbolOrAssetId],
5714
5712
  });
@@ -5911,11 +5909,12 @@ async function closeAllPositionsAfterHours$1(auth, params = { cancel_orders: tru
5911
5909
  account: auth.adapticAccountId || "direct",
5912
5910
  });
5913
5911
  }
5914
- const alpacaAuth = {
5912
+ const alpacaAuthObj = {
5915
5913
  type: "LIVE",
5916
5914
  alpacaApiKey: process.env.ALPACA_API_KEY,
5917
5915
  alpacaApiSecret: process.env.ALPACA_SECRET_KEY,
5918
5916
  };
5917
+ const alpacaAuth = alpacaAuthObj;
5919
5918
  const symbols = positions.map((position) => position.symbol);
5920
5919
  const quotesResponse = await getLatestQuotes$1(alpacaAuth, { symbols });
5921
5920
  for (const position of positions) {
@@ -5971,11 +5970,12 @@ async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, })
5971
5970
  let alpacaAccountObj = alpacaAccount ? alpacaAccount : null;
5972
5971
  if (!alpacaAccountObj && auth) {
5973
5972
  const validatedAuth = await validateAuth(auth);
5974
- alpacaAccountObj = {
5973
+ const accountFromAuth = {
5975
5974
  APIKey: validatedAuth.APIKey,
5976
5975
  APISecret: validatedAuth.APISecret,
5977
5976
  type: validatedAuth.type,
5978
5977
  };
5978
+ alpacaAccountObj = accountFromAuth;
5979
5979
  }
5980
5980
  if (!alpacaAccountObj) {
5981
5981
  try {
@@ -6220,7 +6220,7 @@ async function updateConfiguration(user, account, updatedConfig) {
6220
6220
  throw new Error(`Allocation percentages must sum to 100%. Current total: ${totalAllocation}%`);
6221
6221
  }
6222
6222
  if (account.allocation) {
6223
- allocUpdatePromise = adaptic$1.allocation.update({
6223
+ const allocUpdateData = {
6224
6224
  id: account.allocation.id,
6225
6225
  alpacaAccount: {
6226
6226
  id: account.id,
@@ -6232,10 +6232,11 @@ async function updateConfiguration(user, account, updatedConfig) {
6232
6232
  etfs: updatedConfig.allocation.etfs ?? 0,
6233
6233
  forex: updatedConfig.allocation.forex ?? 0,
6234
6234
  crypto: updatedConfig.allocation.crypto ?? 0,
6235
- }, client);
6235
+ };
6236
+ allocUpdatePromise = adaptic$1.allocation.update(allocUpdateData, client);
6236
6237
  }
6237
6238
  else {
6238
- allocUpdatePromise = adaptic$1.allocation.create({
6239
+ const allocCreateData = {
6239
6240
  stocks: updatedConfig.allocation.stocks ?? 0,
6240
6241
  options: updatedConfig.allocation.options ?? 0,
6241
6242
  futures: updatedConfig.allocation.futures ?? 0,
@@ -6246,10 +6247,11 @@ async function updateConfiguration(user, account, updatedConfig) {
6246
6247
  id: account.id,
6247
6248
  },
6248
6249
  alpacaAccountId: account.id,
6249
- }, client);
6250
+ };
6251
+ allocUpdatePromise = adaptic$1.allocation.create(allocCreateData, client);
6250
6252
  }
6251
6253
  }
6252
- const adapticUpdatePromise = adaptic$1.alpacaAccount.update({
6254
+ const accountUpdateData = {
6253
6255
  id: account.id,
6254
6256
  user: {
6255
6257
  id: user.id,
@@ -6275,7 +6277,8 @@ async function updateConfiguration(user, account, updatedConfig) {
6275
6277
  firstReducedTrailPercentage100: updatedConfig.firstReducedTrailPercentage100 ?? 0,
6276
6278
  secondReducedTrailPercentage100: updatedConfig.secondReducedTrailPercentage100 ?? 0,
6277
6279
  minimumPriceChangePercent100: updatedConfig.minimumPriceChangePercent100 ?? 0,
6278
- }, client);
6280
+ };
6281
+ const adapticUpdatePromise = adaptic$1.alpacaAccount.update(accountUpdateData, client);
6279
6282
  const [alpacaResponse, updatedAlpacaAccount, updatedAllocation] = await Promise.all([
6280
6283
  alpacaUpdatePromise,
6281
6284
  adapticUpdatePromise,
@@ -7586,7 +7589,7 @@ const fetchTickerInfo = async (symbol, options) => {
7586
7589
  if (results.share_class_shares_outstanding === undefined) {
7587
7590
  results.share_class_shares_outstanding = null;
7588
7591
  }
7589
- return {
7592
+ const tickerInfo = {
7590
7593
  ticker: results.ticker,
7591
7594
  type: results.type,
7592
7595
  active: results.active,
@@ -7599,6 +7602,7 @@ const fetchTickerInfo = async (symbol, options) => {
7599
7602
  primary_exchange: results.primary_exchange,
7600
7603
  share_class_shares_outstanding: results.share_class_shares_outstanding,
7601
7604
  };
7605
+ return tickerInfo;
7602
7606
  }
7603
7607
  catch (error) {
7604
7608
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
@@ -7923,7 +7927,7 @@ const fetchGroupedDaily = async (date, options) => {
7923
7927
  if (!MASSIVE_VALID_STATUSES.has(data.status)) {
7924
7928
  throw new Error(`Massive.com API responded with status: ${data.status}`);
7925
7929
  }
7926
- return {
7930
+ const groupedDaily = {
7927
7931
  adjusted: data.adjusted,
7928
7932
  queryCount: data.queryCount,
7929
7933
  request_id: data.request_id,
@@ -7941,6 +7945,7 @@ const fetchGroupedDaily = async (date, options) => {
7941
7945
  trades: result.n,
7942
7946
  })),
7943
7947
  };
7948
+ return groupedDaily;
7944
7949
  }
7945
7950
  catch (error) {
7946
7951
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
@@ -8356,25 +8361,9 @@ const calculateFees = async (action, trade, alpacaAccount) => {
8356
8361
  0;
8357
8362
  switch (assetType) {
8358
8363
  case "STOCK":
8359
- // case "ETF" as enums.AssetType.ETF:
8360
- // commissionFee =
8361
- // (tradeValue * FEE_CONFIG.SHARES_COMMISSION_PERCENTAGE) / 100;
8362
- // regulatoryFee =
8363
- // (tradeValue * FEE_CONFIG.REGULATORY_FEES_PERCENTAGE) / 100;
8364
- // fee = commissionFee + regulatoryFee;
8365
- // break;
8366
- // case "OPTION" as enums.AssetType.OPTION:
8367
- // perContractFee = qty * FEE_CONFIG.OPTIONS_PER_CONTRACT_FEE;
8368
- // baseCommission = FEE_CONFIG.OPTIONS_BASE_COMMISSION;
8369
- // fee = perContractFee + baseCommission;
8370
- // break;
8371
- // case "CRYPTOCURRENCY" as enums.AssetType.CRYPTOCURRENCY:
8372
- // fee = (tradeValue * FEE_CONFIG.CRYPTO_TRANSACTION_PERCENTAGE) / 100;
8373
- // break;
8374
- // case "FUTURE" as enums.AssetType.FUTURE:
8375
- // // Sum of all futures fees
8376
- // fee = 0.85 + 0.85 + 0.25 + 0.02 + 0.01 + 0.3 + 0.01;
8377
- // break;
8364
+ // Currently zero fees for stocks via Alpaca
8365
+ fee = 0;
8366
+ break;
8378
8367
  default:
8379
8368
  fee = 0;
8380
8369
  break;
@@ -8948,7 +8937,7 @@ async function calculateExpenseRatio({ accountId, client, alpacaAccount, }) {
8948
8937
  getLogger().warn("Missing account ID or client to calculate expense ratio.");
8949
8938
  return "N/A";
8950
8939
  }
8951
- let alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
8940
+ const alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
8952
8941
  let accountDetails;
8953
8942
  if (!alpacaAccountId) {
8954
8943
  getLogger().warn("Invalid account ID.");
@@ -8988,7 +8977,7 @@ async function calculateExpenseRatio({ accountId, client, alpacaAccount, }) {
8988
8977
  return `${expenseRatio.toFixed(2)}%`;
8989
8978
  }
8990
8979
  // Mock function to represent fetching expenses from your system
8991
- async function getPortfolioExpensesFromYourSystem(accountId) {
8980
+ async function getPortfolioExpensesFromYourSystem(_accountId) {
8992
8981
  // Implement this function based on your data storage
8993
8982
  return 0; // Placeholder
8994
8983
  }
@@ -9004,7 +8993,7 @@ async function calculateLiquidityRatio({ accountId, client, alpacaAccount, }) {
9004
8993
  getLogger().warn("Missing account ID or client to calculateLiquidityRatio.");
9005
8994
  return "N/A";
9006
8995
  }
9007
- let alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
8996
+ const alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
9008
8997
  let accountDetails;
9009
8998
  if (!alpacaAccountId) {
9010
8999
  getLogger().warn("Invalid account ID.");
@@ -9704,7 +9693,7 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
9704
9693
  const benchmarkSymbol = "SPY";
9705
9694
  let benchmarkBars = [];
9706
9695
  try {
9707
- const { start, end } = await getStartAndEndTimestamps({
9696
+ const { start, end } = getStartAndEndTimestamps({
9708
9697
  timezone: "America/New_York",
9709
9698
  period: params?.period === "YTD" || params?.period === "1A"
9710
9699
  ? "1Y"
@@ -9749,7 +9738,7 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
9749
9738
  alpacaAccount: alpacaAccountObj,
9750
9739
  }),
9751
9740
  getDividendYield(),
9752
- calculateMaxDrawdown(portfolioHistory.equity),
9741
+ Promise.resolve(calculateMaxDrawdown(portfolioHistory.equity)),
9753
9742
  ]);
9754
9743
  // Extract results with error handling for each metric
9755
9744
  const result = { ...defaultMetrics };
@@ -9904,7 +9893,7 @@ function calculateFibonacciLevels(priceData, { lookbackPeriod = 20, retracementL
9904
9893
  const swingLow = Math.min(...periodSlice.map((d) => d.low));
9905
9894
  const priceRange = swingHigh - swingLow;
9906
9895
  const trend = reverseDirection ? "downtrend" : "uptrend";
9907
- let levels = [];
9896
+ const levels = [];
9908
9897
  if (priceRange > 0) {
9909
9898
  // Calculate retracement levels
9910
9899
  retracementLevels.forEach((level) => {
@@ -48577,7 +48566,8 @@ class AlpacaClient {
48577
48566
  // Handle empty responses (e.g., DELETE requests)
48578
48567
  const contentType = response.headers.get("content-type");
48579
48568
  if (!contentType || !contentType.includes("application/json")) {
48580
- return {};
48569
+ const emptyObj = {};
48570
+ return emptyObj;
48581
48571
  }
48582
48572
  return (await response.json());
48583
48573
  }
@@ -56063,7 +56053,7 @@ async function getHistoricalOptionsBars(client, params) {
56063
56053
  * Calculate implied volatility from option price (simplified approximation)
56064
56054
  * For production use, consider using a proper Black-Scholes solver
56065
56055
  */
56066
- function approximateImpliedVolatility(optionPrice, underlyingPrice, strike, daysToExpiration, riskFreeRate = 0.05, isCall = true) {
56056
+ function approximateImpliedVolatility(optionPrice, underlyingPrice, strike, daysToExpiration, _riskFreeRate = 0.05, isCall = true) {
56067
56057
  // Simplified IV approximation using Brenner-Subrahmanyam formula
56068
56058
  // IV ~ (optionPrice / underlyingPrice) * sqrt(2 * pi / T)
56069
56059
  const T = daysToExpiration / 365;
@@ -61334,7 +61324,7 @@ class AssetAllocationEngine {
61334
61324
  /**
61335
61325
  * Apply user constraints and preferences
61336
61326
  */
61337
- applyConstraints(allocations, preferences, constraints, characteristics) {
61327
+ applyConstraints(allocations, preferences, constraints, _characteristics) {
61338
61328
  const constrained = new Map(allocations);
61339
61329
  // Apply exclusions
61340
61330
  if (preferences?.excludedAssetClasses) {