@adaptic/utils 0.0.915 → 0.0.916

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
@@ -5789,6 +5789,24 @@ async function closeAllPositions$1(auth, params = { cancel_orders: true, useLimi
5789
5789
  account: auth.adapticAccountId || "direct",
5790
5790
  });
5791
5791
  if (useLimitOrders) {
5792
+ // Cancel all existing orders first when requested, to free up qty_available
5793
+ // for the limit close orders. Without this, existing trailing stops and
5794
+ // pending orders reduce qty_available, causing "insufficient qty" errors.
5795
+ if (cancel_orders) {
5796
+ try {
5797
+ await cancelAllOrders$1(auth);
5798
+ getLogger().info("Canceled all open orders before placing limit close orders", {
5799
+ account: auth.adapticAccountId || "direct",
5800
+ });
5801
+ }
5802
+ catch (cancelError) {
5803
+ getLogger().warn(`Failed to cancel orders before limit closure: ${cancelError instanceof Error ? cancelError.message : String(cancelError)}`, {
5804
+ account: auth.adapticAccountId || "direct",
5805
+ type: "warn",
5806
+ });
5807
+ // Continue with closure attempt even if cancel failed
5808
+ }
5809
+ }
5792
5810
  const positions = await fetchAllPositions(auth);
5793
5811
  if (positions.length === 0) {
5794
5812
  getLogger().info("No positions to close", {
@@ -5799,13 +5817,10 @@ async function closeAllPositions$1(auth, params = { cancel_orders: true, useLimi
5799
5817
  getLogger().info(`Found ${positions.length} positions to close`, {
5800
5818
  account: auth.adapticAccountId || "direct",
5801
5819
  });
5802
- const alpacaAuth = {
5803
- type: "LIVE",
5804
- alpacaApiKey: process.env.ALPACA_API_KEY,
5805
- alpacaApiSecret: process.env.ALPACA_API_SECRET || process.env.ALPACA_SECRET_KEY,
5806
- };
5820
+ // Use the passed auth for quote fetching (not hardcoded env vars)
5821
+ // so multi-account setups use the correct credentials per account
5807
5822
  const symbols = positions.map((position) => position.symbol);
5808
- const quotesResponse = await getLatestQuotes$1(alpacaAuth, { symbols });
5823
+ const quotesResponse = await getLatestQuotes$1(auth, { symbols });
5809
5824
  const lengthOfQuotes = Object.keys(quotesResponse.quotes).length;
5810
5825
  if (lengthOfQuotes === 0) {
5811
5826
  getLogger().error("No quotes available for positions, received 0 quotes", {
@@ -5815,11 +5830,12 @@ async function closeAllPositions$1(auth, params = { cancel_orders: true, useLimi
5815
5830
  return [];
5816
5831
  }
5817
5832
  if (lengthOfQuotes !== positions.length) {
5818
- getLogger().warn(`Received ${lengthOfQuotes} quotes for ${positions.length} positions, expected ${positions.length} quotes`, {
5833
+ getLogger().warn(`Received ${lengthOfQuotes} quotes for ${positions.length} positions (expected ${positions.length}), proceeding with available quotes`, {
5819
5834
  account: auth.adapticAccountId || "direct",
5820
5835
  type: "warn",
5821
5836
  });
5822
- return [];
5837
+ // Continue with available quotes instead of aborting — some symbols may
5838
+ // lack quotes (halted, delisted) but other positions should still close
5823
5839
  }
5824
5840
  for (const position of positions) {
5825
5841
  const quote = quotesResponse.quotes[position.symbol];