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