@adaptic/utils 0.0.961 → 0.0.962
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 +112 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +112 -61
- package/dist/index.mjs.map +1 -1
- package/dist/types/alpaca/client.d.ts +10 -0
- package/dist/types/alpaca/client.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/bars.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/quotes.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/trades.d.ts.map +1 -1
- package/dist/types/alpaca/trading/clock.d.ts.map +1 -1
- package/dist/types/alpaca/trading/orders.d.ts.map +1 -1
- package/dist/types/alpaca/trading/positions.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/massive-indices.d.ts.map +1 -1
- package/dist/types/massive.d.ts.map +1 -1
- package/dist/types/trading-policy/schemas/effective-policy.schema.d.ts +6 -6
- package/dist/types/trading-policy/schemas/overlay-response-prefs.schema.d.ts +8 -8
- package/dist/types/trading-policy/schemas/policy-mutation.schema.d.ts +12 -12
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -8016,8 +8016,9 @@ const fetchTickerInfo = async (symbol, options) => {
|
|
|
8016
8016
|
apiKey,
|
|
8017
8017
|
});
|
|
8018
8018
|
return massiveLimit(async () => {
|
|
8019
|
+
await rateLimiters.massive.acquire();
|
|
8019
8020
|
try {
|
|
8020
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8021
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8021
8022
|
const data = await response.json();
|
|
8022
8023
|
// Check for "NOT_FOUND" status and return null
|
|
8023
8024
|
if (data.status === "NOT_FOUND") {
|
|
@@ -8128,8 +8129,9 @@ const fetchLastTradeImpl = async (symbol, options) => {
|
|
|
8128
8129
|
order: "desc",
|
|
8129
8130
|
});
|
|
8130
8131
|
return massiveLimit(async () => {
|
|
8132
|
+
await rateLimiters.massive.acquire();
|
|
8131
8133
|
try {
|
|
8132
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8134
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8133
8135
|
const data = (await response.json());
|
|
8134
8136
|
if ("message" in data) {
|
|
8135
8137
|
throw new Error(`Massive.com API error: ${data.message}`);
|
|
@@ -8198,8 +8200,9 @@ const fetchLastQuote = async (symbol, options) => {
|
|
|
8198
8200
|
order: "desc",
|
|
8199
8201
|
});
|
|
8200
8202
|
return massiveLimit(async () => {
|
|
8203
|
+
await rateLimiters.massive.acquire();
|
|
8201
8204
|
try {
|
|
8202
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8205
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8203
8206
|
const data = (await response.json());
|
|
8204
8207
|
if ("message" in data) {
|
|
8205
8208
|
throw new Error(`Massive.com API error: ${data.message}`);
|
|
@@ -8282,7 +8285,7 @@ const fetchPrices = async (params, options) => {
|
|
|
8282
8285
|
while (nextUrl) {
|
|
8283
8286
|
//getLogger().info(`Debug: Fetching ${nextUrl}`);
|
|
8284
8287
|
await rateLimiters.massive.acquire();
|
|
8285
|
-
const response = await fetchWithRetry(nextUrl, {}, 3, 1000);
|
|
8288
|
+
const response = await fetchWithRetry(nextUrl, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8286
8289
|
const data = await response.json();
|
|
8287
8290
|
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
8288
8291
|
throw new Error(`Massive.com API responded with status: ${data.status}`);
|
|
@@ -8403,8 +8406,9 @@ const fetchGroupedDaily = async (date, options) => {
|
|
|
8403
8406
|
include_otc: options?.includeOTC ? "true" : "false",
|
|
8404
8407
|
});
|
|
8405
8408
|
return massiveLimit(async () => {
|
|
8409
|
+
await rateLimiters.massive.acquire();
|
|
8406
8410
|
try {
|
|
8407
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8411
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8408
8412
|
const data = await response.json();
|
|
8409
8413
|
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
8410
8414
|
throw new Error(`Massive.com API responded with status: ${data.status}`);
|
|
@@ -8496,12 +8500,20 @@ symbol, date = new Date(), options) => {
|
|
|
8496
8500
|
adjusted: (options?.adjusted ?? true).toString(),
|
|
8497
8501
|
});
|
|
8498
8502
|
return massiveLimit(async () => {
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
+
await rateLimiters.massive.acquire();
|
|
8504
|
+
try {
|
|
8505
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8506
|
+
const data = await response.json();
|
|
8507
|
+
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
8508
|
+
throw new Error(`Failed to fetch daily open/close data for ${symbol}: ${data.status}`);
|
|
8509
|
+
}
|
|
8510
|
+
return data;
|
|
8511
|
+
}
|
|
8512
|
+
catch (error) {
|
|
8513
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
8514
|
+
getLogger().error(`Error fetching daily open/close for ${symbol}: ${errorMessage}`);
|
|
8515
|
+
throw error;
|
|
8503
8516
|
}
|
|
8504
|
-
return data;
|
|
8505
8517
|
});
|
|
8506
8518
|
};
|
|
8507
8519
|
/**
|
|
@@ -8562,10 +8574,11 @@ const fetchTrades = async (symbol, options) => {
|
|
|
8562
8574
|
if (options?.sort)
|
|
8563
8575
|
params.append("sort", options.sort);
|
|
8564
8576
|
return massiveLimit(async () => {
|
|
8577
|
+
await rateLimiters.massive.acquire();
|
|
8565
8578
|
const url = `${baseUrl}?${params.toString()}`;
|
|
8566
8579
|
try {
|
|
8567
8580
|
logIfDebug(`Fetching trades for ${symbol} from ${url}`);
|
|
8568
|
-
const response = await fetchWithRetry(url, {}, 3, 1000);
|
|
8581
|
+
const response = await fetchWithRetry(url, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8569
8582
|
const data = (await response.json());
|
|
8570
8583
|
if ("message" in data) {
|
|
8571
8584
|
// This is an error response
|
|
@@ -8641,8 +8654,9 @@ const fetchIndicesAggregates = async (params, options) => {
|
|
|
8641
8654
|
}
|
|
8642
8655
|
url.search = queryParams.toString();
|
|
8643
8656
|
return massiveIndicesLimit(async () => {
|
|
8657
|
+
await rateLimiters.massive.acquire();
|
|
8644
8658
|
try {
|
|
8645
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8659
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8646
8660
|
const data = await response.json();
|
|
8647
8661
|
if (data.status === "ERROR") {
|
|
8648
8662
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8670,8 +8684,9 @@ const fetchIndicesPreviousClose = async (indicesTicker, options) => {
|
|
|
8670
8684
|
queryParams.append("apiKey", apiKey);
|
|
8671
8685
|
url.search = queryParams.toString();
|
|
8672
8686
|
return massiveIndicesLimit(async () => {
|
|
8687
|
+
await rateLimiters.massive.acquire();
|
|
8673
8688
|
try {
|
|
8674
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8689
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8675
8690
|
const data = await response.json();
|
|
8676
8691
|
if (data.status === "ERROR") {
|
|
8677
8692
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8700,8 +8715,9 @@ const fetchIndicesDailyOpenClose = async (indicesTicker, date, options) => {
|
|
|
8700
8715
|
queryParams.append("apiKey", apiKey);
|
|
8701
8716
|
url.search = queryParams.toString();
|
|
8702
8717
|
return massiveIndicesLimit(async () => {
|
|
8718
|
+
await rateLimiters.massive.acquire();
|
|
8703
8719
|
try {
|
|
8704
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8720
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8705
8721
|
const data = await response.json();
|
|
8706
8722
|
if (data.status === "ERROR") {
|
|
8707
8723
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8741,8 +8757,9 @@ const fetchIndicesSnapshot = async (params, options) => {
|
|
|
8741
8757
|
}
|
|
8742
8758
|
url.search = queryParams.toString();
|
|
8743
8759
|
return massiveIndicesLimit(async () => {
|
|
8760
|
+
await rateLimiters.massive.acquire();
|
|
8744
8761
|
try {
|
|
8745
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8762
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8746
8763
|
const data = await response.json();
|
|
8747
8764
|
if (data.status === "ERROR") {
|
|
8748
8765
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8789,8 +8806,9 @@ const fetchUniversalSnapshot = async (tickers, options) => {
|
|
|
8789
8806
|
}
|
|
8790
8807
|
url.search = queryParams.toString();
|
|
8791
8808
|
return massiveIndicesLimit(async () => {
|
|
8809
|
+
await rateLimiters.massive.acquire();
|
|
8792
8810
|
try {
|
|
8793
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8811
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8794
8812
|
const data = await response.json();
|
|
8795
8813
|
if (data.status === "ERROR") {
|
|
8796
8814
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -48979,6 +48997,25 @@ class AlpacaClient {
|
|
|
48979
48997
|
isPaper() {
|
|
48980
48998
|
return this.config.accountType === "PAPER";
|
|
48981
48999
|
}
|
|
49000
|
+
/**
|
|
49001
|
+
* Execute an Alpaca SDK operation with rate limiting and retry.
|
|
49002
|
+
* Use this for all SDK calls to prevent rate limit breaches and handle
|
|
49003
|
+
* transient failures during market hours.
|
|
49004
|
+
*
|
|
49005
|
+
* @param operation - Async function that calls the SDK
|
|
49006
|
+
* @param label - Human-readable label for logging
|
|
49007
|
+
* @returns Result of the operation
|
|
49008
|
+
*/
|
|
49009
|
+
async executeWithRateLimit(operation, label) {
|
|
49010
|
+
await rateLimiters.alpaca.acquire();
|
|
49011
|
+
return withRetry(operation, {
|
|
49012
|
+
maxRetries: 2,
|
|
49013
|
+
baseDelayMs: 1000,
|
|
49014
|
+
maxDelayMs: 10000,
|
|
49015
|
+
retryableStatusCodes: [429, 500, 502, 503, 504],
|
|
49016
|
+
retryOnNetworkError: true,
|
|
49017
|
+
}, `Alpaca SDK: ${label}`);
|
|
49018
|
+
}
|
|
48982
49019
|
/**
|
|
48983
49020
|
* Validate credentials by fetching account info
|
|
48984
49021
|
*/
|
|
@@ -49029,6 +49066,7 @@ class AlpacaClient {
|
|
|
49029
49066
|
* @returns Response data
|
|
49030
49067
|
*/
|
|
49031
49068
|
async makeRequest(endpoint, method = "GET", body) {
|
|
49069
|
+
await rateLimiters.alpaca.acquire();
|
|
49032
49070
|
const url = `${this.apiBaseUrl}${endpoint}`;
|
|
49033
49071
|
const options = {
|
|
49034
49072
|
method,
|
|
@@ -49037,14 +49075,26 @@ class AlpacaClient {
|
|
|
49037
49075
|
if (body && (method === "POST" || method === "PUT")) {
|
|
49038
49076
|
options.body = JSON.stringify(body);
|
|
49039
49077
|
}
|
|
49040
|
-
|
|
49078
|
+
return withRetry(async () => {
|
|
49041
49079
|
const response = await fetch(url, {
|
|
49042
49080
|
...options,
|
|
49043
49081
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
49044
49082
|
});
|
|
49045
49083
|
if (!response.ok) {
|
|
49046
49084
|
const errorText = await response.text();
|
|
49047
|
-
|
|
49085
|
+
const statusCode = response.status;
|
|
49086
|
+
// Classify error for retry logic
|
|
49087
|
+
if (statusCode === 429) {
|
|
49088
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
49089
|
+
throw new Error(`RATE_LIMIT: ${statusCode}${retryAfter ? `:${parseInt(retryAfter, 10) * 1000}` : ""}`);
|
|
49090
|
+
}
|
|
49091
|
+
if ([500, 502, 503, 504].includes(statusCode)) {
|
|
49092
|
+
throw new Error(`SERVER_ERROR: ${statusCode}`);
|
|
49093
|
+
}
|
|
49094
|
+
if ([401, 403].includes(statusCode)) {
|
|
49095
|
+
throw new Error(`AUTH_ERROR: ${statusCode}: ${errorText}`);
|
|
49096
|
+
}
|
|
49097
|
+
throw new Error(`CLIENT_ERROR: ${statusCode}: ${errorText}`);
|
|
49048
49098
|
}
|
|
49049
49099
|
// Handle empty responses (e.g., DELETE requests)
|
|
49050
49100
|
const contentType = response.headers.get("content-type");
|
|
@@ -49053,14 +49103,13 @@ class AlpacaClient {
|
|
|
49053
49103
|
return emptyObj;
|
|
49054
49104
|
}
|
|
49055
49105
|
return (await response.json());
|
|
49056
|
-
}
|
|
49057
|
-
|
|
49058
|
-
|
|
49059
|
-
|
|
49060
|
-
|
|
49061
|
-
|
|
49062
|
-
|
|
49063
|
-
}
|
|
49106
|
+
}, {
|
|
49107
|
+
maxRetries: 2,
|
|
49108
|
+
baseDelayMs: 1000,
|
|
49109
|
+
maxDelayMs: 10000,
|
|
49110
|
+
retryableStatusCodes: [429, 500, 502, 503, 504],
|
|
49111
|
+
retryOnNetworkError: true,
|
|
49112
|
+
}, `Alpaca ${method} ${endpoint}`);
|
|
49064
49113
|
}
|
|
49065
49114
|
}
|
|
49066
49115
|
// Client cache for connection pooling
|
|
@@ -49397,7 +49446,7 @@ async function getAccountDetails(client) {
|
|
|
49397
49446
|
log$i("Fetching account details");
|
|
49398
49447
|
try {
|
|
49399
49448
|
const sdk = client.getSDK();
|
|
49400
|
-
const account = await sdk.getAccount();
|
|
49449
|
+
const account = await client.executeWithRateLimit(() => sdk.getAccount(), "getAccount");
|
|
49401
49450
|
log$i(`Account details fetched successfully for account ${account.account_number}`);
|
|
49402
49451
|
return account;
|
|
49403
49452
|
}
|
|
@@ -49416,7 +49465,7 @@ async function getAccountConfiguration(client) {
|
|
|
49416
49465
|
log$i("Fetching account configuration");
|
|
49417
49466
|
try {
|
|
49418
49467
|
const sdk = client.getSDK();
|
|
49419
|
-
const config = await sdk.getAccountConfigurations();
|
|
49468
|
+
const config = await client.executeWithRateLimit(() => sdk.getAccountConfigurations(), "getAccountConfigurations");
|
|
49420
49469
|
log$i("Account configuration fetched successfully");
|
|
49421
49470
|
return config;
|
|
49422
49471
|
}
|
|
@@ -49438,7 +49487,7 @@ async function updateAccountConfiguration(client, config) {
|
|
|
49438
49487
|
log$i("Updating account configuration");
|
|
49439
49488
|
try {
|
|
49440
49489
|
const sdk = client.getSDK();
|
|
49441
|
-
const updatedConfig = await sdk.updateAccountConfigurations(config);
|
|
49490
|
+
const updatedConfig = await client.executeWithRateLimit(() => sdk.updateAccountConfigurations(config), "updateAccountConfigurations");
|
|
49442
49491
|
log$i("Account configuration updated successfully");
|
|
49443
49492
|
return updatedConfig;
|
|
49444
49493
|
}
|
|
@@ -49460,7 +49509,7 @@ async function getPortfolioHistory(client, params) {
|
|
|
49460
49509
|
log$i(`Fetching portfolio history with period: ${params.period || "default"}, timeframe: ${params.timeframe || "default"}`);
|
|
49461
49510
|
try {
|
|
49462
49511
|
const sdk = client.getSDK();
|
|
49463
|
-
const history = await sdk.getPortfolioHistory(params);
|
|
49512
|
+
const history = await client.executeWithRateLimit(() => sdk.getPortfolioHistory(params), "getPortfolioHistory");
|
|
49464
49513
|
log$i(`Portfolio history fetched successfully with ${history.equity?.length || 0} data points`);
|
|
49465
49514
|
return history;
|
|
49466
49515
|
}
|
|
@@ -52176,7 +52225,7 @@ async function getAlpacaClock(client) {
|
|
|
52176
52225
|
log$d("Fetching market clock");
|
|
52177
52226
|
try {
|
|
52178
52227
|
const sdk = client.getSDK();
|
|
52179
|
-
const clock = await sdk.getClock();
|
|
52228
|
+
const clock = await client.executeWithRateLimit(() => sdk.getClock(), "getClock");
|
|
52180
52229
|
log$d(`Market clock fetched: is_open=${clock.is_open}, next_open=${clock.next_open}`);
|
|
52181
52230
|
return clock;
|
|
52182
52231
|
}
|
|
@@ -52221,10 +52270,10 @@ async function getAlpacaCalendar(client, options) {
|
|
|
52221
52270
|
log$d(`Fetching market calendar${startStr ? ` from ${startStr}` : ""}${endStr ? ` to ${endStr}` : ""}`);
|
|
52222
52271
|
try {
|
|
52223
52272
|
const sdk = client.getSDK();
|
|
52224
|
-
const calendar = await sdk.getCalendar({
|
|
52273
|
+
const calendar = await client.executeWithRateLimit(() => sdk.getCalendar({
|
|
52225
52274
|
start: startStr,
|
|
52226
52275
|
end: endStr,
|
|
52227
|
-
});
|
|
52276
|
+
}), "getCalendar");
|
|
52228
52277
|
log$d(`Market calendar fetched: ${calendar.length} trading days`);
|
|
52229
52278
|
return calendar;
|
|
52230
52279
|
}
|
|
@@ -52283,9 +52332,9 @@ async function getLatestQuote(client, symbol, feed) {
|
|
|
52283
52332
|
const config = client.getConfig();
|
|
52284
52333
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52285
52334
|
// Use SDK's getLatestQuote method
|
|
52286
|
-
const response = await sdk.getLatestQuote(normalizedSymbol, {
|
|
52335
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestQuote(normalizedSymbol, {
|
|
52287
52336
|
feed: dataFeed,
|
|
52288
|
-
});
|
|
52337
|
+
}), "getLatestQuote");
|
|
52289
52338
|
if (!response) {
|
|
52290
52339
|
throw new QuoteError(`No quote data returned for ${normalizedSymbol}`, "NO_DATA", normalizedSymbol);
|
|
52291
52340
|
}
|
|
@@ -52340,9 +52389,9 @@ async function getLatestQuotes(client, symbols, feed) {
|
|
|
52340
52389
|
const config = client.getConfig();
|
|
52341
52390
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52342
52391
|
// Use SDK's getLatestQuotes method
|
|
52343
|
-
const response = await sdk.getLatestQuotes(normalizedSymbols, {
|
|
52392
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestQuotes(normalizedSymbols, {
|
|
52344
52393
|
feed: dataFeed,
|
|
52345
|
-
});
|
|
52394
|
+
}), "getLatestQuotes");
|
|
52346
52395
|
if (!response) {
|
|
52347
52396
|
throw new QuoteError("No quote data returned", "NO_DATA");
|
|
52348
52397
|
}
|
|
@@ -52545,7 +52594,8 @@ async function getBars(client, params) {
|
|
|
52545
52594
|
for (const symbol of normalizedSymbols) {
|
|
52546
52595
|
result.set(symbol, []);
|
|
52547
52596
|
}
|
|
52548
|
-
//
|
|
52597
|
+
// Acquire rate limit token before starting the async iterator
|
|
52598
|
+
await client.executeWithRateLimit(() => Promise.resolve(), "getBarsV2");
|
|
52549
52599
|
const barsIterator = sdk.getBarsV2(normalizedSymbols.join(","), options);
|
|
52550
52600
|
for await (const bar of barsIterator) {
|
|
52551
52601
|
const symbol = bar.Symbol;
|
|
@@ -52595,9 +52645,9 @@ async function getLatestBars(client, symbols) {
|
|
|
52595
52645
|
const sdk = client.getSDK();
|
|
52596
52646
|
const config = client.getConfig();
|
|
52597
52647
|
const dataFeed = config.dataFeed || "iex";
|
|
52598
|
-
const response = await sdk.getLatestBars(normalizedSymbols, {
|
|
52648
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestBars(normalizedSymbols, {
|
|
52599
52649
|
feed: dataFeed,
|
|
52600
|
-
});
|
|
52650
|
+
}), "getLatestBars");
|
|
52601
52651
|
const result = new Map();
|
|
52602
52652
|
for (const [symbol, bar] of Object.entries(response)) {
|
|
52603
52653
|
const b = bar;
|
|
@@ -52885,9 +52935,9 @@ async function getLatestTrade(client, symbol, feed) {
|
|
|
52885
52935
|
const config = client.getConfig();
|
|
52886
52936
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52887
52937
|
// Use SDK's getLatestTrade method
|
|
52888
|
-
const response = await sdk.getLatestTrade(normalizedSymbol, {
|
|
52938
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestTrade(normalizedSymbol, {
|
|
52889
52939
|
feed: dataFeed,
|
|
52890
|
-
});
|
|
52940
|
+
}), "getLatestTrade");
|
|
52891
52941
|
if (!response) {
|
|
52892
52942
|
throw new TradeError(`No trade data returned for ${normalizedSymbol}`, "NO_DATA", normalizedSymbol);
|
|
52893
52943
|
}
|
|
@@ -52940,9 +52990,9 @@ async function getLatestTrades(client, symbols, feed) {
|
|
|
52940
52990
|
const config = client.getConfig();
|
|
52941
52991
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52942
52992
|
// Use SDK's getLatestTrades method
|
|
52943
|
-
const response = await sdk.getLatestTrades(normalizedSymbols, {
|
|
52993
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestTrades(normalizedSymbols, {
|
|
52944
52994
|
feed: dataFeed,
|
|
52945
|
-
});
|
|
52995
|
+
}), "getLatestTrades");
|
|
52946
52996
|
if (!response) {
|
|
52947
52997
|
throw new TradeError("No trade data returned", "NO_DATA");
|
|
52948
52998
|
}
|
|
@@ -53004,7 +53054,8 @@ async function getHistoricalTrades(client, params) {
|
|
|
53004
53054
|
options.limit = limit;
|
|
53005
53055
|
}
|
|
53006
53056
|
const trades = [];
|
|
53007
|
-
//
|
|
53057
|
+
// Acquire rate limit token before starting the async iterator
|
|
53058
|
+
await client.executeWithRateLimit(() => Promise.resolve(), "getTradesV2");
|
|
53008
53059
|
const tradesIterator = sdk.getTradesV2(normalizedSymbol, options);
|
|
53009
53060
|
for await (const trade of tradesIterator) {
|
|
53010
53061
|
trades.push({
|
|
@@ -53479,7 +53530,7 @@ async function getNews(client, params = {}) {
|
|
|
53479
53530
|
options.include_content = true;
|
|
53480
53531
|
}
|
|
53481
53532
|
// Use SDK's getNews method
|
|
53482
|
-
const response = await sdk.getNews(options);
|
|
53533
|
+
const response = await client.executeWithRateLimit(() => sdk.getNews(options), "getNews");
|
|
53483
53534
|
if (!response || !Array.isArray(response)) {
|
|
53484
53535
|
log$9("No news data returned", { type: "debug" });
|
|
53485
53536
|
return [];
|
|
@@ -55290,7 +55341,7 @@ async function createOrder(client, params) {
|
|
|
55290
55341
|
});
|
|
55291
55342
|
try {
|
|
55292
55343
|
const sdk = client.getSDK();
|
|
55293
|
-
const order = await sdk.createOrder(params);
|
|
55344
|
+
const order = await client.executeWithRateLimit(() => sdk.createOrder(params), `createOrder ${symbol}`);
|
|
55294
55345
|
log$6(`Order created successfully: ${order.id}`, {
|
|
55295
55346
|
type: "info",
|
|
55296
55347
|
symbol,
|
|
@@ -55329,7 +55380,7 @@ async function getOrder(client, orderId) {
|
|
|
55329
55380
|
log$6(`Fetching order: ${orderId}`, { type: "debug" });
|
|
55330
55381
|
try {
|
|
55331
55382
|
const sdk = client.getSDK();
|
|
55332
|
-
const order = await sdk.getOrder(orderId);
|
|
55383
|
+
const order = await client.executeWithRateLimit(() => sdk.getOrder(orderId), `getOrder ${orderId}`);
|
|
55333
55384
|
log$6(`Order retrieved: ${orderId} (${order.status})`, {
|
|
55334
55385
|
type: "debug",
|
|
55335
55386
|
symbol: order.symbol,
|
|
@@ -55392,7 +55443,7 @@ async function getOrders(client, params = {}) {
|
|
|
55392
55443
|
}
|
|
55393
55444
|
if (params.side)
|
|
55394
55445
|
queryParams.side = params.side;
|
|
55395
|
-
const orders = await sdk.getOrders(queryParams);
|
|
55446
|
+
const orders = await client.executeWithRateLimit(() => sdk.getOrders(queryParams), "getOrders");
|
|
55396
55447
|
log$6(`Retrieved ${orders.length} orders`, {
|
|
55397
55448
|
type: "debug",
|
|
55398
55449
|
metadata: { count: orders.length, status: filterDescription },
|
|
@@ -55421,7 +55472,7 @@ async function cancelOrder(client, orderId) {
|
|
|
55421
55472
|
log$6(`Canceling order: ${orderId}`, { type: "info" });
|
|
55422
55473
|
try {
|
|
55423
55474
|
const sdk = client.getSDK();
|
|
55424
|
-
await sdk.cancelOrder(orderId);
|
|
55475
|
+
await client.executeWithRateLimit(() => sdk.cancelOrder(orderId), "cancelOrder");
|
|
55425
55476
|
log$6(`Order canceled successfully: ${orderId}`, { type: "info" });
|
|
55426
55477
|
}
|
|
55427
55478
|
catch (error) {
|
|
@@ -55463,7 +55514,7 @@ async function cancelAllOrders(client) {
|
|
|
55463
55514
|
log$6("Canceling all open orders", { type: "info" });
|
|
55464
55515
|
try {
|
|
55465
55516
|
const sdk = client.getSDK();
|
|
55466
|
-
const result = await sdk.cancelAllOrders();
|
|
55517
|
+
const result = await client.executeWithRateLimit(() => sdk.cancelAllOrders(), "cancelAllOrders");
|
|
55467
55518
|
// The SDK returns an array of canceled order statuses
|
|
55468
55519
|
const canceled = Array.isArray(result) ? result.length : 0;
|
|
55469
55520
|
const failed = [];
|
|
@@ -55523,7 +55574,7 @@ async function replaceOrder(client, orderId, params) {
|
|
|
55523
55574
|
});
|
|
55524
55575
|
try {
|
|
55525
55576
|
const sdk = client.getSDK();
|
|
55526
|
-
const newOrder = await sdk.replaceOrder(orderId, params);
|
|
55577
|
+
const newOrder = await client.executeWithRateLimit(() => sdk.replaceOrder(orderId, params), "replaceOrder");
|
|
55527
55578
|
log$6(`Order replaced successfully: ${orderId} -> ${newOrder.id}`, {
|
|
55528
55579
|
type: "info",
|
|
55529
55580
|
symbol: newOrder.symbol,
|
|
@@ -55628,7 +55679,7 @@ async function getOrderByClientId(client, clientOrderId) {
|
|
|
55628
55679
|
log$6(`Fetching order by client_order_id: ${clientOrderId}`, { type: "debug" });
|
|
55629
55680
|
try {
|
|
55630
55681
|
const sdk = client.getSDK();
|
|
55631
|
-
const order = await sdk.getOrderByClientId(clientOrderId);
|
|
55682
|
+
const order = await client.executeWithRateLimit(() => sdk.getOrderByClientId(clientOrderId), "getOrderByClientId");
|
|
55632
55683
|
log$6(`Order retrieved by client_order_id: ${clientOrderId} -> ${order.id}`, {
|
|
55633
55684
|
type: "debug",
|
|
55634
55685
|
symbol: order.symbol,
|
|
@@ -58569,7 +58620,7 @@ async function getPositions(client) {
|
|
|
58569
58620
|
log("Fetching all open positions", { type: "debug" });
|
|
58570
58621
|
try {
|
|
58571
58622
|
const sdk = client.getSDK();
|
|
58572
|
-
const positions = (await sdk.getPositions());
|
|
58623
|
+
const positions = (await client.executeWithRateLimit(() => sdk.getPositions(), "getPositions"));
|
|
58573
58624
|
log(`Retrieved ${positions.length} positions`, { type: "info" });
|
|
58574
58625
|
return positions;
|
|
58575
58626
|
}
|
|
@@ -58623,7 +58674,7 @@ async function getPosition(client, symbol) {
|
|
|
58623
58674
|
log(`Fetching position for symbol: ${symbol}`, { type: "debug", symbol });
|
|
58624
58675
|
try {
|
|
58625
58676
|
const sdk = client.getSDK();
|
|
58626
|
-
const position = (await sdk.getPosition(symbol));
|
|
58677
|
+
const position = (await client.executeWithRateLimit(() => sdk.getPosition(symbol), "getPosition"));
|
|
58627
58678
|
log(`Found position for ${symbol}: ${position.qty} shares`, {
|
|
58628
58679
|
type: "info",
|
|
58629
58680
|
symbol,
|
|
@@ -58770,10 +58821,10 @@ async function closePosition(client, symbol, options) {
|
|
|
58770
58821
|
let order;
|
|
58771
58822
|
if (Object.keys(queryParams).length > 0) {
|
|
58772
58823
|
// SDK doesn't support params, use sendRequest directly
|
|
58773
|
-
order = (await sdk.sendRequest(`/positions/${encodeURIComponent(normalizedSymbol)}`, queryParams, null, "DELETE"));
|
|
58824
|
+
order = (await client.executeWithRateLimit(() => sdk.sendRequest(`/positions/${encodeURIComponent(normalizedSymbol)}`, queryParams, null, "DELETE"), "closePosition"));
|
|
58774
58825
|
}
|
|
58775
58826
|
else {
|
|
58776
|
-
order = (await sdk.closePosition(normalizedSymbol));
|
|
58827
|
+
order = (await client.executeWithRateLimit(() => sdk.closePosition(normalizedSymbol), "closePosition"));
|
|
58777
58828
|
}
|
|
58778
58829
|
log(`Position close order created for ${normalizedSymbol}: ${order.id}`, {
|
|
58779
58830
|
type: "info",
|
|
@@ -58814,7 +58865,7 @@ async function closeAllPositions(client, options) {
|
|
|
58814
58865
|
cancel_orders: cancelOrders.toString(),
|
|
58815
58866
|
};
|
|
58816
58867
|
// Use sendRequest to pass the cancel_orders parameter
|
|
58817
|
-
const response = await sdk.sendRequest("/positions", queryParams, null, "DELETE");
|
|
58868
|
+
const response = await client.executeWithRateLimit(() => sdk.sendRequest("/positions", queryParams, null, "DELETE"), "closeAllPositions");
|
|
58818
58869
|
// The SDK returns an array of objects with order info
|
|
58819
58870
|
const orders = Array.isArray(response) ? response : [];
|
|
58820
58871
|
log(`Closed ${orders.length} positions`, { type: "info" });
|
|
@@ -58849,7 +58900,7 @@ async function closeAllPositionsAfterHours(client, options) {
|
|
|
58849
58900
|
return [];
|
|
58850
58901
|
}
|
|
58851
58902
|
// First cancel all open orders
|
|
58852
|
-
await sdk.cancelAllOrders();
|
|
58903
|
+
await client.executeWithRateLimit(() => sdk.cancelAllOrders(), "cancelAllOrders");
|
|
58853
58904
|
log("Cancelled all open orders", { type: "info" });
|
|
58854
58905
|
const orders = [];
|
|
58855
58906
|
const offsetMultiplier = limitPriceOffset / 100;
|
|
@@ -58870,7 +58921,7 @@ async function closeAllPositionsAfterHours(client, options) {
|
|
|
58870
58921
|
: roundPriceForAlpaca(currentPrice * (1 + offsetMultiplier));
|
|
58871
58922
|
log(`Creating limit order to close ${position.symbol}: ${side} ${qty} shares at $${limitPrice.toFixed(2)}`, { type: "info", symbol: position.symbol });
|
|
58872
58923
|
try {
|
|
58873
|
-
const order = (await sdk.createOrder({
|
|
58924
|
+
const order = (await client.executeWithRateLimit(() => sdk.createOrder({
|
|
58874
58925
|
symbol: position.symbol,
|
|
58875
58926
|
qty: qty,
|
|
58876
58927
|
side: side,
|
|
@@ -58878,7 +58929,7 @@ async function closeAllPositionsAfterHours(client, options) {
|
|
|
58878
58929
|
time_in_force: "day",
|
|
58879
58930
|
limit_price: limitPrice,
|
|
58880
58931
|
extended_hours: true,
|
|
58881
|
-
}));
|
|
58932
|
+
}), `createOrder ${position.symbol}`));
|
|
58882
58933
|
orders.push(order);
|
|
58883
58934
|
}
|
|
58884
58935
|
catch (orderError) {
|