@adaptic/utils 0.0.996 → 0.0.998
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 +27 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +27 -5
- 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
|
@@ -6998,11 +6998,33 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
|
|
|
6998
6998
|
status: "open",
|
|
6999
6999
|
symbols: [normalizedSymbol],
|
|
7000
7000
|
});
|
|
7001
|
-
//
|
|
7002
|
-
//
|
|
7003
|
-
//
|
|
7004
|
-
//
|
|
7005
|
-
|
|
7001
|
+
// pending_cancel / pending_replace handling needs an age split
|
|
7002
|
+
// (2026-06-10 live evidence, both directions):
|
|
7003
|
+
// - FRESH pending (entered the state < 30s ago): the broker is
|
|
7004
|
+
// mid-terminalisation and STILL HOLDS the order's quantity.
|
|
7005
|
+
// Treating it as done made the close fire early and bounce
|
|
7006
|
+
// with 403 40310000 "insufficient qty available" (META/WFC
|
|
7007
|
+
// closes at 17:07Z), so it must stay in `remainingOrders`
|
|
7008
|
+
// and keep the verification loop waiting.
|
|
7009
|
+
// - STALE pending (>= 30s): a wedged zombie (observed 8 days
|
|
7010
|
+
// on one order) that will never terminalise — waiting spins
|
|
7011
|
+
// the loop to exhaustion on every close attempt, so it is
|
|
7012
|
+
// excluded and the close proceeds; the broker arbitrates the
|
|
7013
|
+
// held quantity.
|
|
7014
|
+
const WEDGED_PENDING_AGE_MS = 30_000;
|
|
7015
|
+
const remainingOrders = allRemainingOrders.filter((o) => {
|
|
7016
|
+
if (o.status !== "pending_cancel" &&
|
|
7017
|
+
o.status !== "pending_replace") {
|
|
7018
|
+
return true;
|
|
7019
|
+
}
|
|
7020
|
+
const updatedAtMs = Date.parse(o.updated_at ?? "");
|
|
7021
|
+
if (!Number.isFinite(updatedAtMs)) {
|
|
7022
|
+
// No usable timestamp — conservatively treat as fresh so the
|
|
7023
|
+
// loop waits rather than racing the broker's qty release.
|
|
7024
|
+
return true;
|
|
7025
|
+
}
|
|
7026
|
+
return Date.now() - updatedAtMs < WEDGED_PENDING_AGE_MS;
|
|
7027
|
+
});
|
|
7006
7028
|
if (remainingOrders.length === 0) {
|
|
7007
7029
|
getLogger().info(`Cancel verification passed for ${normalizedSymbol} (attempt ${attempt}/${maxVerifyAttempts})`, {
|
|
7008
7030
|
account: auth.adapticAccountId || "direct",
|