@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.cjs
CHANGED
|
@@ -8018,8 +8018,9 @@ const fetchTickerInfo = async (symbol, options) => {
|
|
|
8018
8018
|
apiKey,
|
|
8019
8019
|
});
|
|
8020
8020
|
return massiveLimit(async () => {
|
|
8021
|
+
await rateLimiters.massive.acquire();
|
|
8021
8022
|
try {
|
|
8022
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8023
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8023
8024
|
const data = await response.json();
|
|
8024
8025
|
// Check for "NOT_FOUND" status and return null
|
|
8025
8026
|
if (data.status === "NOT_FOUND") {
|
|
@@ -8130,8 +8131,9 @@ const fetchLastTradeImpl = async (symbol, options) => {
|
|
|
8130
8131
|
order: "desc",
|
|
8131
8132
|
});
|
|
8132
8133
|
return massiveLimit(async () => {
|
|
8134
|
+
await rateLimiters.massive.acquire();
|
|
8133
8135
|
try {
|
|
8134
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8136
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8135
8137
|
const data = (await response.json());
|
|
8136
8138
|
if ("message" in data) {
|
|
8137
8139
|
throw new Error(`Massive.com API error: ${data.message}`);
|
|
@@ -8200,8 +8202,9 @@ const fetchLastQuote = async (symbol, options) => {
|
|
|
8200
8202
|
order: "desc",
|
|
8201
8203
|
});
|
|
8202
8204
|
return massiveLimit(async () => {
|
|
8205
|
+
await rateLimiters.massive.acquire();
|
|
8203
8206
|
try {
|
|
8204
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8207
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8205
8208
|
const data = (await response.json());
|
|
8206
8209
|
if ("message" in data) {
|
|
8207
8210
|
throw new Error(`Massive.com API error: ${data.message}`);
|
|
@@ -8284,7 +8287,7 @@ const fetchPrices = async (params, options) => {
|
|
|
8284
8287
|
while (nextUrl) {
|
|
8285
8288
|
//getLogger().info(`Debug: Fetching ${nextUrl}`);
|
|
8286
8289
|
await rateLimiters.massive.acquire();
|
|
8287
|
-
const response = await fetchWithRetry(nextUrl, {}, 3, 1000);
|
|
8290
|
+
const response = await fetchWithRetry(nextUrl, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8288
8291
|
const data = await response.json();
|
|
8289
8292
|
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
8290
8293
|
throw new Error(`Massive.com API responded with status: ${data.status}`);
|
|
@@ -8405,8 +8408,9 @@ const fetchGroupedDaily = async (date, options) => {
|
|
|
8405
8408
|
include_otc: options?.includeOTC ? "true" : "false",
|
|
8406
8409
|
});
|
|
8407
8410
|
return massiveLimit(async () => {
|
|
8411
|
+
await rateLimiters.massive.acquire();
|
|
8408
8412
|
try {
|
|
8409
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
8413
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8410
8414
|
const data = await response.json();
|
|
8411
8415
|
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
8412
8416
|
throw new Error(`Massive.com API responded with status: ${data.status}`);
|
|
@@ -8498,12 +8502,20 @@ symbol, date = new Date(), options) => {
|
|
|
8498
8502
|
adjusted: (options?.adjusted ?? true).toString(),
|
|
8499
8503
|
});
|
|
8500
8504
|
return massiveLimit(async () => {
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
+
await rateLimiters.massive.acquire();
|
|
8506
|
+
try {
|
|
8507
|
+
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8508
|
+
const data = await response.json();
|
|
8509
|
+
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
8510
|
+
throw new Error(`Failed to fetch daily open/close data for ${symbol}: ${data.status}`);
|
|
8511
|
+
}
|
|
8512
|
+
return data;
|
|
8513
|
+
}
|
|
8514
|
+
catch (error) {
|
|
8515
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
8516
|
+
getLogger().error(`Error fetching daily open/close for ${symbol}: ${errorMessage}`);
|
|
8517
|
+
throw error;
|
|
8505
8518
|
}
|
|
8506
|
-
return data;
|
|
8507
8519
|
});
|
|
8508
8520
|
};
|
|
8509
8521
|
/**
|
|
@@ -8564,10 +8576,11 @@ const fetchTrades = async (symbol, options) => {
|
|
|
8564
8576
|
if (options?.sort)
|
|
8565
8577
|
params.append("sort", options.sort);
|
|
8566
8578
|
return massiveLimit(async () => {
|
|
8579
|
+
await rateLimiters.massive.acquire();
|
|
8567
8580
|
const url = `${baseUrl}?${params.toString()}`;
|
|
8568
8581
|
try {
|
|
8569
8582
|
logIfDebug(`Fetching trades for ${symbol} from ${url}`);
|
|
8570
|
-
const response = await fetchWithRetry(url, {}, 3, 1000);
|
|
8583
|
+
const response = await fetchWithRetry(url, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
|
|
8571
8584
|
const data = (await response.json());
|
|
8572
8585
|
if ("message" in data) {
|
|
8573
8586
|
// This is an error response
|
|
@@ -8643,8 +8656,9 @@ const fetchIndicesAggregates = async (params, options) => {
|
|
|
8643
8656
|
}
|
|
8644
8657
|
url.search = queryParams.toString();
|
|
8645
8658
|
return massiveIndicesLimit(async () => {
|
|
8659
|
+
await rateLimiters.massive.acquire();
|
|
8646
8660
|
try {
|
|
8647
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8661
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8648
8662
|
const data = await response.json();
|
|
8649
8663
|
if (data.status === "ERROR") {
|
|
8650
8664
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8672,8 +8686,9 @@ const fetchIndicesPreviousClose = async (indicesTicker, options) => {
|
|
|
8672
8686
|
queryParams.append("apiKey", apiKey);
|
|
8673
8687
|
url.search = queryParams.toString();
|
|
8674
8688
|
return massiveIndicesLimit(async () => {
|
|
8689
|
+
await rateLimiters.massive.acquire();
|
|
8675
8690
|
try {
|
|
8676
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8691
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8677
8692
|
const data = await response.json();
|
|
8678
8693
|
if (data.status === "ERROR") {
|
|
8679
8694
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8702,8 +8717,9 @@ const fetchIndicesDailyOpenClose = async (indicesTicker, date, options) => {
|
|
|
8702
8717
|
queryParams.append("apiKey", apiKey);
|
|
8703
8718
|
url.search = queryParams.toString();
|
|
8704
8719
|
return massiveIndicesLimit(async () => {
|
|
8720
|
+
await rateLimiters.massive.acquire();
|
|
8705
8721
|
try {
|
|
8706
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8722
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8707
8723
|
const data = await response.json();
|
|
8708
8724
|
if (data.status === "ERROR") {
|
|
8709
8725
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8743,8 +8759,9 @@ const fetchIndicesSnapshot = async (params, options) => {
|
|
|
8743
8759
|
}
|
|
8744
8760
|
url.search = queryParams.toString();
|
|
8745
8761
|
return massiveIndicesLimit(async () => {
|
|
8762
|
+
await rateLimiters.massive.acquire();
|
|
8746
8763
|
try {
|
|
8747
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8764
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8748
8765
|
const data = await response.json();
|
|
8749
8766
|
if (data.status === "ERROR") {
|
|
8750
8767
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -8791,8 +8808,9 @@ const fetchUniversalSnapshot = async (tickers, options) => {
|
|
|
8791
8808
|
}
|
|
8792
8809
|
url.search = queryParams.toString();
|
|
8793
8810
|
return massiveIndicesLimit(async () => {
|
|
8811
|
+
await rateLimiters.massive.acquire();
|
|
8794
8812
|
try {
|
|
8795
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
8813
|
+
const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
|
|
8796
8814
|
const data = await response.json();
|
|
8797
8815
|
if (data.status === "ERROR") {
|
|
8798
8816
|
throw new Error(`Massive API Error: ${data.error}`);
|
|
@@ -48981,6 +48999,25 @@ class AlpacaClient {
|
|
|
48981
48999
|
isPaper() {
|
|
48982
49000
|
return this.config.accountType === "PAPER";
|
|
48983
49001
|
}
|
|
49002
|
+
/**
|
|
49003
|
+
* Execute an Alpaca SDK operation with rate limiting and retry.
|
|
49004
|
+
* Use this for all SDK calls to prevent rate limit breaches and handle
|
|
49005
|
+
* transient failures during market hours.
|
|
49006
|
+
*
|
|
49007
|
+
* @param operation - Async function that calls the SDK
|
|
49008
|
+
* @param label - Human-readable label for logging
|
|
49009
|
+
* @returns Result of the operation
|
|
49010
|
+
*/
|
|
49011
|
+
async executeWithRateLimit(operation, label) {
|
|
49012
|
+
await rateLimiters.alpaca.acquire();
|
|
49013
|
+
return withRetry(operation, {
|
|
49014
|
+
maxRetries: 2,
|
|
49015
|
+
baseDelayMs: 1000,
|
|
49016
|
+
maxDelayMs: 10000,
|
|
49017
|
+
retryableStatusCodes: [429, 500, 502, 503, 504],
|
|
49018
|
+
retryOnNetworkError: true,
|
|
49019
|
+
}, `Alpaca SDK: ${label}`);
|
|
49020
|
+
}
|
|
48984
49021
|
/**
|
|
48985
49022
|
* Validate credentials by fetching account info
|
|
48986
49023
|
*/
|
|
@@ -49031,6 +49068,7 @@ class AlpacaClient {
|
|
|
49031
49068
|
* @returns Response data
|
|
49032
49069
|
*/
|
|
49033
49070
|
async makeRequest(endpoint, method = "GET", body) {
|
|
49071
|
+
await rateLimiters.alpaca.acquire();
|
|
49034
49072
|
const url = `${this.apiBaseUrl}${endpoint}`;
|
|
49035
49073
|
const options = {
|
|
49036
49074
|
method,
|
|
@@ -49039,14 +49077,26 @@ class AlpacaClient {
|
|
|
49039
49077
|
if (body && (method === "POST" || method === "PUT")) {
|
|
49040
49078
|
options.body = JSON.stringify(body);
|
|
49041
49079
|
}
|
|
49042
|
-
|
|
49080
|
+
return withRetry(async () => {
|
|
49043
49081
|
const response = await fetch(url, {
|
|
49044
49082
|
...options,
|
|
49045
49083
|
signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
|
|
49046
49084
|
});
|
|
49047
49085
|
if (!response.ok) {
|
|
49048
49086
|
const errorText = await response.text();
|
|
49049
|
-
|
|
49087
|
+
const statusCode = response.status;
|
|
49088
|
+
// Classify error for retry logic
|
|
49089
|
+
if (statusCode === 429) {
|
|
49090
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
49091
|
+
throw new Error(`RATE_LIMIT: ${statusCode}${retryAfter ? `:${parseInt(retryAfter, 10) * 1000}` : ""}`);
|
|
49092
|
+
}
|
|
49093
|
+
if ([500, 502, 503, 504].includes(statusCode)) {
|
|
49094
|
+
throw new Error(`SERVER_ERROR: ${statusCode}`);
|
|
49095
|
+
}
|
|
49096
|
+
if ([401, 403].includes(statusCode)) {
|
|
49097
|
+
throw new Error(`AUTH_ERROR: ${statusCode}: ${errorText}`);
|
|
49098
|
+
}
|
|
49099
|
+
throw new Error(`CLIENT_ERROR: ${statusCode}: ${errorText}`);
|
|
49050
49100
|
}
|
|
49051
49101
|
// Handle empty responses (e.g., DELETE requests)
|
|
49052
49102
|
const contentType = response.headers.get("content-type");
|
|
@@ -49055,14 +49105,13 @@ class AlpacaClient {
|
|
|
49055
49105
|
return emptyObj;
|
|
49056
49106
|
}
|
|
49057
49107
|
return (await response.json());
|
|
49058
|
-
}
|
|
49059
|
-
|
|
49060
|
-
|
|
49061
|
-
|
|
49062
|
-
|
|
49063
|
-
|
|
49064
|
-
|
|
49065
|
-
}
|
|
49108
|
+
}, {
|
|
49109
|
+
maxRetries: 2,
|
|
49110
|
+
baseDelayMs: 1000,
|
|
49111
|
+
maxDelayMs: 10000,
|
|
49112
|
+
retryableStatusCodes: [429, 500, 502, 503, 504],
|
|
49113
|
+
retryOnNetworkError: true,
|
|
49114
|
+
}, `Alpaca ${method} ${endpoint}`);
|
|
49066
49115
|
}
|
|
49067
49116
|
}
|
|
49068
49117
|
// Client cache for connection pooling
|
|
@@ -49399,7 +49448,7 @@ async function getAccountDetails(client) {
|
|
|
49399
49448
|
log$i("Fetching account details");
|
|
49400
49449
|
try {
|
|
49401
49450
|
const sdk = client.getSDK();
|
|
49402
|
-
const account = await sdk.getAccount();
|
|
49451
|
+
const account = await client.executeWithRateLimit(() => sdk.getAccount(), "getAccount");
|
|
49403
49452
|
log$i(`Account details fetched successfully for account ${account.account_number}`);
|
|
49404
49453
|
return account;
|
|
49405
49454
|
}
|
|
@@ -49418,7 +49467,7 @@ async function getAccountConfiguration(client) {
|
|
|
49418
49467
|
log$i("Fetching account configuration");
|
|
49419
49468
|
try {
|
|
49420
49469
|
const sdk = client.getSDK();
|
|
49421
|
-
const config = await sdk.getAccountConfigurations();
|
|
49470
|
+
const config = await client.executeWithRateLimit(() => sdk.getAccountConfigurations(), "getAccountConfigurations");
|
|
49422
49471
|
log$i("Account configuration fetched successfully");
|
|
49423
49472
|
return config;
|
|
49424
49473
|
}
|
|
@@ -49440,7 +49489,7 @@ async function updateAccountConfiguration(client, config) {
|
|
|
49440
49489
|
log$i("Updating account configuration");
|
|
49441
49490
|
try {
|
|
49442
49491
|
const sdk = client.getSDK();
|
|
49443
|
-
const updatedConfig = await sdk.updateAccountConfigurations(config);
|
|
49492
|
+
const updatedConfig = await client.executeWithRateLimit(() => sdk.updateAccountConfigurations(config), "updateAccountConfigurations");
|
|
49444
49493
|
log$i("Account configuration updated successfully");
|
|
49445
49494
|
return updatedConfig;
|
|
49446
49495
|
}
|
|
@@ -49462,7 +49511,7 @@ async function getPortfolioHistory(client, params) {
|
|
|
49462
49511
|
log$i(`Fetching portfolio history with period: ${params.period || "default"}, timeframe: ${params.timeframe || "default"}`);
|
|
49463
49512
|
try {
|
|
49464
49513
|
const sdk = client.getSDK();
|
|
49465
|
-
const history = await sdk.getPortfolioHistory(params);
|
|
49514
|
+
const history = await client.executeWithRateLimit(() => sdk.getPortfolioHistory(params), "getPortfolioHistory");
|
|
49466
49515
|
log$i(`Portfolio history fetched successfully with ${history.equity?.length || 0} data points`);
|
|
49467
49516
|
return history;
|
|
49468
49517
|
}
|
|
@@ -52178,7 +52227,7 @@ async function getAlpacaClock(client) {
|
|
|
52178
52227
|
log$d("Fetching market clock");
|
|
52179
52228
|
try {
|
|
52180
52229
|
const sdk = client.getSDK();
|
|
52181
|
-
const clock = await sdk.getClock();
|
|
52230
|
+
const clock = await client.executeWithRateLimit(() => sdk.getClock(), "getClock");
|
|
52182
52231
|
log$d(`Market clock fetched: is_open=${clock.is_open}, next_open=${clock.next_open}`);
|
|
52183
52232
|
return clock;
|
|
52184
52233
|
}
|
|
@@ -52223,10 +52272,10 @@ async function getAlpacaCalendar(client, options) {
|
|
|
52223
52272
|
log$d(`Fetching market calendar${startStr ? ` from ${startStr}` : ""}${endStr ? ` to ${endStr}` : ""}`);
|
|
52224
52273
|
try {
|
|
52225
52274
|
const sdk = client.getSDK();
|
|
52226
|
-
const calendar = await sdk.getCalendar({
|
|
52275
|
+
const calendar = await client.executeWithRateLimit(() => sdk.getCalendar({
|
|
52227
52276
|
start: startStr,
|
|
52228
52277
|
end: endStr,
|
|
52229
|
-
});
|
|
52278
|
+
}), "getCalendar");
|
|
52230
52279
|
log$d(`Market calendar fetched: ${calendar.length} trading days`);
|
|
52231
52280
|
return calendar;
|
|
52232
52281
|
}
|
|
@@ -52285,9 +52334,9 @@ async function getLatestQuote(client, symbol, feed) {
|
|
|
52285
52334
|
const config = client.getConfig();
|
|
52286
52335
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52287
52336
|
// Use SDK's getLatestQuote method
|
|
52288
|
-
const response = await sdk.getLatestQuote(normalizedSymbol, {
|
|
52337
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestQuote(normalizedSymbol, {
|
|
52289
52338
|
feed: dataFeed,
|
|
52290
|
-
});
|
|
52339
|
+
}), "getLatestQuote");
|
|
52291
52340
|
if (!response) {
|
|
52292
52341
|
throw new QuoteError(`No quote data returned for ${normalizedSymbol}`, "NO_DATA", normalizedSymbol);
|
|
52293
52342
|
}
|
|
@@ -52342,9 +52391,9 @@ async function getLatestQuotes(client, symbols, feed) {
|
|
|
52342
52391
|
const config = client.getConfig();
|
|
52343
52392
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52344
52393
|
// Use SDK's getLatestQuotes method
|
|
52345
|
-
const response = await sdk.getLatestQuotes(normalizedSymbols, {
|
|
52394
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestQuotes(normalizedSymbols, {
|
|
52346
52395
|
feed: dataFeed,
|
|
52347
|
-
});
|
|
52396
|
+
}), "getLatestQuotes");
|
|
52348
52397
|
if (!response) {
|
|
52349
52398
|
throw new QuoteError("No quote data returned", "NO_DATA");
|
|
52350
52399
|
}
|
|
@@ -52547,7 +52596,8 @@ async function getBars(client, params) {
|
|
|
52547
52596
|
for (const symbol of normalizedSymbols) {
|
|
52548
52597
|
result.set(symbol, []);
|
|
52549
52598
|
}
|
|
52550
|
-
//
|
|
52599
|
+
// Acquire rate limit token before starting the async iterator
|
|
52600
|
+
await client.executeWithRateLimit(() => Promise.resolve(), "getBarsV2");
|
|
52551
52601
|
const barsIterator = sdk.getBarsV2(normalizedSymbols.join(","), options);
|
|
52552
52602
|
for await (const bar of barsIterator) {
|
|
52553
52603
|
const symbol = bar.Symbol;
|
|
@@ -52597,9 +52647,9 @@ async function getLatestBars(client, symbols) {
|
|
|
52597
52647
|
const sdk = client.getSDK();
|
|
52598
52648
|
const config = client.getConfig();
|
|
52599
52649
|
const dataFeed = config.dataFeed || "iex";
|
|
52600
|
-
const response = await sdk.getLatestBars(normalizedSymbols, {
|
|
52650
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestBars(normalizedSymbols, {
|
|
52601
52651
|
feed: dataFeed,
|
|
52602
|
-
});
|
|
52652
|
+
}), "getLatestBars");
|
|
52603
52653
|
const result = new Map();
|
|
52604
52654
|
for (const [symbol, bar] of Object.entries(response)) {
|
|
52605
52655
|
const b = bar;
|
|
@@ -52887,9 +52937,9 @@ async function getLatestTrade(client, symbol, feed) {
|
|
|
52887
52937
|
const config = client.getConfig();
|
|
52888
52938
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52889
52939
|
// Use SDK's getLatestTrade method
|
|
52890
|
-
const response = await sdk.getLatestTrade(normalizedSymbol, {
|
|
52940
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestTrade(normalizedSymbol, {
|
|
52891
52941
|
feed: dataFeed,
|
|
52892
|
-
});
|
|
52942
|
+
}), "getLatestTrade");
|
|
52893
52943
|
if (!response) {
|
|
52894
52944
|
throw new TradeError(`No trade data returned for ${normalizedSymbol}`, "NO_DATA", normalizedSymbol);
|
|
52895
52945
|
}
|
|
@@ -52942,9 +52992,9 @@ async function getLatestTrades(client, symbols, feed) {
|
|
|
52942
52992
|
const config = client.getConfig();
|
|
52943
52993
|
const dataFeed = feed || config.dataFeed || "iex";
|
|
52944
52994
|
// Use SDK's getLatestTrades method
|
|
52945
|
-
const response = await sdk.getLatestTrades(normalizedSymbols, {
|
|
52995
|
+
const response = await client.executeWithRateLimit(() => sdk.getLatestTrades(normalizedSymbols, {
|
|
52946
52996
|
feed: dataFeed,
|
|
52947
|
-
});
|
|
52997
|
+
}), "getLatestTrades");
|
|
52948
52998
|
if (!response) {
|
|
52949
52999
|
throw new TradeError("No trade data returned", "NO_DATA");
|
|
52950
53000
|
}
|
|
@@ -53006,7 +53056,8 @@ async function getHistoricalTrades(client, params) {
|
|
|
53006
53056
|
options.limit = limit;
|
|
53007
53057
|
}
|
|
53008
53058
|
const trades = [];
|
|
53009
|
-
//
|
|
53059
|
+
// Acquire rate limit token before starting the async iterator
|
|
53060
|
+
await client.executeWithRateLimit(() => Promise.resolve(), "getTradesV2");
|
|
53010
53061
|
const tradesIterator = sdk.getTradesV2(normalizedSymbol, options);
|
|
53011
53062
|
for await (const trade of tradesIterator) {
|
|
53012
53063
|
trades.push({
|
|
@@ -53481,7 +53532,7 @@ async function getNews(client, params = {}) {
|
|
|
53481
53532
|
options.include_content = true;
|
|
53482
53533
|
}
|
|
53483
53534
|
// Use SDK's getNews method
|
|
53484
|
-
const response = await sdk.getNews(options);
|
|
53535
|
+
const response = await client.executeWithRateLimit(() => sdk.getNews(options), "getNews");
|
|
53485
53536
|
if (!response || !Array.isArray(response)) {
|
|
53486
53537
|
log$9("No news data returned", { type: "debug" });
|
|
53487
53538
|
return [];
|
|
@@ -55292,7 +55343,7 @@ async function createOrder(client, params) {
|
|
|
55292
55343
|
});
|
|
55293
55344
|
try {
|
|
55294
55345
|
const sdk = client.getSDK();
|
|
55295
|
-
const order = await sdk.createOrder(params);
|
|
55346
|
+
const order = await client.executeWithRateLimit(() => sdk.createOrder(params), `createOrder ${symbol}`);
|
|
55296
55347
|
log$6(`Order created successfully: ${order.id}`, {
|
|
55297
55348
|
type: "info",
|
|
55298
55349
|
symbol,
|
|
@@ -55331,7 +55382,7 @@ async function getOrder(client, orderId) {
|
|
|
55331
55382
|
log$6(`Fetching order: ${orderId}`, { type: "debug" });
|
|
55332
55383
|
try {
|
|
55333
55384
|
const sdk = client.getSDK();
|
|
55334
|
-
const order = await sdk.getOrder(orderId);
|
|
55385
|
+
const order = await client.executeWithRateLimit(() => sdk.getOrder(orderId), `getOrder ${orderId}`);
|
|
55335
55386
|
log$6(`Order retrieved: ${orderId} (${order.status})`, {
|
|
55336
55387
|
type: "debug",
|
|
55337
55388
|
symbol: order.symbol,
|
|
@@ -55394,7 +55445,7 @@ async function getOrders(client, params = {}) {
|
|
|
55394
55445
|
}
|
|
55395
55446
|
if (params.side)
|
|
55396
55447
|
queryParams.side = params.side;
|
|
55397
|
-
const orders = await sdk.getOrders(queryParams);
|
|
55448
|
+
const orders = await client.executeWithRateLimit(() => sdk.getOrders(queryParams), "getOrders");
|
|
55398
55449
|
log$6(`Retrieved ${orders.length} orders`, {
|
|
55399
55450
|
type: "debug",
|
|
55400
55451
|
metadata: { count: orders.length, status: filterDescription },
|
|
@@ -55423,7 +55474,7 @@ async function cancelOrder(client, orderId) {
|
|
|
55423
55474
|
log$6(`Canceling order: ${orderId}`, { type: "info" });
|
|
55424
55475
|
try {
|
|
55425
55476
|
const sdk = client.getSDK();
|
|
55426
|
-
await sdk.cancelOrder(orderId);
|
|
55477
|
+
await client.executeWithRateLimit(() => sdk.cancelOrder(orderId), "cancelOrder");
|
|
55427
55478
|
log$6(`Order canceled successfully: ${orderId}`, { type: "info" });
|
|
55428
55479
|
}
|
|
55429
55480
|
catch (error) {
|
|
@@ -55465,7 +55516,7 @@ async function cancelAllOrders(client) {
|
|
|
55465
55516
|
log$6("Canceling all open orders", { type: "info" });
|
|
55466
55517
|
try {
|
|
55467
55518
|
const sdk = client.getSDK();
|
|
55468
|
-
const result = await sdk.cancelAllOrders();
|
|
55519
|
+
const result = await client.executeWithRateLimit(() => sdk.cancelAllOrders(), "cancelAllOrders");
|
|
55469
55520
|
// The SDK returns an array of canceled order statuses
|
|
55470
55521
|
const canceled = Array.isArray(result) ? result.length : 0;
|
|
55471
55522
|
const failed = [];
|
|
@@ -55525,7 +55576,7 @@ async function replaceOrder(client, orderId, params) {
|
|
|
55525
55576
|
});
|
|
55526
55577
|
try {
|
|
55527
55578
|
const sdk = client.getSDK();
|
|
55528
|
-
const newOrder = await sdk.replaceOrder(orderId, params);
|
|
55579
|
+
const newOrder = await client.executeWithRateLimit(() => sdk.replaceOrder(orderId, params), "replaceOrder");
|
|
55529
55580
|
log$6(`Order replaced successfully: ${orderId} -> ${newOrder.id}`, {
|
|
55530
55581
|
type: "info",
|
|
55531
55582
|
symbol: newOrder.symbol,
|
|
@@ -55630,7 +55681,7 @@ async function getOrderByClientId(client, clientOrderId) {
|
|
|
55630
55681
|
log$6(`Fetching order by client_order_id: ${clientOrderId}`, { type: "debug" });
|
|
55631
55682
|
try {
|
|
55632
55683
|
const sdk = client.getSDK();
|
|
55633
|
-
const order = await sdk.getOrderByClientId(clientOrderId);
|
|
55684
|
+
const order = await client.executeWithRateLimit(() => sdk.getOrderByClientId(clientOrderId), "getOrderByClientId");
|
|
55634
55685
|
log$6(`Order retrieved by client_order_id: ${clientOrderId} -> ${order.id}`, {
|
|
55635
55686
|
type: "debug",
|
|
55636
55687
|
symbol: order.symbol,
|
|
@@ -58571,7 +58622,7 @@ async function getPositions(client) {
|
|
|
58571
58622
|
log("Fetching all open positions", { type: "debug" });
|
|
58572
58623
|
try {
|
|
58573
58624
|
const sdk = client.getSDK();
|
|
58574
|
-
const positions = (await sdk.getPositions());
|
|
58625
|
+
const positions = (await client.executeWithRateLimit(() => sdk.getPositions(), "getPositions"));
|
|
58575
58626
|
log(`Retrieved ${positions.length} positions`, { type: "info" });
|
|
58576
58627
|
return positions;
|
|
58577
58628
|
}
|
|
@@ -58625,7 +58676,7 @@ async function getPosition(client, symbol) {
|
|
|
58625
58676
|
log(`Fetching position for symbol: ${symbol}`, { type: "debug", symbol });
|
|
58626
58677
|
try {
|
|
58627
58678
|
const sdk = client.getSDK();
|
|
58628
|
-
const position = (await sdk.getPosition(symbol));
|
|
58679
|
+
const position = (await client.executeWithRateLimit(() => sdk.getPosition(symbol), "getPosition"));
|
|
58629
58680
|
log(`Found position for ${symbol}: ${position.qty} shares`, {
|
|
58630
58681
|
type: "info",
|
|
58631
58682
|
symbol,
|
|
@@ -58772,10 +58823,10 @@ async function closePosition(client, symbol, options) {
|
|
|
58772
58823
|
let order;
|
|
58773
58824
|
if (Object.keys(queryParams).length > 0) {
|
|
58774
58825
|
// SDK doesn't support params, use sendRequest directly
|
|
58775
|
-
order = (await sdk.sendRequest(`/positions/${encodeURIComponent(normalizedSymbol)}`, queryParams, null, "DELETE"));
|
|
58826
|
+
order = (await client.executeWithRateLimit(() => sdk.sendRequest(`/positions/${encodeURIComponent(normalizedSymbol)}`, queryParams, null, "DELETE"), "closePosition"));
|
|
58776
58827
|
}
|
|
58777
58828
|
else {
|
|
58778
|
-
order = (await sdk.closePosition(normalizedSymbol));
|
|
58829
|
+
order = (await client.executeWithRateLimit(() => sdk.closePosition(normalizedSymbol), "closePosition"));
|
|
58779
58830
|
}
|
|
58780
58831
|
log(`Position close order created for ${normalizedSymbol}: ${order.id}`, {
|
|
58781
58832
|
type: "info",
|
|
@@ -58816,7 +58867,7 @@ async function closeAllPositions(client, options) {
|
|
|
58816
58867
|
cancel_orders: cancelOrders.toString(),
|
|
58817
58868
|
};
|
|
58818
58869
|
// Use sendRequest to pass the cancel_orders parameter
|
|
58819
|
-
const response = await sdk.sendRequest("/positions", queryParams, null, "DELETE");
|
|
58870
|
+
const response = await client.executeWithRateLimit(() => sdk.sendRequest("/positions", queryParams, null, "DELETE"), "closeAllPositions");
|
|
58820
58871
|
// The SDK returns an array of objects with order info
|
|
58821
58872
|
const orders = Array.isArray(response) ? response : [];
|
|
58822
58873
|
log(`Closed ${orders.length} positions`, { type: "info" });
|
|
@@ -58851,7 +58902,7 @@ async function closeAllPositionsAfterHours(client, options) {
|
|
|
58851
58902
|
return [];
|
|
58852
58903
|
}
|
|
58853
58904
|
// First cancel all open orders
|
|
58854
|
-
await sdk.cancelAllOrders();
|
|
58905
|
+
await client.executeWithRateLimit(() => sdk.cancelAllOrders(), "cancelAllOrders");
|
|
58855
58906
|
log("Cancelled all open orders", { type: "info" });
|
|
58856
58907
|
const orders = [];
|
|
58857
58908
|
const offsetMultiplier = limitPriceOffset / 100;
|
|
@@ -58872,7 +58923,7 @@ async function closeAllPositionsAfterHours(client, options) {
|
|
|
58872
58923
|
: roundPriceForAlpaca(currentPrice * (1 + offsetMultiplier));
|
|
58873
58924
|
log(`Creating limit order to close ${position.symbol}: ${side} ${qty} shares at $${limitPrice.toFixed(2)}`, { type: "info", symbol: position.symbol });
|
|
58874
58925
|
try {
|
|
58875
|
-
const order = (await sdk.createOrder({
|
|
58926
|
+
const order = (await client.executeWithRateLimit(() => sdk.createOrder({
|
|
58876
58927
|
symbol: position.symbol,
|
|
58877
58928
|
qty: qty,
|
|
58878
58929
|
side: side,
|
|
@@ -58880,7 +58931,7 @@ async function closeAllPositionsAfterHours(client, options) {
|
|
|
58880
58931
|
time_in_force: "day",
|
|
58881
58932
|
limit_price: limitPrice,
|
|
58882
58933
|
extended_hours: true,
|
|
58883
|
-
}));
|
|
58934
|
+
}), `createOrder ${position.symbol}`));
|
|
58884
58935
|
orders.push(order);
|
|
58885
58936
|
}
|
|
58886
58937
|
catch (orderError) {
|