@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 +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.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".
|