@adaptic/utils 0.1.3 → 0.1.41
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 +171 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +171 -171
- package/dist/index.mjs.map +1 -1
- package/dist/types/alpaca/legacy/account.d.ts +4 -4
- package/dist/types/alpaca/legacy/account.d.ts.map +1 -1
- package/dist/types/alpaca/legacy/auth.d.ts +2 -2
- package/dist/types/crypto.d.ts +2 -2
- package/dist/types/crypto.d.ts.map +1 -1
- package/dist/types/performance-metrics.d.ts +2 -2
- package/dist/types/performance-metrics.d.ts.map +1 -1
- package/dist/types/types/alpaca-types.d.ts +6 -6
- package/dist/types/types/alpaca-types.d.ts.map +1 -1
- package/dist/types/types/metrics-types.d.ts +1 -1
- package/dist/types/types/metrics-types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -388,21 +388,21 @@ function validateAlphaVantageApiKey(apiKey) {
|
|
|
388
388
|
async function validateAuth(auth) {
|
|
389
389
|
if (auth.adapticAccountId) {
|
|
390
390
|
const client = await getSharedApolloClient();
|
|
391
|
-
const
|
|
391
|
+
const brokerageAccount = (await adaptic$1.brokerageAccount.get({
|
|
392
392
|
id: auth.adapticAccountId,
|
|
393
393
|
}, client));
|
|
394
|
-
if (!
|
|
394
|
+
if (!brokerageAccount || !brokerageAccount.apiKey || !brokerageAccount.apiSecret) {
|
|
395
395
|
throw new Error("Alpaca account not found or incomplete");
|
|
396
396
|
}
|
|
397
397
|
validateAlpacaCredentials({
|
|
398
|
-
apiKey:
|
|
399
|
-
apiSecret:
|
|
400
|
-
isPaper:
|
|
398
|
+
apiKey: brokerageAccount.apiKey,
|
|
399
|
+
apiSecret: brokerageAccount.apiSecret,
|
|
400
|
+
isPaper: brokerageAccount.type === "PAPER",
|
|
401
401
|
});
|
|
402
402
|
return {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
type:
|
|
403
|
+
apiKey: brokerageAccount.apiKey,
|
|
404
|
+
apiSecret: brokerageAccount.apiSecret,
|
|
405
|
+
type: brokerageAccount.type,
|
|
406
406
|
};
|
|
407
407
|
}
|
|
408
408
|
else if (auth.alpacaApiKey && auth.alpacaApiSecret) {
|
|
@@ -411,8 +411,8 @@ async function validateAuth(auth) {
|
|
|
411
411
|
apiKey: auth.alpacaApiKey,
|
|
412
412
|
apiSecret: auth.alpacaApiSecret});
|
|
413
413
|
return {
|
|
414
|
-
|
|
415
|
-
|
|
414
|
+
apiKey: auth.alpacaApiKey,
|
|
415
|
+
apiSecret: auth.alpacaApiSecret,
|
|
416
416
|
type: accountType,
|
|
417
417
|
};
|
|
418
418
|
}
|
|
@@ -583,11 +583,11 @@ const ORDER_CHUNK_SIZE = 500;
|
|
|
583
583
|
async function makeRequest(auth, params) {
|
|
584
584
|
const { endpoint, method, body, queryString, apiBaseUrl } = params;
|
|
585
585
|
try {
|
|
586
|
-
const {
|
|
586
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
587
587
|
const apiBaseUrlInner = apiBaseUrl
|
|
588
588
|
? apiBaseUrl
|
|
589
589
|
: getTradingApiUrl(type);
|
|
590
|
-
if (!
|
|
590
|
+
if (!apiKey || !apiSecret) {
|
|
591
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.");
|
|
592
592
|
}
|
|
593
593
|
const url = `${apiBaseUrlInner}${endpoint}${queryString || ""}`;
|
|
@@ -598,8 +598,8 @@ async function makeRequest(auth, params) {
|
|
|
598
598
|
const fetchOptions = {
|
|
599
599
|
method,
|
|
600
600
|
headers: {
|
|
601
|
-
"APCA-API-KEY-ID":
|
|
602
|
-
"APCA-API-SECRET-KEY":
|
|
601
|
+
"APCA-API-KEY-ID": apiKey,
|
|
602
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
603
603
|
},
|
|
604
604
|
};
|
|
605
605
|
// Only add Content-Type and body for non-GET/HEAD requests that have a body
|
|
@@ -643,13 +643,13 @@ async function makeRequest(auth, params) {
|
|
|
643
643
|
*/
|
|
644
644
|
async function createOrder$1(auth, params) {
|
|
645
645
|
try {
|
|
646
|
-
const {
|
|
646
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
647
647
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
648
648
|
const response = await fetch(`${apiBaseUrl}/v2/orders`, {
|
|
649
649
|
method: "POST",
|
|
650
650
|
headers: {
|
|
651
|
-
"APCA-API-KEY-ID":
|
|
652
|
-
"APCA-API-SECRET-KEY":
|
|
651
|
+
"APCA-API-KEY-ID": apiKey,
|
|
652
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
653
653
|
"Content-Type": "application/json",
|
|
654
654
|
},
|
|
655
655
|
body: JSON.stringify(params),
|
|
@@ -674,7 +674,7 @@ async function createOrder$1(auth, params) {
|
|
|
674
674
|
*/
|
|
675
675
|
async function getOrders$1(auth, params = {}) {
|
|
676
676
|
try {
|
|
677
|
-
const {
|
|
677
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
678
678
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
679
679
|
const allOrders = [];
|
|
680
680
|
let currentUntil = params.until ? params.until : new Date().toISOString();
|
|
@@ -697,8 +697,8 @@ async function getOrders$1(auth, params = {}) {
|
|
|
697
697
|
const response = await fetch(`${apiBaseUrl}/v2/orders?${queryParams}`, {
|
|
698
698
|
method: "GET",
|
|
699
699
|
headers: {
|
|
700
|
-
"APCA-API-KEY-ID":
|
|
701
|
-
"APCA-API-SECRET-KEY":
|
|
700
|
+
"APCA-API-KEY-ID": apiKey,
|
|
701
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
702
702
|
},
|
|
703
703
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
704
704
|
});
|
|
@@ -730,13 +730,13 @@ async function getOrders$1(auth, params = {}) {
|
|
|
730
730
|
*/
|
|
731
731
|
async function cancelAllOrders$1(auth) {
|
|
732
732
|
try {
|
|
733
|
-
const {
|
|
733
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
734
734
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
735
735
|
const response = await fetch(`${apiBaseUrl}/v2/orders`, {
|
|
736
736
|
method: "DELETE",
|
|
737
737
|
headers: {
|
|
738
|
-
"APCA-API-KEY-ID":
|
|
739
|
-
"APCA-API-SECRET-KEY":
|
|
738
|
+
"APCA-API-KEY-ID": apiKey,
|
|
739
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
740
740
|
},
|
|
741
741
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
742
742
|
});
|
|
@@ -760,7 +760,7 @@ async function cancelAllOrders$1(auth) {
|
|
|
760
760
|
*/
|
|
761
761
|
async function getOrder$1(auth, orderId, nested) {
|
|
762
762
|
try {
|
|
763
|
-
const {
|
|
763
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
764
764
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
765
765
|
const queryParams = new URLSearchParams();
|
|
766
766
|
if (nested)
|
|
@@ -768,8 +768,8 @@ async function getOrder$1(auth, orderId, nested) {
|
|
|
768
768
|
const response = await fetch(`${apiBaseUrl}/v2/orders/${orderId}?${queryParams}`, {
|
|
769
769
|
method: "GET",
|
|
770
770
|
headers: {
|
|
771
|
-
"APCA-API-KEY-ID":
|
|
772
|
-
"APCA-API-SECRET-KEY":
|
|
771
|
+
"APCA-API-KEY-ID": apiKey,
|
|
772
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
773
773
|
},
|
|
774
774
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
775
775
|
});
|
|
@@ -793,13 +793,13 @@ async function getOrder$1(auth, orderId, nested) {
|
|
|
793
793
|
*/
|
|
794
794
|
async function replaceOrder$1(auth, orderId, params) {
|
|
795
795
|
try {
|
|
796
|
-
const {
|
|
796
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
797
797
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
798
798
|
const response = await fetch(`${apiBaseUrl}/v2/orders/${orderId}`, {
|
|
799
799
|
method: "PATCH",
|
|
800
800
|
headers: {
|
|
801
|
-
"APCA-API-KEY-ID":
|
|
802
|
-
"APCA-API-SECRET-KEY":
|
|
801
|
+
"APCA-API-KEY-ID": apiKey,
|
|
802
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
803
803
|
"Content-Type": "application/json",
|
|
804
804
|
accept: "application/json",
|
|
805
805
|
},
|
|
@@ -825,13 +825,13 @@ async function replaceOrder$1(auth, orderId, params) {
|
|
|
825
825
|
*/
|
|
826
826
|
async function cancelOrder$1(auth, orderId) {
|
|
827
827
|
try {
|
|
828
|
-
const {
|
|
828
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
829
829
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
830
830
|
const response = await fetch(`${apiBaseUrl}/v2/orders/${orderId}`, {
|
|
831
831
|
method: "DELETE",
|
|
832
832
|
headers: {
|
|
833
|
-
"APCA-API-KEY-ID":
|
|
834
|
-
"APCA-API-SECRET-KEY":
|
|
833
|
+
"APCA-API-KEY-ID": apiKey,
|
|
834
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
835
835
|
},
|
|
836
836
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
837
837
|
});
|
|
@@ -1413,14 +1413,14 @@ async function fetchNews$1(symbols, params) {
|
|
|
1413
1413
|
}
|
|
1414
1414
|
else if (mergedParams.auth.adapticAccountId) {
|
|
1415
1415
|
const client = await getSharedApolloClient();
|
|
1416
|
-
const
|
|
1416
|
+
const brokerageAccount = (await adaptic$1.brokerageAccount.get({
|
|
1417
1417
|
id: mergedParams.auth.adapticAccountId,
|
|
1418
1418
|
}, client));
|
|
1419
|
-
if (!
|
|
1419
|
+
if (!brokerageAccount || !brokerageAccount.apiKey || !brokerageAccount.apiSecret) {
|
|
1420
1420
|
throw new Error("Alpaca account not found or incomplete");
|
|
1421
1421
|
}
|
|
1422
|
-
APIKey =
|
|
1423
|
-
APISecret =
|
|
1422
|
+
APIKey = brokerageAccount.apiKey;
|
|
1423
|
+
APISecret = brokerageAccount.apiSecret;
|
|
1424
1424
|
}
|
|
1425
1425
|
}
|
|
1426
1426
|
else {
|
|
@@ -1513,14 +1513,14 @@ async function fetchNews$1(symbols, params) {
|
|
|
1513
1513
|
*/
|
|
1514
1514
|
async function fetchAllPositions(auth) {
|
|
1515
1515
|
try {
|
|
1516
|
-
const {
|
|
1516
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
1517
1517
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
1518
1518
|
const apiUrl = `${apiBaseUrl}/v2/positions`;
|
|
1519
1519
|
const response = await fetch(apiUrl, {
|
|
1520
1520
|
method: "GET",
|
|
1521
1521
|
headers: {
|
|
1522
|
-
"APCA-API-KEY-ID":
|
|
1523
|
-
"APCA-API-SECRET-KEY":
|
|
1522
|
+
"APCA-API-KEY-ID": apiKey,
|
|
1523
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
1524
1524
|
"Content-Type": "application/json",
|
|
1525
1525
|
},
|
|
1526
1526
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
@@ -1544,13 +1544,13 @@ async function fetchAllPositions(auth) {
|
|
|
1544
1544
|
*/
|
|
1545
1545
|
async function fetchPosition(auth, symbolOrAssetId) {
|
|
1546
1546
|
try {
|
|
1547
|
-
const {
|
|
1547
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
1548
1548
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
1549
1549
|
const response = await fetch(`${apiBaseUrl}/v2/positions/${symbolOrAssetId}`, {
|
|
1550
1550
|
method: "GET",
|
|
1551
1551
|
headers: {
|
|
1552
|
-
"APCA-API-KEY-ID":
|
|
1553
|
-
"APCA-API-SECRET-KEY":
|
|
1552
|
+
"APCA-API-KEY-ID": apiKey,
|
|
1553
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
1554
1554
|
"Content-Type": "application/json",
|
|
1555
1555
|
},
|
|
1556
1556
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
@@ -1584,7 +1584,7 @@ async function fetchPosition(auth, symbolOrAssetId) {
|
|
|
1584
1584
|
*/
|
|
1585
1585
|
async function closePosition$1(auth, symbolOrAssetId, params) {
|
|
1586
1586
|
try {
|
|
1587
|
-
const {
|
|
1587
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
1588
1588
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
1589
1589
|
const useLimitOrder = params?.useLimitOrder ?? false;
|
|
1590
1590
|
const cancelOrdersFlag = params?.cancelOrders ?? true;
|
|
@@ -1667,8 +1667,8 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
|
|
|
1667
1667
|
const response = await fetch(url, {
|
|
1668
1668
|
method: "DELETE",
|
|
1669
1669
|
headers: {
|
|
1670
|
-
"APCA-API-KEY-ID":
|
|
1671
|
-
"APCA-API-SECRET-KEY":
|
|
1670
|
+
"APCA-API-KEY-ID": apiKey,
|
|
1671
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
1672
1672
|
},
|
|
1673
1673
|
});
|
|
1674
1674
|
if (!response.ok) {
|
|
@@ -1859,20 +1859,20 @@ async function closeAllPositionsAfterHours$1(auth, params = { cancel_orders: tru
|
|
|
1859
1859
|
* @param props - The properties for fetching account details
|
|
1860
1860
|
* @returns The account details
|
|
1861
1861
|
*/
|
|
1862
|
-
async function fetchAccountDetails({ accountId, client,
|
|
1863
|
-
let
|
|
1864
|
-
if (!
|
|
1862
|
+
async function fetchAccountDetails({ accountId, client, brokerageAccount, auth, }) {
|
|
1863
|
+
let brokerageAccountObj = brokerageAccount ? brokerageAccount : null;
|
|
1864
|
+
if (!brokerageAccountObj && auth) {
|
|
1865
1865
|
const validatedAuth = await validateAuth(auth);
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1866
|
+
brokerageAccountObj = {
|
|
1867
|
+
apiKey: validatedAuth.apiKey,
|
|
1868
|
+
apiSecret: validatedAuth.apiSecret,
|
|
1869
1869
|
type: validatedAuth.type,
|
|
1870
1870
|
};
|
|
1871
1871
|
}
|
|
1872
|
-
if (!
|
|
1872
|
+
if (!brokerageAccountObj) {
|
|
1873
1873
|
try {
|
|
1874
1874
|
const apolloClient = client || (await getSharedApolloClient());
|
|
1875
|
-
|
|
1875
|
+
brokerageAccountObj = (await adaptic$1.brokerageAccount.get({
|
|
1876
1876
|
id: accountId,
|
|
1877
1877
|
}, apolloClient));
|
|
1878
1878
|
}
|
|
@@ -1881,19 +1881,19 @@ async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, })
|
|
|
1881
1881
|
throw error;
|
|
1882
1882
|
}
|
|
1883
1883
|
}
|
|
1884
|
-
if (!
|
|
1885
|
-
!
|
|
1886
|
-
!
|
|
1884
|
+
if (!brokerageAccountObj ||
|
|
1885
|
+
!brokerageAccountObj.apiKey ||
|
|
1886
|
+
!brokerageAccountObj.apiSecret) {
|
|
1887
1887
|
throw new Error("[fetchAccountDetails] Alpaca account not found or incomplete");
|
|
1888
1888
|
}
|
|
1889
|
-
const {
|
|
1889
|
+
const { apiKey, apiSecret, type } = brokerageAccountObj;
|
|
1890
1890
|
const apiUrl = `${getTradingApiUrl(type)}/account`;
|
|
1891
1891
|
try {
|
|
1892
1892
|
const response = await fetch(apiUrl, {
|
|
1893
1893
|
method: "GET",
|
|
1894
1894
|
headers: {
|
|
1895
|
-
"APCA-API-KEY-ID":
|
|
1896
|
-
"APCA-API-SECRET-KEY":
|
|
1895
|
+
"APCA-API-KEY-ID": apiKey,
|
|
1896
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
1897
1897
|
"Content-Type": "application/json",
|
|
1898
1898
|
},
|
|
1899
1899
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
@@ -1914,12 +1914,12 @@ async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, })
|
|
|
1914
1914
|
* @param props - The properties for fetching portfolio history
|
|
1915
1915
|
* @returns The portfolio history
|
|
1916
1916
|
*/
|
|
1917
|
-
async function fetchPortfolioHistory({ params, accountId, client,
|
|
1918
|
-
let
|
|
1919
|
-
if (!
|
|
1917
|
+
async function fetchPortfolioHistory({ params, accountId, client, brokerageAccount, }) {
|
|
1918
|
+
let brokerageAccountObj = brokerageAccount ? brokerageAccount : null;
|
|
1919
|
+
if (!brokerageAccountObj) {
|
|
1920
1920
|
try {
|
|
1921
1921
|
const apolloClient = client || (await getSharedApolloClient());
|
|
1922
|
-
|
|
1922
|
+
brokerageAccountObj = (await adaptic$1.brokerageAccount.get({
|
|
1923
1923
|
id: accountId,
|
|
1924
1924
|
}, apolloClient));
|
|
1925
1925
|
}
|
|
@@ -1928,12 +1928,12 @@ async function fetchPortfolioHistory({ params, accountId, client, alpacaAccount,
|
|
|
1928
1928
|
throw error;
|
|
1929
1929
|
}
|
|
1930
1930
|
}
|
|
1931
|
-
if (!
|
|
1932
|
-
!
|
|
1933
|
-
!
|
|
1931
|
+
if (!brokerageAccountObj ||
|
|
1932
|
+
!brokerageAccountObj.apiKey ||
|
|
1933
|
+
!brokerageAccountObj.apiSecret) {
|
|
1934
1934
|
throw new Error("[fetchPortfolioHistory] Alpaca account not found or incomplete");
|
|
1935
1935
|
}
|
|
1936
|
-
const {
|
|
1936
|
+
const { apiKey, apiSecret, type } = brokerageAccountObj;
|
|
1937
1937
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
1938
1938
|
const apiUrl = `${apiBaseUrl}/v2/account/portfolio/history`;
|
|
1939
1939
|
const { start, end, period } = params;
|
|
@@ -1959,8 +1959,8 @@ async function fetchPortfolioHistory({ params, accountId, client, alpacaAccount,
|
|
|
1959
1959
|
const response = await fetch(fullUrl, {
|
|
1960
1960
|
method: "GET",
|
|
1961
1961
|
headers: {
|
|
1962
|
-
"APCA-API-KEY-ID":
|
|
1963
|
-
"APCA-API-SECRET-KEY":
|
|
1962
|
+
"APCA-API-KEY-ID": apiKey,
|
|
1963
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
1964
1964
|
"Content-Type": "application/json",
|
|
1965
1965
|
},
|
|
1966
1966
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
@@ -1987,31 +1987,31 @@ async function getConfiguration(account) {
|
|
|
1987
1987
|
if (!account) {
|
|
1988
1988
|
throw new Error(`Account is missing.`);
|
|
1989
1989
|
}
|
|
1990
|
-
const {
|
|
1991
|
-
if (!
|
|
1992
|
-
throw new Error("
|
|
1990
|
+
const { apiKey, apiSecret } = account;
|
|
1991
|
+
if (!apiKey || !apiSecret) {
|
|
1992
|
+
throw new Error("Account apiKey or apiSecret is missing.");
|
|
1993
1993
|
}
|
|
1994
1994
|
const apiUrl = getTradingApiUrl(account.type);
|
|
1995
1995
|
const client = await getSharedApolloClient();
|
|
1996
|
-
const [alpacaResponse,
|
|
1996
|
+
const [alpacaResponse, freshBrokerageAccount] = await Promise.all([
|
|
1997
1997
|
fetch(`${apiUrl}/account/configurations`, {
|
|
1998
1998
|
method: "GET",
|
|
1999
1999
|
headers: {
|
|
2000
|
-
"APCA-API-KEY-ID":
|
|
2001
|
-
"APCA-API-SECRET-KEY":
|
|
2000
|
+
"APCA-API-KEY-ID": apiKey,
|
|
2001
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
2002
2002
|
accept: "application/json",
|
|
2003
2003
|
},
|
|
2004
2004
|
}),
|
|
2005
|
-
adaptic$1.
|
|
2005
|
+
adaptic$1.brokerageAccount.get({ id: account.id }, client),
|
|
2006
2006
|
]);
|
|
2007
2007
|
if (!alpacaResponse.ok) {
|
|
2008
2008
|
throw new Error(`Failed to fetch account configuration: ${alpacaResponse.statusText}`);
|
|
2009
2009
|
}
|
|
2010
|
-
if (!
|
|
2010
|
+
if (!freshBrokerageAccount) {
|
|
2011
2011
|
throw new Error("Failed to get Alpaca Account from @adaptic/backend-legacy.");
|
|
2012
2012
|
}
|
|
2013
2013
|
const dataFromAlpaca = (await alpacaResponse.json());
|
|
2014
|
-
const accountWithAllocation =
|
|
2014
|
+
const accountWithAllocation = freshBrokerageAccount;
|
|
2015
2015
|
const allocationData = accountWithAllocation.allocation || {
|
|
2016
2016
|
stocks: 70,
|
|
2017
2017
|
options: 0,
|
|
@@ -2022,26 +2022,26 @@ async function getConfiguration(account) {
|
|
|
2022
2022
|
};
|
|
2023
2023
|
const combinedConfig = {
|
|
2024
2024
|
...dataFromAlpaca,
|
|
2025
|
-
marketOpen:
|
|
2026
|
-
realTime:
|
|
2027
|
-
tradeAllocationPct:
|
|
2028
|
-
minPercentageChange:
|
|
2029
|
-
volumeThreshold:
|
|
2030
|
-
cryptoTradingEnabled:
|
|
2031
|
-
cryptoTradingPairs:
|
|
2032
|
-
cryptoTradeAllocationPct:
|
|
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,
|
|
2033
2033
|
autoAllocation: accountWithAllocation.autoAllocation ?? false,
|
|
2034
2034
|
allocation: allocationData,
|
|
2035
|
-
enablePortfolioTrailingStop:
|
|
2036
|
-
portfolioTrailPercent:
|
|
2037
|
-
portfolioProfitThresholdPercent:
|
|
2038
|
-
reducedPortfolioTrailPercent:
|
|
2039
|
-
defaultTrailingStopPercentage100:
|
|
2040
|
-
firstTrailReductionThreshold100:
|
|
2041
|
-
secondTrailReductionThreshold100:
|
|
2042
|
-
firstReducedTrailPercentage100:
|
|
2043
|
-
secondReducedTrailPercentage100:
|
|
2044
|
-
minimumPriceChangePercent100:
|
|
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,
|
|
2045
2045
|
};
|
|
2046
2046
|
return combinedConfig;
|
|
2047
2047
|
}
|
|
@@ -2062,9 +2062,9 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2062
2062
|
if (!account) {
|
|
2063
2063
|
throw new Error(`Account is missing.`);
|
|
2064
2064
|
}
|
|
2065
|
-
const {
|
|
2066
|
-
if (!
|
|
2067
|
-
throw new Error("
|
|
2065
|
+
const { apiKey, apiSecret } = account;
|
|
2066
|
+
if (!apiKey || !apiSecret) {
|
|
2067
|
+
throw new Error("Account apiKey or apiSecret is missing.");
|
|
2068
2068
|
}
|
|
2069
2069
|
const apiUrl = getTradingApiUrl(account.type);
|
|
2070
2070
|
// Prepare the config object for Alpaca by removing DB-only fields
|
|
@@ -2092,8 +2092,8 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2092
2092
|
const alpacaUpdatePromise = fetch(`${apiUrl}/account/configurations`, {
|
|
2093
2093
|
method: "PATCH",
|
|
2094
2094
|
headers: {
|
|
2095
|
-
"APCA-API-KEY-ID":
|
|
2096
|
-
"APCA-API-SECRET-KEY":
|
|
2095
|
+
"APCA-API-KEY-ID": apiKey,
|
|
2096
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
2097
2097
|
"Content-Type": "application/json",
|
|
2098
2098
|
accept: "application/json",
|
|
2099
2099
|
},
|
|
@@ -2114,10 +2114,10 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2114
2114
|
if (account.allocation) {
|
|
2115
2115
|
allocUpdatePromise = adaptic$1.allocation.update({
|
|
2116
2116
|
id: account.allocation.id,
|
|
2117
|
-
|
|
2117
|
+
brokerageAccount: {
|
|
2118
2118
|
id: account.id,
|
|
2119
2119
|
},
|
|
2120
|
-
|
|
2120
|
+
brokerageAccountId: account.id,
|
|
2121
2121
|
stocks: updatedConfig.allocation.stocks ?? 0,
|
|
2122
2122
|
options: updatedConfig.allocation.options ?? 0,
|
|
2123
2123
|
futures: updatedConfig.allocation.futures ?? 0,
|
|
@@ -2134,14 +2134,14 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2134
2134
|
etfs: updatedConfig.allocation.etfs ?? 0,
|
|
2135
2135
|
forex: updatedConfig.allocation.forex ?? 0,
|
|
2136
2136
|
crypto: updatedConfig.allocation.crypto ?? 0,
|
|
2137
|
-
|
|
2137
|
+
brokerageAccount: {
|
|
2138
2138
|
id: account.id,
|
|
2139
2139
|
},
|
|
2140
|
-
|
|
2140
|
+
brokerageAccountId: account.id,
|
|
2141
2141
|
}, client);
|
|
2142
2142
|
}
|
|
2143
2143
|
}
|
|
2144
|
-
const adapticUpdatePromise = adaptic$1.
|
|
2144
|
+
const adapticUpdatePromise = adaptic$1.brokerageAccount.update({
|
|
2145
2145
|
id: account.id,
|
|
2146
2146
|
user: {
|
|
2147
2147
|
id: user.id,
|
|
@@ -2168,7 +2168,7 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2168
2168
|
secondReducedTrailPercentage100: updatedConfig.secondReducedTrailPercentage100 ?? 0,
|
|
2169
2169
|
minimumPriceChangePercent100: updatedConfig.minimumPriceChangePercent100 ?? 0,
|
|
2170
2170
|
}, client);
|
|
2171
|
-
const [alpacaResponse,
|
|
2171
|
+
const [alpacaResponse, updatedBrokerageAccount, updatedAllocation] = await Promise.all([
|
|
2172
2172
|
alpacaUpdatePromise,
|
|
2173
2173
|
adapticUpdatePromise,
|
|
2174
2174
|
allocUpdatePromise,
|
|
@@ -2188,10 +2188,10 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2188
2188
|
throw new Error(`Failed to update account config at Alpaca: ${alpacaResponse.statusText}`);
|
|
2189
2189
|
}
|
|
2190
2190
|
const alpacaData = (await alpacaResponse.json());
|
|
2191
|
-
if (!
|
|
2191
|
+
if (!updatedBrokerageAccount) {
|
|
2192
2192
|
throw new Error("Failed to update Alpaca Account in @adaptic/backend-legacy.");
|
|
2193
2193
|
}
|
|
2194
|
-
const updatedAccountWithAllocation =
|
|
2194
|
+
const updatedAccountWithAllocation = updatedBrokerageAccount;
|
|
2195
2195
|
const selectedAllocation = (updatedConfig.allocation ||
|
|
2196
2196
|
updatedAllocation ||
|
|
2197
2197
|
updatedAccountWithAllocation.allocation);
|
|
@@ -2201,26 +2201,26 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2201
2201
|
getLogger().info("Final allocation:", selectedAllocation);
|
|
2202
2202
|
const finalConfig = {
|
|
2203
2203
|
...alpacaData,
|
|
2204
|
-
marketOpen:
|
|
2205
|
-
realTime:
|
|
2206
|
-
tradeAllocationPct:
|
|
2207
|
-
minPercentageChange:
|
|
2208
|
-
volumeThreshold:
|
|
2209
|
-
cryptoTradingEnabled:
|
|
2210
|
-
cryptoTradingPairs:
|
|
2211
|
-
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,
|
|
2212
2212
|
autoAllocation: updatedAccountWithAllocation.autoAllocation,
|
|
2213
2213
|
allocation: selectedAllocation,
|
|
2214
|
-
enablePortfolioTrailingStop:
|
|
2215
|
-
portfolioTrailPercent:
|
|
2216
|
-
portfolioProfitThresholdPercent:
|
|
2217
|
-
reducedPortfolioTrailPercent:
|
|
2218
|
-
defaultTrailingStopPercentage100:
|
|
2219
|
-
firstTrailReductionThreshold100:
|
|
2220
|
-
secondTrailReductionThreshold100:
|
|
2221
|
-
firstReducedTrailPercentage100:
|
|
2222
|
-
secondReducedTrailPercentage100:
|
|
2223
|
-
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,
|
|
2224
2224
|
};
|
|
2225
2225
|
return finalConfig;
|
|
2226
2226
|
}
|
|
@@ -2238,15 +2238,15 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
2238
2238
|
*/
|
|
2239
2239
|
async function getAsset(auth, symbolOrAssetId) {
|
|
2240
2240
|
try {
|
|
2241
|
-
const {
|
|
2241
|
+
const { apiKey, apiSecret, type } = await validateAuth(auth);
|
|
2242
2242
|
const apiBaseUrl = getTradingApiUrl(type);
|
|
2243
2243
|
// Use encodeURIComponent to handle special characters in symbols (e.g., BTC/USDT)
|
|
2244
2244
|
const encodedSymbolOrAssetId = encodeURIComponent(symbolOrAssetId);
|
|
2245
2245
|
const response = await fetch(`${apiBaseUrl}/v2/assets/${encodedSymbolOrAssetId}`, {
|
|
2246
2246
|
method: "GET",
|
|
2247
2247
|
headers: {
|
|
2248
|
-
"APCA-API-KEY-ID":
|
|
2249
|
-
"APCA-API-SECRET-KEY":
|
|
2248
|
+
"APCA-API-KEY-ID": apiKey,
|
|
2249
|
+
"APCA-API-SECRET-KEY": apiSecret,
|
|
2250
2250
|
"Content-Type": "application/json",
|
|
2251
2251
|
},
|
|
2252
2252
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
@@ -3303,24 +3303,24 @@ async function calculateTotalReturnYTD(portfolioHistory) {
|
|
|
3303
3303
|
* Calculates the expense ratio for a given Alpaca account.
|
|
3304
3304
|
* @param accountId - The ID of the Alpaca account.
|
|
3305
3305
|
* @param client - The Apollo client instance.
|
|
3306
|
-
* @param
|
|
3306
|
+
* @param brokerageAccount - The Alpaca account object.
|
|
3307
3307
|
* @returns A promise that resolves to a string representing the expense ratio in percentage format.
|
|
3308
3308
|
*/
|
|
3309
|
-
async function calculateExpenseRatio$1({ accountId, client,
|
|
3310
|
-
if (!accountId && !
|
|
3309
|
+
async function calculateExpenseRatio$1({ accountId, client, brokerageAccount, }) {
|
|
3310
|
+
if (!accountId && !brokerageAccount && !client) {
|
|
3311
3311
|
getLogger().warn("Missing account ID or client to calculate expense ratio.");
|
|
3312
3312
|
return "N/A";
|
|
3313
3313
|
}
|
|
3314
|
-
let
|
|
3314
|
+
let brokerageAccountId = accountId || (brokerageAccount && brokerageAccount.id) || "";
|
|
3315
3315
|
let accountDetails;
|
|
3316
|
-
if (!
|
|
3316
|
+
if (!brokerageAccountId) {
|
|
3317
3317
|
getLogger().warn("Invalid account ID.");
|
|
3318
3318
|
return "N/A";
|
|
3319
3319
|
}
|
|
3320
|
-
if (
|
|
3320
|
+
if (brokerageAccount) {
|
|
3321
3321
|
// Use Alpaca account object to get accountDetails
|
|
3322
3322
|
accountDetails = (await fetchAccountDetails({
|
|
3323
|
-
|
|
3323
|
+
brokerageAccount: brokerageAccount,
|
|
3324
3324
|
}));
|
|
3325
3325
|
if (!accountDetails) {
|
|
3326
3326
|
getLogger().warn("Failed to fetch account details inside calculateExpenseRatio.");
|
|
@@ -3359,24 +3359,24 @@ async function getPortfolioExpensesFromYourSystem(accountId) {
|
|
|
3359
3359
|
* Calculates the liquidity ratio for a given Alpaca account.
|
|
3360
3360
|
* @param accountId - The ID of the Alpaca account.
|
|
3361
3361
|
* @param client - The Apollo client instance.
|
|
3362
|
-
* @param
|
|
3362
|
+
* @param brokerageAccount - The Alpaca account object.
|
|
3363
3363
|
* @returns A promise that resolves to a string representing the liquidity ratio in the format "1:ratio".
|
|
3364
3364
|
*/
|
|
3365
|
-
async function calculateLiquidityRatio({ accountId, client,
|
|
3366
|
-
if (!accountId && !
|
|
3365
|
+
async function calculateLiquidityRatio({ accountId, client, brokerageAccount, }) {
|
|
3366
|
+
if (!accountId && !brokerageAccount && !client) {
|
|
3367
3367
|
getLogger().warn("Missing account ID or client to calculateLiquidityRatio.");
|
|
3368
3368
|
return "N/A";
|
|
3369
3369
|
}
|
|
3370
|
-
let
|
|
3370
|
+
let brokerageAccountId = accountId || (brokerageAccount && brokerageAccount.id) || "";
|
|
3371
3371
|
let accountDetails;
|
|
3372
|
-
if (!
|
|
3372
|
+
if (!brokerageAccountId) {
|
|
3373
3373
|
getLogger().warn("Invalid account ID.");
|
|
3374
3374
|
return "N/A";
|
|
3375
3375
|
}
|
|
3376
|
-
if (
|
|
3376
|
+
if (brokerageAccount) {
|
|
3377
3377
|
// Use Alpaca account object to get accountDetails
|
|
3378
3378
|
accountDetails = (await fetchAccountDetails({
|
|
3379
|
-
|
|
3379
|
+
brokerageAccount: brokerageAccount,
|
|
3380
3380
|
}));
|
|
3381
3381
|
if (!accountDetails) {
|
|
3382
3382
|
getLogger().warn("Failed to fetch account details inside calculateLiquidityRatio.");
|
|
@@ -4004,11 +4004,11 @@ async function calculateInformationRatio$1(portfolioHistory, benchmarkBars) {
|
|
|
4004
4004
|
* @param params - The parameters for fetching performance metrics.
|
|
4005
4005
|
* @param client - The Apollo client instance.
|
|
4006
4006
|
* @param accountId - The ID of the Alpaca account.
|
|
4007
|
-
* @param
|
|
4007
|
+
* @param brokerageAccount - The Alpaca account object.
|
|
4008
4008
|
* @returns A promise that resolves to an object containing various performance metrics.
|
|
4009
4009
|
* @throws Will throw an error if required parameters are missing or if fetching fails.
|
|
4010
4010
|
*/
|
|
4011
|
-
async function fetchPerformanceMetrics({ params, client, accountId,
|
|
4011
|
+
async function fetchPerformanceMetrics({ params, client, accountId, brokerageAccount, }) {
|
|
4012
4012
|
// Default response for error cases
|
|
4013
4013
|
const defaultMetrics = {
|
|
4014
4014
|
totalReturnYTD: "N/A",
|
|
@@ -4031,12 +4031,12 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
|
|
|
4031
4031
|
throw new Error("Missing required timeframe or period parameters");
|
|
4032
4032
|
}
|
|
4033
4033
|
// Obtain Alpaca account
|
|
4034
|
-
let
|
|
4035
|
-
if (!
|
|
4034
|
+
let brokerageAccountObj = brokerageAccount ? brokerageAccount : null;
|
|
4035
|
+
if (!brokerageAccountObj && accountId) {
|
|
4036
4036
|
try {
|
|
4037
4037
|
// Use provided client or get the shared client
|
|
4038
4038
|
const apolloClient = client || (await getSharedApolloClient());
|
|
4039
|
-
|
|
4039
|
+
brokerageAccountObj = (await adaptic$1.brokerageAccount.get({
|
|
4040
4040
|
id: accountId,
|
|
4041
4041
|
}, apolloClient));
|
|
4042
4042
|
}
|
|
@@ -4046,9 +4046,9 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
|
|
|
4046
4046
|
}
|
|
4047
4047
|
}
|
|
4048
4048
|
// Validate Alpaca account
|
|
4049
|
-
if (!
|
|
4050
|
-
!
|
|
4051
|
-
!
|
|
4049
|
+
if (!brokerageAccountObj ||
|
|
4050
|
+
!brokerageAccountObj.apiKey ||
|
|
4051
|
+
!brokerageAccountObj.apiSecret) {
|
|
4052
4052
|
throw new Error("Alpaca account not found or credentials missing");
|
|
4053
4053
|
}
|
|
4054
4054
|
// Fetch portfolio history with structured error handling
|
|
@@ -4056,7 +4056,7 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
|
|
|
4056
4056
|
try {
|
|
4057
4057
|
portfolioHistory = await fetchPortfolioHistory({
|
|
4058
4058
|
params: params,
|
|
4059
|
-
|
|
4059
|
+
brokerageAccount: brokerageAccountObj,
|
|
4060
4060
|
});
|
|
4061
4061
|
}
|
|
4062
4062
|
catch (error) {
|
|
@@ -4106,10 +4106,10 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
|
|
|
4106
4106
|
calculateInformationRatio$1(portfolioHistory, benchmarkBars),
|
|
4107
4107
|
calculateRiskAdjustedReturn$1(portfolioHistory),
|
|
4108
4108
|
calculateLiquidityRatio({
|
|
4109
|
-
|
|
4109
|
+
brokerageAccount: brokerageAccountObj,
|
|
4110
4110
|
}),
|
|
4111
4111
|
calculateExpenseRatio$1({
|
|
4112
|
-
|
|
4112
|
+
brokerageAccount: brokerageAccountObj,
|
|
4113
4113
|
}),
|
|
4114
4114
|
getDividendYield(),
|
|
4115
4115
|
calculateMaxDrawdown$1(portfolioHistory.equity),
|
|
@@ -4329,15 +4329,15 @@ const timeDiffString = (milliseconds) => {
|
|
|
4329
4329
|
};
|
|
4330
4330
|
|
|
4331
4331
|
// price-utils.ts
|
|
4332
|
-
const calculateFees = async (action, trade,
|
|
4332
|
+
const calculateFees = async (action, trade, brokerageAccount) => {
|
|
4333
4333
|
let fee = 0;
|
|
4334
4334
|
const alpacaOrderId = action.alpacaOrderId;
|
|
4335
4335
|
if (!alpacaOrderId)
|
|
4336
4336
|
return fee;
|
|
4337
4337
|
const order = await getOrder$1({
|
|
4338
|
-
adapticAccountId: trade.
|
|
4339
|
-
alpacaApiKey:
|
|
4340
|
-
alpacaApiSecret:
|
|
4338
|
+
adapticAccountId: trade.brokerageAccountId,
|
|
4339
|
+
alpacaApiKey: brokerageAccount.apiKey,
|
|
4340
|
+
alpacaApiSecret: brokerageAccount.apiSecret,
|
|
4341
4341
|
}, alpacaOrderId);
|
|
4342
4342
|
if (!order)
|
|
4343
4343
|
return fee;
|
|
@@ -4375,13 +4375,13 @@ const calculateFees = async (action, trade, alpacaAccount) => {
|
|
|
4375
4375
|
};
|
|
4376
4376
|
const computeTotalFees = async (trade) => {
|
|
4377
4377
|
let totalFees = 0;
|
|
4378
|
-
// fetch alpaca account details using adaptic.
|
|
4379
|
-
const
|
|
4380
|
-
id: trade.
|
|
4378
|
+
// fetch alpaca account details using adaptic.brokerageAccount.get({id: trade.brokerageAccountId})
|
|
4379
|
+
const brokerageAccount = (await adaptic$1.brokerageAccount.get({
|
|
4380
|
+
id: trade.brokerageAccountId,
|
|
4381
4381
|
}));
|
|
4382
|
-
if (!
|
|
4382
|
+
if (!brokerageAccount)
|
|
4383
4383
|
return totalFees;
|
|
4384
|
-
const feePromises = trade?.actions?.map((action) => calculateFees(action, trade,
|
|
4384
|
+
const feePromises = trade?.actions?.map((action) => calculateFees(action, trade, brokerageAccount));
|
|
4385
4385
|
const fees = await Promise.all(feePromises || []);
|
|
4386
4386
|
totalFees = fees.reduce((acc, fee) => acc + fee, 0);
|
|
4387
4387
|
return totalFees;
|
|
@@ -6128,7 +6128,7 @@ async function fetchBars(params) {
|
|
|
6128
6128
|
*/
|
|
6129
6129
|
async function fetchNews(params, auth) {
|
|
6130
6130
|
const { symbol, start = new Date(Date.now() - 24 * 60 * 60 * 1000), sort = "desc", includeContent = false, limit = 1000, } = params;
|
|
6131
|
-
if (!auth.
|
|
6131
|
+
if (!auth.alpacaApiKey || !auth.alpacaApiSecret) {
|
|
6132
6132
|
throw new Error("Alpaca API key and secret are required");
|
|
6133
6133
|
}
|
|
6134
6134
|
if (!symbol) {
|
|
@@ -6196,7 +6196,7 @@ async function fetchNews(params, auth) {
|
|
|
6196
6196
|
*/
|
|
6197
6197
|
async function fetchLatestTrades(params, auth) {
|
|
6198
6198
|
const { symbols, loc = "us" } = params;
|
|
6199
|
-
if (!auth.
|
|
6199
|
+
if (!auth.alpacaApiKey || !auth.alpacaApiSecret) {
|
|
6200
6200
|
throw new Error("Alpaca API key and secret are required");
|
|
6201
6201
|
}
|
|
6202
6202
|
if (!symbols || symbols.length === 0) {
|
|
@@ -6212,8 +6212,8 @@ async function fetchLatestTrades(params, auth) {
|
|
|
6212
6212
|
return withRetry(async () => {
|
|
6213
6213
|
const response = await fetch(url, {
|
|
6214
6214
|
headers: {
|
|
6215
|
-
"APCA-API-KEY-ID": auth.
|
|
6216
|
-
"APCA-API-SECRET-KEY": auth.
|
|
6215
|
+
"APCA-API-KEY-ID": auth.alpacaApiKey,
|
|
6216
|
+
"APCA-API-SECRET-KEY": auth.alpacaApiSecret,
|
|
6217
6217
|
},
|
|
6218
6218
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
6219
6219
|
});
|
|
@@ -6239,7 +6239,7 @@ async function fetchLatestTrades(params, auth) {
|
|
|
6239
6239
|
*/
|
|
6240
6240
|
async function fetchLatestQuotes(params, auth) {
|
|
6241
6241
|
const { symbols, loc = "us" } = params;
|
|
6242
|
-
if (!auth.
|
|
6242
|
+
if (!auth.alpacaApiKey || !auth.alpacaApiSecret) {
|
|
6243
6243
|
throw new Error("Alpaca API key and secret are required");
|
|
6244
6244
|
}
|
|
6245
6245
|
if (!symbols || symbols.length === 0) {
|
|
@@ -6255,8 +6255,8 @@ async function fetchLatestQuotes(params, auth) {
|
|
|
6255
6255
|
return withRetry(async () => {
|
|
6256
6256
|
const response = await fetch(url, {
|
|
6257
6257
|
headers: {
|
|
6258
|
-
"APCA-API-KEY-ID": auth.
|
|
6259
|
-
"APCA-API-SECRET-KEY": auth.
|
|
6258
|
+
"APCA-API-KEY-ID": auth.alpacaApiKey,
|
|
6259
|
+
"APCA-API-SECRET-KEY": auth.alpacaApiSecret,
|
|
6260
6260
|
},
|
|
6261
6261
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
6262
6262
|
});
|