@adaptic/utils 0.1.2 → 0.1.4

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.cjs CHANGED
@@ -320,23 +320,42 @@ const fetchAssetOverview = async (symbol) => {
320
320
  /**
321
321
  * Validates Alpaca API credentials
322
322
  * @param auth - Authentication object containing API key and secret
323
- * @throws {Error} If credentials are invalid or missing
323
+ * @param options - Validation options
324
+ * @param options.throwOnMissing - If false, missing credentials will log a warning instead of throwing (default: true)
325
+ * @throws {Error} If credentials are invalid (when throwOnMissing is true)
326
+ * @returns {boolean} True if credentials are valid, false if missing (when throwOnMissing is false)
324
327
  */
325
- function validateAlpacaCredentials(auth) {
328
+ function validateAlpacaCredentials(auth, options = { throwOnMissing: true }) {
329
+ const { throwOnMissing = true } = options;
330
+ // Check for missing or empty API key
326
331
  if (!auth.apiKey ||
327
332
  typeof auth.apiKey !== "string" ||
328
333
  auth.apiKey.trim().length === 0) {
329
- throw new Error("Invalid Alpaca API key: must be a non-empty string");
334
+ if (throwOnMissing) {
335
+ throw new Error("Invalid Alpaca API key: must be a non-empty string");
336
+ }
337
+ console.warn("[AlpacaAPI] API key not configured. Market data features will be unavailable.");
338
+ return false;
330
339
  }
340
+ // Check for missing or empty API secret
331
341
  if (!auth.apiSecret ||
332
342
  typeof auth.apiSecret !== "string" ||
333
343
  auth.apiSecret.trim().length === 0) {
334
- throw new Error("Invalid Alpaca API secret: must be a non-empty string");
344
+ if (throwOnMissing) {
345
+ throw new Error("Invalid Alpaca API secret: must be a non-empty string");
346
+ }
347
+ console.warn("[AlpacaAPI] API secret not configured. Market data features will be unavailable.");
348
+ return false;
335
349
  }
336
350
  // Alpaca keys are typically 20+ characters
337
351
  if (auth.apiKey.length < 10) {
338
- throw new Error("Alpaca API key appears to be too short");
352
+ if (throwOnMissing) {
353
+ throw new Error("Alpaca API key appears to be too short");
354
+ }
355
+ console.warn("[AlpacaAPI] API key appears to be too short.");
356
+ return false;
339
357
  }
358
+ return true;
340
359
  }
341
360
  /**
342
361
  * Validates Polygon API key
@@ -369,21 +388,21 @@ function validateAlphaVantageApiKey(apiKey) {
369
388
  async function validateAuth(auth) {
370
389
  if (auth.adapticAccountId) {
371
390
  const client = await getSharedApolloClient();
372
- const alpacaAccount = (await adaptic$1.alpacaAccount.get({
391
+ const brokerageAccount = (await adaptic$1.brokerageAccount.get({
373
392
  id: auth.adapticAccountId,
374
393
  }, client));
375
- if (!alpacaAccount || !alpacaAccount.APIKey || !alpacaAccount.APISecret) {
394
+ if (!brokerageAccount || !brokerageAccount.apiKey || !brokerageAccount.apiSecret) {
376
395
  throw new Error("Alpaca account not found or incomplete");
377
396
  }
378
397
  validateAlpacaCredentials({
379
- apiKey: alpacaAccount.APIKey,
380
- apiSecret: alpacaAccount.APISecret,
381
- isPaper: alpacaAccount.type === "PAPER",
398
+ apiKey: brokerageAccount.apiKey,
399
+ apiSecret: brokerageAccount.apiSecret,
400
+ isPaper: brokerageAccount.type === "PAPER",
382
401
  });
383
402
  return {
384
- APIKey: alpacaAccount.APIKey,
385
- APISecret: alpacaAccount.APISecret,
386
- type: alpacaAccount.type,
403
+ apiKey: brokerageAccount.apiKey,
404
+ apiSecret: brokerageAccount.apiSecret,
405
+ type: brokerageAccount.type,
387
406
  };
388
407
  }
389
408
  else if (auth.alpacaApiKey && auth.alpacaApiSecret) {
@@ -392,8 +411,8 @@ async function validateAuth(auth) {
392
411
  apiKey: auth.alpacaApiKey,
393
412
  apiSecret: auth.alpacaApiSecret});
394
413
  return {
395
- APIKey: auth.alpacaApiKey,
396
- APISecret: auth.alpacaApiSecret,
414
+ apiKey: auth.alpacaApiKey,
415
+ apiSecret: auth.alpacaApiSecret,
397
416
  type: accountType,
398
417
  };
399
418
  }
@@ -564,11 +583,11 @@ const ORDER_CHUNK_SIZE = 500;
564
583
  async function makeRequest(auth, params) {
565
584
  const { endpoint, method, body, queryString, apiBaseUrl } = params;
566
585
  try {
567
- const { APIKey, APISecret, type } = await validateAuth(auth);
586
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
568
587
  const apiBaseUrlInner = apiBaseUrl
569
588
  ? apiBaseUrl
570
589
  : getTradingApiUrl(type);
571
- if (!APIKey || !APISecret) {
590
+ if (!apiKey || !apiSecret) {
572
591
  throw new Error("No valid Alpaca authentication found. Please provide either auth object or set ALPACA_API_KEY and ALPACA_API_SECRET environment variables.");
573
592
  }
574
593
  const url = `${apiBaseUrlInner}${endpoint}${queryString || ""}`;
@@ -579,8 +598,8 @@ async function makeRequest(auth, params) {
579
598
  const fetchOptions = {
580
599
  method,
581
600
  headers: {
582
- "APCA-API-KEY-ID": APIKey,
583
- "APCA-API-SECRET-KEY": APISecret,
601
+ "APCA-API-KEY-ID": apiKey,
602
+ "APCA-API-SECRET-KEY": apiSecret,
584
603
  },
585
604
  };
586
605
  // Only add Content-Type and body for non-GET/HEAD requests that have a body
@@ -624,13 +643,13 @@ async function makeRequest(auth, params) {
624
643
  */
625
644
  async function createOrder$1(auth, params) {
626
645
  try {
627
- const { APIKey, APISecret, type } = await validateAuth(auth);
646
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
628
647
  const apiBaseUrl = getTradingApiUrl(type);
629
648
  const response = await fetch(`${apiBaseUrl}/v2/orders`, {
630
649
  method: "POST",
631
650
  headers: {
632
- "APCA-API-KEY-ID": APIKey,
633
- "APCA-API-SECRET-KEY": APISecret,
651
+ "APCA-API-KEY-ID": apiKey,
652
+ "APCA-API-SECRET-KEY": apiSecret,
634
653
  "Content-Type": "application/json",
635
654
  },
636
655
  body: JSON.stringify(params),
@@ -655,7 +674,7 @@ async function createOrder$1(auth, params) {
655
674
  */
656
675
  async function getOrders$1(auth, params = {}) {
657
676
  try {
658
- const { APIKey, APISecret, type } = await validateAuth(auth);
677
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
659
678
  const apiBaseUrl = getTradingApiUrl(type);
660
679
  const allOrders = [];
661
680
  let currentUntil = params.until ? params.until : new Date().toISOString();
@@ -678,8 +697,8 @@ async function getOrders$1(auth, params = {}) {
678
697
  const response = await fetch(`${apiBaseUrl}/v2/orders?${queryParams}`, {
679
698
  method: "GET",
680
699
  headers: {
681
- "APCA-API-KEY-ID": APIKey,
682
- "APCA-API-SECRET-KEY": APISecret,
700
+ "APCA-API-KEY-ID": apiKey,
701
+ "APCA-API-SECRET-KEY": apiSecret,
683
702
  },
684
703
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
685
704
  });
@@ -711,13 +730,13 @@ async function getOrders$1(auth, params = {}) {
711
730
  */
712
731
  async function cancelAllOrders$1(auth) {
713
732
  try {
714
- const { APIKey, APISecret, type } = await validateAuth(auth);
733
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
715
734
  const apiBaseUrl = getTradingApiUrl(type);
716
735
  const response = await fetch(`${apiBaseUrl}/v2/orders`, {
717
736
  method: "DELETE",
718
737
  headers: {
719
- "APCA-API-KEY-ID": APIKey,
720
- "APCA-API-SECRET-KEY": APISecret,
738
+ "APCA-API-KEY-ID": apiKey,
739
+ "APCA-API-SECRET-KEY": apiSecret,
721
740
  },
722
741
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
723
742
  });
@@ -741,7 +760,7 @@ async function cancelAllOrders$1(auth) {
741
760
  */
742
761
  async function getOrder$1(auth, orderId, nested) {
743
762
  try {
744
- const { APIKey, APISecret, type } = await validateAuth(auth);
763
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
745
764
  const apiBaseUrl = getTradingApiUrl(type);
746
765
  const queryParams = new URLSearchParams();
747
766
  if (nested)
@@ -749,8 +768,8 @@ async function getOrder$1(auth, orderId, nested) {
749
768
  const response = await fetch(`${apiBaseUrl}/v2/orders/${orderId}?${queryParams}`, {
750
769
  method: "GET",
751
770
  headers: {
752
- "APCA-API-KEY-ID": APIKey,
753
- "APCA-API-SECRET-KEY": APISecret,
771
+ "APCA-API-KEY-ID": apiKey,
772
+ "APCA-API-SECRET-KEY": apiSecret,
754
773
  },
755
774
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
756
775
  });
@@ -774,13 +793,13 @@ async function getOrder$1(auth, orderId, nested) {
774
793
  */
775
794
  async function replaceOrder$1(auth, orderId, params) {
776
795
  try {
777
- const { APIKey, APISecret, type } = await validateAuth(auth);
796
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
778
797
  const apiBaseUrl = getTradingApiUrl(type);
779
798
  const response = await fetch(`${apiBaseUrl}/v2/orders/${orderId}`, {
780
799
  method: "PATCH",
781
800
  headers: {
782
- "APCA-API-KEY-ID": APIKey,
783
- "APCA-API-SECRET-KEY": APISecret,
801
+ "APCA-API-KEY-ID": apiKey,
802
+ "APCA-API-SECRET-KEY": apiSecret,
784
803
  "Content-Type": "application/json",
785
804
  accept: "application/json",
786
805
  },
@@ -806,13 +825,13 @@ async function replaceOrder$1(auth, orderId, params) {
806
825
  */
807
826
  async function cancelOrder$1(auth, orderId) {
808
827
  try {
809
- const { APIKey, APISecret, type } = await validateAuth(auth);
828
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
810
829
  const apiBaseUrl = getTradingApiUrl(type);
811
830
  const response = await fetch(`${apiBaseUrl}/v2/orders/${orderId}`, {
812
831
  method: "DELETE",
813
832
  headers: {
814
- "APCA-API-KEY-ID": APIKey,
815
- "APCA-API-SECRET-KEY": APISecret,
833
+ "APCA-API-KEY-ID": apiKey,
834
+ "APCA-API-SECRET-KEY": apiSecret,
816
835
  },
817
836
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
818
837
  });
@@ -1394,14 +1413,14 @@ async function fetchNews$1(symbols, params) {
1394
1413
  }
1395
1414
  else if (mergedParams.auth.adapticAccountId) {
1396
1415
  const client = await getSharedApolloClient();
1397
- const alpacaAccount = (await adaptic$1.alpacaAccount.get({
1416
+ const brokerageAccount = (await adaptic$1.brokerageAccount.get({
1398
1417
  id: mergedParams.auth.adapticAccountId,
1399
1418
  }, client));
1400
- if (!alpacaAccount || !alpacaAccount.APIKey || !alpacaAccount.APISecret) {
1419
+ if (!brokerageAccount || !brokerageAccount.apiKey || !brokerageAccount.apiSecret) {
1401
1420
  throw new Error("Alpaca account not found or incomplete");
1402
1421
  }
1403
- APIKey = alpacaAccount.APIKey;
1404
- APISecret = alpacaAccount.APISecret;
1422
+ APIKey = brokerageAccount.apiKey;
1423
+ APISecret = brokerageAccount.apiSecret;
1405
1424
  }
1406
1425
  }
1407
1426
  else {
@@ -1494,14 +1513,14 @@ async function fetchNews$1(symbols, params) {
1494
1513
  */
1495
1514
  async function fetchAllPositions(auth) {
1496
1515
  try {
1497
- const { APIKey, APISecret, type } = await validateAuth(auth);
1516
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
1498
1517
  const apiBaseUrl = getTradingApiUrl(type);
1499
1518
  const apiUrl = `${apiBaseUrl}/v2/positions`;
1500
1519
  const response = await fetch(apiUrl, {
1501
1520
  method: "GET",
1502
1521
  headers: {
1503
- "APCA-API-KEY-ID": APIKey,
1504
- "APCA-API-SECRET-KEY": APISecret,
1522
+ "APCA-API-KEY-ID": apiKey,
1523
+ "APCA-API-SECRET-KEY": apiSecret,
1505
1524
  "Content-Type": "application/json",
1506
1525
  },
1507
1526
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
@@ -1525,13 +1544,13 @@ async function fetchAllPositions(auth) {
1525
1544
  */
1526
1545
  async function fetchPosition(auth, symbolOrAssetId) {
1527
1546
  try {
1528
- const { APIKey, APISecret, type } = await validateAuth(auth);
1547
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
1529
1548
  const apiBaseUrl = getTradingApiUrl(type);
1530
1549
  const response = await fetch(`${apiBaseUrl}/v2/positions/${symbolOrAssetId}`, {
1531
1550
  method: "GET",
1532
1551
  headers: {
1533
- "APCA-API-KEY-ID": APIKey,
1534
- "APCA-API-SECRET-KEY": APISecret,
1552
+ "APCA-API-KEY-ID": apiKey,
1553
+ "APCA-API-SECRET-KEY": apiSecret,
1535
1554
  "Content-Type": "application/json",
1536
1555
  },
1537
1556
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
@@ -1565,7 +1584,7 @@ async function fetchPosition(auth, symbolOrAssetId) {
1565
1584
  */
1566
1585
  async function closePosition$1(auth, symbolOrAssetId, params) {
1567
1586
  try {
1568
- const { APIKey, APISecret, type } = await validateAuth(auth);
1587
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
1569
1588
  const apiBaseUrl = getTradingApiUrl(type);
1570
1589
  const useLimitOrder = params?.useLimitOrder ?? false;
1571
1590
  const cancelOrdersFlag = params?.cancelOrders ?? true;
@@ -1648,8 +1667,8 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
1648
1667
  const response = await fetch(url, {
1649
1668
  method: "DELETE",
1650
1669
  headers: {
1651
- "APCA-API-KEY-ID": APIKey,
1652
- "APCA-API-SECRET-KEY": APISecret,
1670
+ "APCA-API-KEY-ID": apiKey,
1671
+ "APCA-API-SECRET-KEY": apiSecret,
1653
1672
  },
1654
1673
  });
1655
1674
  if (!response.ok) {
@@ -1840,20 +1859,20 @@ async function closeAllPositionsAfterHours$1(auth, params = { cancel_orders: tru
1840
1859
  * @param props - The properties for fetching account details
1841
1860
  * @returns The account details
1842
1861
  */
1843
- async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, }) {
1844
- let alpacaAccountObj = alpacaAccount ? alpacaAccount : null;
1845
- if (!alpacaAccountObj && auth) {
1862
+ async function fetchAccountDetails({ accountId, client, brokerageAccount, auth, }) {
1863
+ let brokerageAccountObj = brokerageAccount ? brokerageAccount : null;
1864
+ if (!brokerageAccountObj && auth) {
1846
1865
  const validatedAuth = await validateAuth(auth);
1847
- alpacaAccountObj = {
1848
- APIKey: validatedAuth.APIKey,
1849
- APISecret: validatedAuth.APISecret,
1866
+ brokerageAccountObj = {
1867
+ apiKey: validatedAuth.apiKey,
1868
+ apiSecret: validatedAuth.apiSecret,
1850
1869
  type: validatedAuth.type,
1851
1870
  };
1852
1871
  }
1853
- if (!alpacaAccountObj) {
1872
+ if (!brokerageAccountObj) {
1854
1873
  try {
1855
1874
  const apolloClient = client || (await getSharedApolloClient());
1856
- alpacaAccountObj = (await adaptic$1.alpacaAccount.get({
1875
+ brokerageAccountObj = (await adaptic$1.brokerageAccount.get({
1857
1876
  id: accountId,
1858
1877
  }, apolloClient));
1859
1878
  }
@@ -1862,19 +1881,19 @@ async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, })
1862
1881
  throw error;
1863
1882
  }
1864
1883
  }
1865
- if (!alpacaAccountObj ||
1866
- !alpacaAccountObj.APIKey ||
1867
- !alpacaAccountObj.APISecret) {
1884
+ if (!brokerageAccountObj ||
1885
+ !brokerageAccountObj.apiKey ||
1886
+ !brokerageAccountObj.apiSecret) {
1868
1887
  throw new Error("[fetchAccountDetails] Alpaca account not found or incomplete");
1869
1888
  }
1870
- const { APIKey, APISecret, type } = alpacaAccountObj;
1889
+ const { apiKey, apiSecret, type } = brokerageAccountObj;
1871
1890
  const apiUrl = `${getTradingApiUrl(type)}/account`;
1872
1891
  try {
1873
1892
  const response = await fetch(apiUrl, {
1874
1893
  method: "GET",
1875
1894
  headers: {
1876
- "APCA-API-KEY-ID": APIKey,
1877
- "APCA-API-SECRET-KEY": APISecret,
1895
+ "APCA-API-KEY-ID": apiKey,
1896
+ "APCA-API-SECRET-KEY": apiSecret,
1878
1897
  "Content-Type": "application/json",
1879
1898
  },
1880
1899
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
@@ -1895,12 +1914,12 @@ async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, })
1895
1914
  * @param props - The properties for fetching portfolio history
1896
1915
  * @returns The portfolio history
1897
1916
  */
1898
- async function fetchPortfolioHistory({ params, accountId, client, alpacaAccount, }) {
1899
- let alpacaAccountObj = alpacaAccount ? alpacaAccount : null;
1900
- if (!alpacaAccountObj) {
1917
+ async function fetchPortfolioHistory({ params, accountId, client, brokerageAccount, }) {
1918
+ let brokerageAccountObj = brokerageAccount ? brokerageAccount : null;
1919
+ if (!brokerageAccountObj) {
1901
1920
  try {
1902
1921
  const apolloClient = client || (await getSharedApolloClient());
1903
- alpacaAccountObj = (await adaptic$1.alpacaAccount.get({
1922
+ brokerageAccountObj = (await adaptic$1.brokerageAccount.get({
1904
1923
  id: accountId,
1905
1924
  }, apolloClient));
1906
1925
  }
@@ -1909,12 +1928,12 @@ async function fetchPortfolioHistory({ params, accountId, client, alpacaAccount,
1909
1928
  throw error;
1910
1929
  }
1911
1930
  }
1912
- if (!alpacaAccountObj ||
1913
- !alpacaAccountObj.APIKey ||
1914
- !alpacaAccountObj.APISecret) {
1931
+ if (!brokerageAccountObj ||
1932
+ !brokerageAccountObj.apiKey ||
1933
+ !brokerageAccountObj.apiSecret) {
1915
1934
  throw new Error("[fetchPortfolioHistory] Alpaca account not found or incomplete");
1916
1935
  }
1917
- const { APIKey, APISecret, type } = alpacaAccountObj;
1936
+ const { apiKey, apiSecret, type } = brokerageAccountObj;
1918
1937
  const apiBaseUrl = getTradingApiUrl(type);
1919
1938
  const apiUrl = `${apiBaseUrl}/v2/account/portfolio/history`;
1920
1939
  const { start, end, period } = params;
@@ -1940,8 +1959,8 @@ async function fetchPortfolioHistory({ params, accountId, client, alpacaAccount,
1940
1959
  const response = await fetch(fullUrl, {
1941
1960
  method: "GET",
1942
1961
  headers: {
1943
- "APCA-API-KEY-ID": APIKey,
1944
- "APCA-API-SECRET-KEY": APISecret,
1962
+ "APCA-API-KEY-ID": apiKey,
1963
+ "APCA-API-SECRET-KEY": apiSecret,
1945
1964
  "Content-Type": "application/json",
1946
1965
  },
1947
1966
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
@@ -1968,31 +1987,31 @@ async function getConfiguration(account) {
1968
1987
  if (!account) {
1969
1988
  throw new Error(`Account is missing.`);
1970
1989
  }
1971
- const { APIKey, APISecret } = account;
1972
- if (!APIKey || !APISecret) {
1973
- throw new Error("User APIKey or APISecret is missing.");
1990
+ const { apiKey, apiSecret } = account;
1991
+ if (!apiKey || !apiSecret) {
1992
+ throw new Error("Account apiKey or apiSecret is missing.");
1974
1993
  }
1975
1994
  const apiUrl = getTradingApiUrl(account.type);
1976
1995
  const client = await getSharedApolloClient();
1977
- const [alpacaResponse, freshAlpacaAccount] = await Promise.all([
1996
+ const [alpacaResponse, freshBrokerageAccount] = await Promise.all([
1978
1997
  fetch(`${apiUrl}/account/configurations`, {
1979
1998
  method: "GET",
1980
1999
  headers: {
1981
- "APCA-API-KEY-ID": APIKey,
1982
- "APCA-API-SECRET-KEY": APISecret,
2000
+ "APCA-API-KEY-ID": apiKey,
2001
+ "APCA-API-SECRET-KEY": apiSecret,
1983
2002
  accept: "application/json",
1984
2003
  },
1985
2004
  }),
1986
- adaptic$1.alpacaAccount.get({ id: account.id }, client),
2005
+ adaptic$1.brokerageAccount.get({ id: account.id }, client),
1987
2006
  ]);
1988
2007
  if (!alpacaResponse.ok) {
1989
2008
  throw new Error(`Failed to fetch account configuration: ${alpacaResponse.statusText}`);
1990
2009
  }
1991
- if (!freshAlpacaAccount) {
2010
+ if (!freshBrokerageAccount) {
1992
2011
  throw new Error("Failed to get Alpaca Account from @adaptic/backend-legacy.");
1993
2012
  }
1994
2013
  const dataFromAlpaca = (await alpacaResponse.json());
1995
- const accountWithAllocation = freshAlpacaAccount;
2014
+ const accountWithAllocation = freshBrokerageAccount;
1996
2015
  const allocationData = accountWithAllocation.allocation || {
1997
2016
  stocks: 70,
1998
2017
  options: 0,
@@ -2003,26 +2022,26 @@ async function getConfiguration(account) {
2003
2022
  };
2004
2023
  const combinedConfig = {
2005
2024
  ...dataFromAlpaca,
2006
- marketOpen: freshAlpacaAccount.marketOpen,
2007
- realTime: freshAlpacaAccount.realTime,
2008
- tradeAllocationPct: freshAlpacaAccount.tradeAllocationPct,
2009
- minPercentageChange: freshAlpacaAccount.minPercentageChange,
2010
- volumeThreshold: freshAlpacaAccount.volumeThreshold,
2011
- cryptoTradingEnabled: freshAlpacaAccount.cryptoTradingEnabled ?? false,
2012
- cryptoTradingPairs: freshAlpacaAccount.cryptoTradingPairs ?? [],
2013
- cryptoTradeAllocationPct: freshAlpacaAccount.cryptoTradeAllocationPct ?? 5.0,
2025
+ marketOpen: freshBrokerageAccount.marketOpen,
2026
+ realTime: freshBrokerageAccount.realTime,
2027
+ tradeAllocationPct: freshBrokerageAccount.tradeAllocationPct,
2028
+ minPercentageChange: freshBrokerageAccount.minPercentageChange,
2029
+ volumeThreshold: freshBrokerageAccount.volumeThreshold,
2030
+ cryptoTradingEnabled: freshBrokerageAccount.cryptoTradingEnabled ?? false,
2031
+ cryptoTradingPairs: freshBrokerageAccount.cryptoTradingPairs ?? [],
2032
+ cryptoTradeAllocationPct: freshBrokerageAccount.cryptoTradeAllocationPct ?? 5.0,
2014
2033
  autoAllocation: accountWithAllocation.autoAllocation ?? false,
2015
2034
  allocation: allocationData,
2016
- enablePortfolioTrailingStop: freshAlpacaAccount.enablePortfolioTrailingStop,
2017
- portfolioTrailPercent: freshAlpacaAccount.portfolioTrailPercent,
2018
- portfolioProfitThresholdPercent: freshAlpacaAccount.portfolioProfitThresholdPercent,
2019
- reducedPortfolioTrailPercent: freshAlpacaAccount.reducedPortfolioTrailPercent,
2020
- defaultTrailingStopPercentage100: freshAlpacaAccount.defaultTrailingStopPercentage100 ?? 4.0,
2021
- firstTrailReductionThreshold100: freshAlpacaAccount.firstTrailReductionThreshold100 ?? 2.0,
2022
- secondTrailReductionThreshold100: freshAlpacaAccount.secondTrailReductionThreshold100 ?? 5.0,
2023
- firstReducedTrailPercentage100: freshAlpacaAccount.firstReducedTrailPercentage100 ?? 1.0,
2024
- secondReducedTrailPercentage100: freshAlpacaAccount.secondReducedTrailPercentage100 ?? 0.5,
2025
- minimumPriceChangePercent100: freshAlpacaAccount.minimumPriceChangePercent100 ?? 0.5,
2035
+ enablePortfolioTrailingStop: freshBrokerageAccount.enablePortfolioTrailingStop,
2036
+ portfolioTrailPercent: freshBrokerageAccount.portfolioTrailPercent,
2037
+ portfolioProfitThresholdPercent: freshBrokerageAccount.portfolioProfitThresholdPercent,
2038
+ reducedPortfolioTrailPercent: freshBrokerageAccount.reducedPortfolioTrailPercent,
2039
+ defaultTrailingStopPercentage100: freshBrokerageAccount.defaultTrailingStopPercentage100 ?? 4.0,
2040
+ firstTrailReductionThreshold100: freshBrokerageAccount.firstTrailReductionThreshold100 ?? 2.0,
2041
+ secondTrailReductionThreshold100: freshBrokerageAccount.secondTrailReductionThreshold100 ?? 5.0,
2042
+ firstReducedTrailPercentage100: freshBrokerageAccount.firstReducedTrailPercentage100 ?? 1.0,
2043
+ secondReducedTrailPercentage100: freshBrokerageAccount.secondReducedTrailPercentage100 ?? 0.5,
2044
+ minimumPriceChangePercent100: freshBrokerageAccount.minimumPriceChangePercent100 ?? 0.5,
2026
2045
  };
2027
2046
  return combinedConfig;
2028
2047
  }
@@ -2043,9 +2062,9 @@ async function updateConfiguration(user, account, updatedConfig) {
2043
2062
  if (!account) {
2044
2063
  throw new Error(`Account is missing.`);
2045
2064
  }
2046
- const { APIKey, APISecret } = account;
2047
- if (!APIKey || !APISecret) {
2048
- throw new Error("User APIKey or APISecret is missing.");
2065
+ const { apiKey, apiSecret } = account;
2066
+ if (!apiKey || !apiSecret) {
2067
+ throw new Error("Account apiKey or apiSecret is missing.");
2049
2068
  }
2050
2069
  const apiUrl = getTradingApiUrl(account.type);
2051
2070
  // Prepare the config object for Alpaca by removing DB-only fields
@@ -2073,8 +2092,8 @@ async function updateConfiguration(user, account, updatedConfig) {
2073
2092
  const alpacaUpdatePromise = fetch(`${apiUrl}/account/configurations`, {
2074
2093
  method: "PATCH",
2075
2094
  headers: {
2076
- "APCA-API-KEY-ID": APIKey,
2077
- "APCA-API-SECRET-KEY": APISecret,
2095
+ "APCA-API-KEY-ID": apiKey,
2096
+ "APCA-API-SECRET-KEY": apiSecret,
2078
2097
  "Content-Type": "application/json",
2079
2098
  accept: "application/json",
2080
2099
  },
@@ -2095,10 +2114,10 @@ async function updateConfiguration(user, account, updatedConfig) {
2095
2114
  if (account.allocation) {
2096
2115
  allocUpdatePromise = adaptic$1.allocation.update({
2097
2116
  id: account.allocation.id,
2098
- alpacaAccount: {
2117
+ brokerageAccount: {
2099
2118
  id: account.id,
2100
2119
  },
2101
- alpacaAccountId: account.id,
2120
+ brokerageAccountId: account.id,
2102
2121
  stocks: updatedConfig.allocation.stocks ?? 0,
2103
2122
  options: updatedConfig.allocation.options ?? 0,
2104
2123
  futures: updatedConfig.allocation.futures ?? 0,
@@ -2115,14 +2134,14 @@ async function updateConfiguration(user, account, updatedConfig) {
2115
2134
  etfs: updatedConfig.allocation.etfs ?? 0,
2116
2135
  forex: updatedConfig.allocation.forex ?? 0,
2117
2136
  crypto: updatedConfig.allocation.crypto ?? 0,
2118
- alpacaAccount: {
2137
+ brokerageAccount: {
2119
2138
  id: account.id,
2120
2139
  },
2121
- alpacaAccountId: account.id,
2140
+ brokerageAccountId: account.id,
2122
2141
  }, client);
2123
2142
  }
2124
2143
  }
2125
- const adapticUpdatePromise = adaptic$1.alpacaAccount.update({
2144
+ const adapticUpdatePromise = adaptic$1.brokerageAccount.update({
2126
2145
  id: account.id,
2127
2146
  user: {
2128
2147
  id: user.id,
@@ -2149,7 +2168,7 @@ async function updateConfiguration(user, account, updatedConfig) {
2149
2168
  secondReducedTrailPercentage100: updatedConfig.secondReducedTrailPercentage100 ?? 0,
2150
2169
  minimumPriceChangePercent100: updatedConfig.minimumPriceChangePercent100 ?? 0,
2151
2170
  }, client);
2152
- const [alpacaResponse, updatedAlpacaAccount, updatedAllocation] = await Promise.all([
2171
+ const [alpacaResponse, updatedBrokerageAccount, updatedAllocation] = await Promise.all([
2153
2172
  alpacaUpdatePromise,
2154
2173
  adapticUpdatePromise,
2155
2174
  allocUpdatePromise,
@@ -2169,10 +2188,10 @@ async function updateConfiguration(user, account, updatedConfig) {
2169
2188
  throw new Error(`Failed to update account config at Alpaca: ${alpacaResponse.statusText}`);
2170
2189
  }
2171
2190
  const alpacaData = (await alpacaResponse.json());
2172
- if (!updatedAlpacaAccount) {
2191
+ if (!updatedBrokerageAccount) {
2173
2192
  throw new Error("Failed to update Alpaca Account in @adaptic/backend-legacy.");
2174
2193
  }
2175
- const updatedAccountWithAllocation = updatedAlpacaAccount;
2194
+ const updatedAccountWithAllocation = updatedBrokerageAccount;
2176
2195
  const selectedAllocation = (updatedConfig.allocation ||
2177
2196
  updatedAllocation ||
2178
2197
  updatedAccountWithAllocation.allocation);
@@ -2182,26 +2201,26 @@ async function updateConfiguration(user, account, updatedConfig) {
2182
2201
  getLogger().info("Final allocation:", selectedAllocation);
2183
2202
  const finalConfig = {
2184
2203
  ...alpacaData,
2185
- marketOpen: updatedAlpacaAccount.marketOpen,
2186
- realTime: updatedAlpacaAccount.realTime,
2187
- tradeAllocationPct: updatedAlpacaAccount.tradeAllocationPct,
2188
- minPercentageChange: updatedAlpacaAccount.minPercentageChange,
2189
- volumeThreshold: updatedAlpacaAccount.volumeThreshold,
2190
- cryptoTradingEnabled: updatedAlpacaAccount.cryptoTradingEnabled,
2191
- cryptoTradingPairs: updatedAlpacaAccount.cryptoTradingPairs,
2192
- cryptoTradeAllocationPct: updatedAlpacaAccount.cryptoTradeAllocationPct,
2204
+ marketOpen: updatedBrokerageAccount.marketOpen,
2205
+ realTime: updatedBrokerageAccount.realTime,
2206
+ tradeAllocationPct: updatedBrokerageAccount.tradeAllocationPct,
2207
+ minPercentageChange: updatedBrokerageAccount.minPercentageChange,
2208
+ volumeThreshold: updatedBrokerageAccount.volumeThreshold,
2209
+ cryptoTradingEnabled: updatedBrokerageAccount.cryptoTradingEnabled,
2210
+ cryptoTradingPairs: updatedBrokerageAccount.cryptoTradingPairs,
2211
+ cryptoTradeAllocationPct: updatedBrokerageAccount.cryptoTradeAllocationPct,
2193
2212
  autoAllocation: updatedAccountWithAllocation.autoAllocation,
2194
2213
  allocation: selectedAllocation,
2195
- enablePortfolioTrailingStop: updatedAlpacaAccount.enablePortfolioTrailingStop,
2196
- portfolioTrailPercent: updatedAlpacaAccount.portfolioTrailPercent,
2197
- portfolioProfitThresholdPercent: updatedAlpacaAccount.portfolioProfitThresholdPercent,
2198
- reducedPortfolioTrailPercent: updatedAlpacaAccount.reducedPortfolioTrailPercent,
2199
- defaultTrailingStopPercentage100: updatedAlpacaAccount.defaultTrailingStopPercentage100,
2200
- firstTrailReductionThreshold100: updatedAlpacaAccount.firstTrailReductionThreshold100,
2201
- secondTrailReductionThreshold100: updatedAlpacaAccount.secondTrailReductionThreshold100,
2202
- firstReducedTrailPercentage100: updatedAlpacaAccount.firstReducedTrailPercentage100,
2203
- secondReducedTrailPercentage100: updatedAlpacaAccount.secondReducedTrailPercentage100,
2204
- minimumPriceChangePercent100: updatedAlpacaAccount.minimumPriceChangePercent100,
2214
+ enablePortfolioTrailingStop: updatedBrokerageAccount.enablePortfolioTrailingStop,
2215
+ portfolioTrailPercent: updatedBrokerageAccount.portfolioTrailPercent,
2216
+ portfolioProfitThresholdPercent: updatedBrokerageAccount.portfolioProfitThresholdPercent,
2217
+ reducedPortfolioTrailPercent: updatedBrokerageAccount.reducedPortfolioTrailPercent,
2218
+ defaultTrailingStopPercentage100: updatedBrokerageAccount.defaultTrailingStopPercentage100,
2219
+ firstTrailReductionThreshold100: updatedBrokerageAccount.firstTrailReductionThreshold100,
2220
+ secondTrailReductionThreshold100: updatedBrokerageAccount.secondTrailReductionThreshold100,
2221
+ firstReducedTrailPercentage100: updatedBrokerageAccount.firstReducedTrailPercentage100,
2222
+ secondReducedTrailPercentage100: updatedBrokerageAccount.secondReducedTrailPercentage100,
2223
+ minimumPriceChangePercent100: updatedBrokerageAccount.minimumPriceChangePercent100,
2205
2224
  };
2206
2225
  return finalConfig;
2207
2226
  }
@@ -2219,15 +2238,15 @@ async function updateConfiguration(user, account, updatedConfig) {
2219
2238
  */
2220
2239
  async function getAsset(auth, symbolOrAssetId) {
2221
2240
  try {
2222
- const { APIKey, APISecret, type } = await validateAuth(auth);
2241
+ const { apiKey, apiSecret, type } = await validateAuth(auth);
2223
2242
  const apiBaseUrl = getTradingApiUrl(type);
2224
2243
  // Use encodeURIComponent to handle special characters in symbols (e.g., BTC/USDT)
2225
2244
  const encodedSymbolOrAssetId = encodeURIComponent(symbolOrAssetId);
2226
2245
  const response = await fetch(`${apiBaseUrl}/v2/assets/${encodedSymbolOrAssetId}`, {
2227
2246
  method: "GET",
2228
2247
  headers: {
2229
- "APCA-API-KEY-ID": APIKey,
2230
- "APCA-API-SECRET-KEY": APISecret,
2248
+ "APCA-API-KEY-ID": apiKey,
2249
+ "APCA-API-SECRET-KEY": apiSecret,
2231
2250
  "Content-Type": "application/json",
2232
2251
  },
2233
2252
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
@@ -3284,24 +3303,24 @@ async function calculateTotalReturnYTD(portfolioHistory) {
3284
3303
  * Calculates the expense ratio for a given Alpaca account.
3285
3304
  * @param accountId - The ID of the Alpaca account.
3286
3305
  * @param client - The Apollo client instance.
3287
- * @param alpacaAccount - The Alpaca account object.
3306
+ * @param brokerageAccount - The Alpaca account object.
3288
3307
  * @returns A promise that resolves to a string representing the expense ratio in percentage format.
3289
3308
  */
3290
- async function calculateExpenseRatio$1({ accountId, client, alpacaAccount, }) {
3291
- if (!accountId && !alpacaAccount && !client) {
3309
+ async function calculateExpenseRatio$1({ accountId, client, brokerageAccount, }) {
3310
+ if (!accountId && !brokerageAccount && !client) {
3292
3311
  getLogger().warn("Missing account ID or client to calculate expense ratio.");
3293
3312
  return "N/A";
3294
3313
  }
3295
- let alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
3314
+ let brokerageAccountId = accountId || (brokerageAccount && brokerageAccount.id) || "";
3296
3315
  let accountDetails;
3297
- if (!alpacaAccountId) {
3316
+ if (!brokerageAccountId) {
3298
3317
  getLogger().warn("Invalid account ID.");
3299
3318
  return "N/A";
3300
3319
  }
3301
- if (alpacaAccount) {
3320
+ if (brokerageAccount) {
3302
3321
  // Use Alpaca account object to get accountDetails
3303
3322
  accountDetails = (await fetchAccountDetails({
3304
- alpacaAccount: alpacaAccount,
3323
+ brokerageAccount: brokerageAccount,
3305
3324
  }));
3306
3325
  if (!accountDetails) {
3307
3326
  getLogger().warn("Failed to fetch account details inside calculateExpenseRatio.");
@@ -3340,24 +3359,24 @@ async function getPortfolioExpensesFromYourSystem(accountId) {
3340
3359
  * Calculates the liquidity ratio for a given Alpaca account.
3341
3360
  * @param accountId - The ID of the Alpaca account.
3342
3361
  * @param client - The Apollo client instance.
3343
- * @param alpacaAccount - The Alpaca account object.
3362
+ * @param brokerageAccount - The Alpaca account object.
3344
3363
  * @returns A promise that resolves to a string representing the liquidity ratio in the format "1:ratio".
3345
3364
  */
3346
- async function calculateLiquidityRatio({ accountId, client, alpacaAccount, }) {
3347
- if (!accountId && !alpacaAccount && !client) {
3365
+ async function calculateLiquidityRatio({ accountId, client, brokerageAccount, }) {
3366
+ if (!accountId && !brokerageAccount && !client) {
3348
3367
  getLogger().warn("Missing account ID or client to calculateLiquidityRatio.");
3349
3368
  return "N/A";
3350
3369
  }
3351
- let alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
3370
+ let brokerageAccountId = accountId || (brokerageAccount && brokerageAccount.id) || "";
3352
3371
  let accountDetails;
3353
- if (!alpacaAccountId) {
3372
+ if (!brokerageAccountId) {
3354
3373
  getLogger().warn("Invalid account ID.");
3355
3374
  return "N/A";
3356
3375
  }
3357
- if (alpacaAccount) {
3376
+ if (brokerageAccount) {
3358
3377
  // Use Alpaca account object to get accountDetails
3359
3378
  accountDetails = (await fetchAccountDetails({
3360
- alpacaAccount: alpacaAccount,
3379
+ brokerageAccount: brokerageAccount,
3361
3380
  }));
3362
3381
  if (!accountDetails) {
3363
3382
  getLogger().warn("Failed to fetch account details inside calculateLiquidityRatio.");
@@ -3985,11 +4004,11 @@ async function calculateInformationRatio$1(portfolioHistory, benchmarkBars) {
3985
4004
  * @param params - The parameters for fetching performance metrics.
3986
4005
  * @param client - The Apollo client instance.
3987
4006
  * @param accountId - The ID of the Alpaca account.
3988
- * @param alpacaAccount - The Alpaca account object.
4007
+ * @param brokerageAccount - The Alpaca account object.
3989
4008
  * @returns A promise that resolves to an object containing various performance metrics.
3990
4009
  * @throws Will throw an error if required parameters are missing or if fetching fails.
3991
4010
  */
3992
- async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccount, }) {
4011
+ async function fetchPerformanceMetrics({ params, client, accountId, brokerageAccount, }) {
3993
4012
  // Default response for error cases
3994
4013
  const defaultMetrics = {
3995
4014
  totalReturnYTD: "N/A",
@@ -4012,12 +4031,12 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
4012
4031
  throw new Error("Missing required timeframe or period parameters");
4013
4032
  }
4014
4033
  // Obtain Alpaca account
4015
- let alpacaAccountObj = alpacaAccount ? alpacaAccount : null;
4016
- if (!alpacaAccountObj && accountId) {
4034
+ let brokerageAccountObj = brokerageAccount ? brokerageAccount : null;
4035
+ if (!brokerageAccountObj && accountId) {
4017
4036
  try {
4018
4037
  // Use provided client or get the shared client
4019
4038
  const apolloClient = client || (await getSharedApolloClient());
4020
- alpacaAccountObj = (await adaptic$1.alpacaAccount.get({
4039
+ brokerageAccountObj = (await adaptic$1.brokerageAccount.get({
4021
4040
  id: accountId,
4022
4041
  }, apolloClient));
4023
4042
  }
@@ -4027,9 +4046,9 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
4027
4046
  }
4028
4047
  }
4029
4048
  // Validate Alpaca account
4030
- if (!alpacaAccountObj ||
4031
- !alpacaAccountObj.APIKey ||
4032
- !alpacaAccountObj.APISecret) {
4049
+ if (!brokerageAccountObj ||
4050
+ !brokerageAccountObj.apiKey ||
4051
+ !brokerageAccountObj.apiSecret) {
4033
4052
  throw new Error("Alpaca account not found or credentials missing");
4034
4053
  }
4035
4054
  // Fetch portfolio history with structured error handling
@@ -4037,7 +4056,7 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
4037
4056
  try {
4038
4057
  portfolioHistory = await fetchPortfolioHistory({
4039
4058
  params: params,
4040
- alpacaAccount: alpacaAccountObj,
4059
+ brokerageAccount: brokerageAccountObj,
4041
4060
  });
4042
4061
  }
4043
4062
  catch (error) {
@@ -4087,10 +4106,10 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
4087
4106
  calculateInformationRatio$1(portfolioHistory, benchmarkBars),
4088
4107
  calculateRiskAdjustedReturn$1(portfolioHistory),
4089
4108
  calculateLiquidityRatio({
4090
- alpacaAccount: alpacaAccountObj,
4109
+ brokerageAccount: brokerageAccountObj,
4091
4110
  }),
4092
4111
  calculateExpenseRatio$1({
4093
- alpacaAccount: alpacaAccountObj,
4112
+ brokerageAccount: brokerageAccountObj,
4094
4113
  }),
4095
4114
  getDividendYield(),
4096
4115
  calculateMaxDrawdown$1(portfolioHistory.equity),
@@ -4310,15 +4329,15 @@ const timeDiffString = (milliseconds) => {
4310
4329
  };
4311
4330
 
4312
4331
  // price-utils.ts
4313
- const calculateFees = async (action, trade, alpacaAccount) => {
4332
+ const calculateFees = async (action, trade, brokerageAccount) => {
4314
4333
  let fee = 0;
4315
4334
  const alpacaOrderId = action.alpacaOrderId;
4316
4335
  if (!alpacaOrderId)
4317
4336
  return fee;
4318
4337
  const order = await getOrder$1({
4319
- adapticAccountId: trade.alpacaAccountId,
4320
- alpacaApiKey: alpacaAccount.APIKey,
4321
- alpacaApiSecret: alpacaAccount.APISecret,
4338
+ adapticAccountId: trade.brokerageAccountId,
4339
+ alpacaApiKey: brokerageAccount.apiKey,
4340
+ alpacaApiSecret: brokerageAccount.apiSecret,
4322
4341
  }, alpacaOrderId);
4323
4342
  if (!order)
4324
4343
  return fee;
@@ -4356,13 +4375,13 @@ const calculateFees = async (action, trade, alpacaAccount) => {
4356
4375
  };
4357
4376
  const computeTotalFees = async (trade) => {
4358
4377
  let totalFees = 0;
4359
- // fetch alpaca account details using adaptic.alpacaAccount.get({id: trade.alpacaAccountId})
4360
- const alpacaAccount = (await adaptic$1.alpacaAccount.get({
4361
- id: trade.alpacaAccountId,
4378
+ // fetch alpaca account details using adaptic.brokerageAccount.get({id: trade.brokerageAccountId})
4379
+ const brokerageAccount = (await adaptic$1.brokerageAccount.get({
4380
+ id: trade.brokerageAccountId,
4362
4381
  }));
4363
- if (!alpacaAccount)
4382
+ if (!brokerageAccount)
4364
4383
  return totalFees;
4365
- const feePromises = trade?.actions?.map((action) => calculateFees(action, trade, alpacaAccount));
4384
+ const feePromises = trade?.actions?.map((action) => calculateFees(action, trade, brokerageAccount));
4366
4385
  const fees = await Promise.all(feePromises || []);
4367
4386
  totalFees = fees.reduce((acc, fee) => acc + fee, 0);
4368
4387
  return totalFees;
@@ -6109,7 +6128,7 @@ async function fetchBars(params) {
6109
6128
  */
6110
6129
  async function fetchNews(params, auth) {
6111
6130
  const { symbol, start = new Date(Date.now() - 24 * 60 * 60 * 1000), sort = "desc", includeContent = false, limit = 1000, } = params;
6112
- if (!auth.APIKey || !auth.APISecret) {
6131
+ if (!auth.alpacaApiKey || !auth.alpacaApiSecret) {
6113
6132
  throw new Error("Alpaca API key and secret are required");
6114
6133
  }
6115
6134
  if (!symbol) {
@@ -6177,7 +6196,7 @@ async function fetchNews(params, auth) {
6177
6196
  */
6178
6197
  async function fetchLatestTrades(params, auth) {
6179
6198
  const { symbols, loc = "us" } = params;
6180
- if (!auth.APIKey || !auth.APISecret) {
6199
+ if (!auth.alpacaApiKey || !auth.alpacaApiSecret) {
6181
6200
  throw new Error("Alpaca API key and secret are required");
6182
6201
  }
6183
6202
  if (!symbols || symbols.length === 0) {
@@ -6193,8 +6212,8 @@ async function fetchLatestTrades(params, auth) {
6193
6212
  return withRetry(async () => {
6194
6213
  const response = await fetch(url, {
6195
6214
  headers: {
6196
- "APCA-API-KEY-ID": auth.APIKey,
6197
- "APCA-API-SECRET-KEY": auth.APISecret,
6215
+ "APCA-API-KEY-ID": auth.alpacaApiKey,
6216
+ "APCA-API-SECRET-KEY": auth.alpacaApiSecret,
6198
6217
  },
6199
6218
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
6200
6219
  });
@@ -6220,7 +6239,7 @@ async function fetchLatestTrades(params, auth) {
6220
6239
  */
6221
6240
  async function fetchLatestQuotes(params, auth) {
6222
6241
  const { symbols, loc = "us" } = params;
6223
- if (!auth.APIKey || !auth.APISecret) {
6242
+ if (!auth.alpacaApiKey || !auth.alpacaApiSecret) {
6224
6243
  throw new Error("Alpaca API key and secret are required");
6225
6244
  }
6226
6245
  if (!symbols || symbols.length === 0) {
@@ -6236,8 +6255,8 @@ async function fetchLatestQuotes(params, auth) {
6236
6255
  return withRetry(async () => {
6237
6256
  const response = await fetch(url, {
6238
6257
  headers: {
6239
- "APCA-API-KEY-ID": auth.APIKey,
6240
- "APCA-API-SECRET-KEY": auth.APISecret,
6258
+ "APCA-API-KEY-ID": auth.alpacaApiKey,
6259
+ "APCA-API-SECRET-KEY": auth.alpacaApiSecret,
6241
6260
  },
6242
6261
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
6243
6262
  });
@@ -12283,6 +12302,8 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12283
12302
  dataURL;
12284
12303
  apiURL;
12285
12304
  v1beta1url;
12305
+ /** Whether API credentials are valid and available. False during build time when env vars are missing. */
12306
+ credentialsValid = false;
12286
12307
  stockStreamUrl = getStockStreamUrl("PRODUCTION"); // production values
12287
12308
  optionStreamUrl = getOptionsStreamUrl("PRODUCTION"); // production values
12288
12309
  cryptoStreamUrl = getCryptoStreamUrl("PRODUCTION"); // production values
@@ -12338,13 +12359,16 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12338
12359
  constructor() {
12339
12360
  super();
12340
12361
  // Validate credentials from environment variables before initializing
12341
- const apiKey = process.env.ALPACA_API_KEY;
12342
- const apiSecret = process.env.ALPACA_SECRET_KEY;
12343
- validateAlpacaCredentials({
12362
+ // Use throwOnMissing: false to allow initialization during build time
12363
+ // when env vars are not available. Features will be unavailable until
12364
+ // credentials are provided at runtime.
12365
+ const apiKey = process.env.ALPACA_API_KEY || "";
12366
+ const apiSecret = process.env.ALPACA_SECRET_KEY || "";
12367
+ this.credentialsValid = validateAlpacaCredentials({
12344
12368
  apiKey,
12345
12369
  apiSecret,
12346
12370
  isPaper: process.env.ALPACA_ACCOUNT_TYPE === "PAPER",
12347
- });
12371
+ }, { throwOnMissing: false });
12348
12372
  this.dataURL = MARKET_DATA_API.STOCKS;
12349
12373
  this.apiURL =
12350
12374
  process.env.ALPACA_ACCOUNT_TYPE === "PAPER"