@adaptic/utils 0.0.973 → 0.0.975

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6475,6 +6475,36 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
6475
6475
  account: auth.adapticAccountId || "direct",
6476
6476
  symbol: normalizedSymbol,
6477
6477
  });
6478
+ // Alpaca processes cancellations asynchronously — the cancel API returns
6479
+ // immediately but the order may still be "open" for 50-500ms+. Closing a
6480
+ // position while an opposing order is still active triggers a 403 "wash
6481
+ // trade detected" rejection. Poll until cancelled orders are confirmed gone.
6482
+ const maxVerifyAttempts = 5;
6483
+ const verifyDelayMs = 500;
6484
+ for (let attempt = 1; attempt <= maxVerifyAttempts; attempt++) {
6485
+ await new Promise((r) => setTimeout(r, verifyDelayMs));
6486
+ const remainingOrders = isCryptoSymbol$1(symbolOrAssetId)
6487
+ ? (await getOrders$1(auth, { status: "open" })).filter((o) => o.symbol.replace(/[-/]/g, "") === normalizedSymbol)
6488
+ : await getOrders$1(auth, {
6489
+ status: "open",
6490
+ symbols: [normalizedSymbol],
6491
+ });
6492
+ if (remainingOrders.length === 0) {
6493
+ getLogger().info(`Cancel verification passed for ${normalizedSymbol} (attempt ${attempt}/${maxVerifyAttempts})`, {
6494
+ account: auth.adapticAccountId || "direct",
6495
+ symbol: normalizedSymbol,
6496
+ });
6497
+ break;
6498
+ }
6499
+ if (attempt === maxVerifyAttempts) {
6500
+ getLogger().warn(`Cancel verification exhausted for ${normalizedSymbol}: ${remainingOrders.length} orders still open after ${maxVerifyAttempts * verifyDelayMs}ms`, {
6501
+ account: auth.adapticAccountId || "direct",
6502
+ symbol: normalizedSymbol,
6503
+ remainingOrderIds: remainingOrders.map((o) => o.id),
6504
+ type: "warn",
6505
+ });
6506
+ }
6507
+ }
6478
6508
  }
6479
6509
  }
6480
6510
  // Crypto positions cannot use limit orders with SIP quotes or time_in_force="day".