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