@adaptic/utils 0.0.974 → 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 +30 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +30 -0
- package/dist/index.mjs.map +1 -1
- package/dist/types/alpaca/legacy/positions.d.ts.map +1 -1
- package/package.json +1 -1
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".
|