@adaptic/utils 0.0.974 → 0.0.976

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.mjs CHANGED
@@ -6473,6 +6473,36 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
6473
6473
  account: auth.adapticAccountId || "direct",
6474
6474
  symbol: normalizedSymbol,
6475
6475
  });
6476
+ // Alpaca processes cancellations asynchronously — the cancel API returns
6477
+ // immediately but the order may still be "open" for 50-500ms+. Closing a
6478
+ // position while an opposing order is still active triggers a 403 "wash
6479
+ // trade detected" rejection. Poll until cancelled orders are confirmed gone.
6480
+ const maxVerifyAttempts = 5;
6481
+ const verifyDelayMs = 500;
6482
+ for (let attempt = 1; attempt <= maxVerifyAttempts; attempt++) {
6483
+ await new Promise((r) => setTimeout(r, verifyDelayMs));
6484
+ const remainingOrders = isCryptoSymbol$1(symbolOrAssetId)
6485
+ ? (await getOrders$1(auth, { status: "open" })).filter((o) => o.symbol.replace(/[-/]/g, "") === normalizedSymbol)
6486
+ : await getOrders$1(auth, {
6487
+ status: "open",
6488
+ symbols: [normalizedSymbol],
6489
+ });
6490
+ if (remainingOrders.length === 0) {
6491
+ getLogger().info(`Cancel verification passed for ${normalizedSymbol} (attempt ${attempt}/${maxVerifyAttempts})`, {
6492
+ account: auth.adapticAccountId || "direct",
6493
+ symbol: normalizedSymbol,
6494
+ });
6495
+ break;
6496
+ }
6497
+ if (attempt === maxVerifyAttempts) {
6498
+ getLogger().warn(`Cancel verification exhausted for ${normalizedSymbol}: ${remainingOrders.length} orders still open after ${maxVerifyAttempts * verifyDelayMs}ms`, {
6499
+ account: auth.adapticAccountId || "direct",
6500
+ symbol: normalizedSymbol,
6501
+ remainingOrderIds: remainingOrders.map((o) => o.id),
6502
+ type: "warn",
6503
+ });
6504
+ }
6505
+ }
6476
6506
  }
6477
6507
  }
6478
6508
  // Crypto positions cannot use limit orders with SIP quotes or time_in_force="day".