{"version":3,"sources":["../src/version.ts","../src/positions/index.ts","../src/positions/notional.ts","../src/positions/unrealizedPnL.ts","../src/constants.ts","../src/utils.ts","../src/positions/liqPrice.ts","../src/positions/maintenanceMargin.ts","../src/positions/unsettlementPnL.ts","../src/positions/positionMMR.ts","../src/positions/takeProfit.ts","../src/positions/maxPosition.ts","../src/positions/liquidationPriceIsolated.ts","../src/account/index.ts","../src/account/totalValue.ts","../src/account/freeCollateral.ts","../src/account/freeCollateralUSDCOnly.ts","../src/account/totalCollateral.ts","../src/account/positionNotional.ts","../src/account/imr.ts","../src/account/ordersFilter.ts","../src/account/positionUtils.ts","../src/account/initialMargin.ts","../src/account/groupOrders.ts","../src/account/otherIMs.ts","../src/account/maxQty.ts","../src/account/maxQtyIsolated.ts","../src/account/marginRatio.ts","../src/account/unrealizedROI.ts","../src/account/leverage.ts","../src/account/availableBalance.ts","../src/account/mmr.ts","../src/account/collateral.ts","../src/account/ltv.ts","../src/account/maxWithdrawal.ts","../src/account/maxAddReduce.ts","../src/order.ts"],"names":["Decimal","IMR","MMR","totalCollateral","liqPrice","notional","extractSymbols","totalUnsettlementPnL","zero","freeCollateral","value","unsettlementPnL","OrderSide","otherIMs","availableBalance","totalUnrealizedPnL","totalValue","totalMarginRatio","collateralRatio","orderFee"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n  interface Window {\n      __ORDERLY_VERSION__?: {\n          [key: string]: string;\n      };\n  }\n}\nif (typeof window !== \"undefined\") {\n  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};\n  window.__ORDERLY_VERSION__[\"@orderly.network/perp\"] = \"5.1.2\";\n}\n\nexport default \"5.1.2\";\n","// Re-export all position functions for backward compatibility\n// These were split from the original positions.ts file\n\nexport * from \"./notional\";\nexport * from \"./unrealizedPnL\";\nexport * from \"./liqPrice\";\nexport * from \"./maintenanceMargin\";\nexport * from \"./unsettlementPnL\";\nexport * from \"./positionMMR\";\nexport * from \"./takeProfit\";\nexport * from \"./maxPosition\";\nexport * from \"./liquidationPriceIsolated\";\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Calculates the notional value of a single position.\n * @param qty The quantity of the position.\n * @param mark_price The price of the position.\n * @returns The notional value of the position.\n */\nexport function notional(qty: number, mark_price: number): number {\n  return new Decimal(qty).mul(mark_price).abs().toNumber();\n}\n\n/**\n * @formulaId totalNotional\n * @name Total Notional\n * @formula Total Notional = sum ( abs(position_qty_i * mark_price_i) )\n * @description\n * ## Term Definitions\n *\n * - **Total Notional**: Sum of current position notional values\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## Example\n *\n * **Total Notional** = 10112.43\n *\n * **abs(BTC position notional)** = 5197.2\n *\n * **abs(ETH position notional)** = 4915.23\n *\n * @param positions The array of positions.\n * @returns The total notional value of all positions.\n */\nexport function totalNotional(positions: API.Position[]): number {\n  return positions.reduce((acc, cur) => {\n    return acc + notional(cur.position_qty, cur.mark_price);\n  }, 0);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/** @deprecated Use inline type or the new input type instead */\nexport type UnrealPnLInputs = {\n  markPrice: number;\n  openPrice: number;\n  qty: number;\n};\n\n/**\n * @formulaId unrealizedPnL\n * @description Calculates the unrealized profit or loss of a single position.\n * This formula applies to both cross margin and isolated margin positions.\n * @formula Unrealized PnL = position_qty * (mark_price - entry_price)\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position (in USDC).\n */\nexport function unrealizedPnL(inputs: {\n  /** symbol mark price */\n  markPrice: number;\n  /** symbol open price (entry price) */\n  openPrice: number;\n  /** symbol quantity (position quantity, positive for long, negative for short) */\n  qty: number;\n}): number {\n  return new Decimal(inputs.qty)\n    .mul(inputs.markPrice - inputs.openPrice)\n    .toNumber();\n}\n\n/**\n * @formulaId unrealizedPnLROI\n * @name Position unrealized ROI\n * @formula Position unrealized ROI = Position unrealized PNL / ( IMR_i *  abs(position_qty_i * entry_price_i) ) * 100%, IMR_i = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i)^(4/5))\n * @description\n * ## Term Definitions\n *\n * - **Position unrealized ROI**: Single symbol unrealized return on investment\n * - **Position unrealized PNL**: Single symbol unrealized profit and loss\n * - **IMR_i**: Single symbol initial margin rate\n * - **Symbol Leverage_i**: Current leverage for symbol i under current margin mode\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * **Position unrealized ROI** = Position unrealized PNL / (IMR_i * abs(position_qty_i * entry_price_i)) * 100% = 216.69 / (0.1 * abs(-3 * 1710.64)) * 100% = 42.22%\n *\n * **ETH IMR_i** = Max(1/10, 0.1, 0.0000003754 * abs(-4915.23)^(4/5)) = Max(0.1, 0.1, 0.000337077174) = 0.1\n *\n * - Symbol Leverage_i = 10\n * - ETH Base IMR_i = 0.1\n * - ETH IMR Factor_i = 0.0000003754\n * - ETH position_qty_i = -3\n * - ETH entry_price_i = 1710.64\n * - ETH mark_price_i = 1638.41\n * - ETH Position Notional = -3 * 1638.41 = -4915.23\n * - ETH Position unrealized PNL = 216.69\n *\n * @param inputs The inputs for calculating the ROI.\n * @returns The ROI of the position's unrealized profit or loss.\n */\nexport function unrealizedPnLROI(inputs: {\n  positionQty: number;\n  openPrice: number;\n  IMR: number;\n  unrealizedPnL: number;\n}): number {\n  const { openPrice, IMR } = inputs;\n\n  if (\n    inputs.unrealizedPnL === 0 ||\n    inputs.positionQty === 0 ||\n    openPrice === 0 ||\n    IMR === 0\n  )\n    return 0;\n\n  return new Decimal(inputs.unrealizedPnL)\n    .div(new Decimal(Math.abs(inputs.positionQty)).mul(openPrice).mul(IMR))\n    .toNumber();\n}\n\n/**\n * @formulaId totalUnrealizedPnl\n * @name Total Unrealized PNL\n * @formula Total Unrealized PNL = sum ( unrealized_pnl_i ), unrealized_pnl_i = position_qty_i * ( mark_price_i - entry_price _i )\n * @description\n * ## Term Definitions\n *\n * - **Total Unrealized PNL**: Sum of all current unrealized profit and loss for user's positions\n * - **unrealized_pnl_i**: Current unrealized profit and loss for a single symbol\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * ```\n * BTC-PERP unrealized_pnl_i = 0.2 * (25986.2 - 26067) = -16.16\n * ETH-PERP unrealized_pnl_i = -3 * (1638.41 - 1710.64) = 216.69\n *\n * Total Unrealized PNL = -16.16 + 216.69 = 200.53\n * ```\n * @param positions The array of positions.\n * @returns The total unrealized profit or loss of all positions.\n */\nexport function totalUnrealizedPnL(positions: API.Position[]): number {\n  return positions.reduce((acc, cur) => {\n    return (\n      acc +\n      unrealizedPnL({\n        qty: cur.position_qty,\n        openPrice: cur.average_open_price,\n        markPrice: cur.mark_price,\n      })\n    );\n  }, 0);\n}\n","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n\n/**\n * Isolated margin frozen amount reserves the highest taker fee tier.\n * This mirrors the backend IsoOrderFrozenBuffer Apollo config.\n */\nexport const IsoTakerFeeBuffer = 0.0006;\n\n/**\n * Safety factor used by max quantity formulas to absorb price races and rounding.\n */\nexport const MaxQtySafetyFactor = 0.995;\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Returns the maximum value among the given Decimal or number values.\n * Similar to Math.max but works with Decimal instances.\n * @param values - Variable number of Decimal instances or numbers to compare\n * @returns The maximum value as a Decimal instance\n */\nexport const DMax = (...values: (Decimal | number)[]): Decimal => {\n  if (values.length === 0) {\n    throw new Error(\"DMax requires at least one argument\");\n  }\n\n  // Convert all values to Decimal instances\n  const decimals = values.map((val) =>\n    val instanceof Decimal ? val : new Decimal(val),\n  );\n\n  // Find the maximum by comparing each value\n  let max = decimals[0];\n  for (let i = 1; i < decimals.length; i++) {\n    if (decimals[i].gte(max)) {\n      max = decimals[i];\n    }\n  }\n\n  return max;\n};\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\nimport { DMax } from \"../utils\";\n\nconst MaxIterates = 30;\nconst CONVERGENCE_THRESHOLD = 0.0001;\n\nconst mmForOtherSymbols = (\n  positions: Pick<API.Position, \"position_qty\" | \"mark_price\" | \"mmr\">[],\n) => {\n  // sum_i ( abs(position_qty_i) * mark_price_i * mmr_i )\n  return positions.reduce<Decimal>((acc, cur) => {\n    return acc.add(\n      new Decimal(cur.position_qty).abs().mul(cur.mark_price).mul(cur.mmr),\n    );\n  }, zero);\n};\n\nconst calculateLiqPrice = (\n  // symbol: string,\n  markPrice: number,\n  positionQty: number,\n  MMR: number,\n  totalCollateral: number,\n  positions: Pick<API.Position, \"position_qty\" | \"mark_price\" | \"mmr\">[],\n): Decimal => {\n  const decimalMarkPrice = new Decimal(markPrice);\n  const absQty = new Decimal(positionQty).abs();\n  const denominator = absQty.mul(MMR).sub(positionQty);\n\n  const liqPrice = new Decimal(totalCollateral)\n    .sub(absQty.mul(decimalMarkPrice).mul(MMR))\n    .sub(mmForOtherSymbols(positions))\n    .div(denominator)\n    .add(decimalMarkPrice);\n\n  return DMax(liqPrice, zero);\n};\n\nconst compareCollateralWithMM = (\n  // price: number,\n  inputs: {\n    totalCollateral: number;\n    positionQty: number;\n    markPrice: number;\n    baseMMR: number;\n    baseIMR: number;\n    IMRFactor: number;\n    // IMRFactorPower: number;\n    positions: Pick<\n      API.PositionExt,\n      \"position_qty\" | \"mark_price\" | \"mmr\" | \"symbol\"\n    >[];\n  },\n) => {\n  return (price: Decimal) => {\n    const {\n      totalCollateral,\n      positionQty,\n      markPrice,\n      baseMMR,\n      baseIMR,\n      IMRFactor,\n      positions,\n    } = inputs;\n    const decimalPositionQty = new Decimal(positionQty);\n    const collateral = new Decimal(totalCollateral)\n      .sub(decimalPositionQty.mul(markPrice))\n      .add(decimalPositionQty.mul(price));\n\n    const mm = decimalPositionQty\n      .abs()\n      .mul(price)\n      .mul(\n        Math.max(\n          baseMMR,\n          new Decimal(baseMMR)\n            .div(baseIMR)\n            .mul(IMRFactor)\n            .mul(decimalPositionQty.mul(price).abs().toPower(IMRFactorPower))\n            .toNumber(),\n        ),\n      )\n      .add(mmForOtherSymbols(positions));\n\n    // console.log(\"*****\", {\n    //   collateral: collateral.toNumber(),\n    //   mm: mm.toNumber(),\n    // });\n\n    return collateral.gte(mm);\n  };\n};\n\n/**\n * @formulaId liqPrice\n * @name Position Liquidation Price\n * @description\n *\n * ## Define:\n *\n * ### (1) calculate_liq_price function\n *\n * ```\n * calculate_liq_price( mark_price, position_qty, mmr )\n * ```\n *\n * If `position_qty >= 0` AND if `abs(position_qty) * mmr - position_qty >= 0`:\n *\n * Return `mark_price`\n *\n * Else:\n *\n * Return `max( mark_price + [ total_collateral_value - abs(position_qty) * mark_price * mmr - mm_for_other_symbols ] / [ abs(position_qty) * mmr - position_qty ], 0 )`\n *\n * Where `total_collateral_value` and `mm_for_other_symbols` are constants.\n *\n * - **total_collateral_value**\n * - **mm_for_other_symbols** = `sum_i ( abs(position_qty_i) * mark_price_i * mmr_i )` for i != current symbol\n *\n * ### (2) compare_collateral_w_mm function\n *\n * ```\n * compare_collateral_w_mm( price ) = collateral >= mm\n * ```\n *\n * Where:\n * - **collateral** = `total_collateral_value - position_qty_i * mark_price + position_qty_i * price`\n * - **mm** = `abs(position_qty_i) * price * Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(position_qty_i * price)^(4/5)) + mm_for_other_symbols`\n *\n * ## Given:\n *\n * Position liquidation price for symbol i with:\n * - current mark price = `mark_price_i`\n * - current position qty = `position_qty_i`\n * - current mmr = `mmr_i = Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(Position Notional i)^(4/5))`\n * - symbol base mmr = `base_mmr_i`\n *\n * ## For LONG position\n *\n * ```\n * liq_price_left = calculate_liq_price( mark_price_i, position_qty_i, base_mmr_i )\n * liq_price_right = calculate_liq_price( mark_price_i, position_qty_i, mmr_i )\n *\n * ITERATE 30 times:\n *     if liq_price_left >= liq_price_right:\n *         return liq_price_right\n *\n *     mid = ( liq_price_left + liq_price_right ) / 2\n *\n *     if compare_collateral_w_mm( mid ):\n *         liq_price_right = mid\n *     else:\n *         liq_price_left = mid\n *\n *     if (liq_price_right - liq_price_left) / (liq_price_left + liq_price_right) * 2 <= 0.0001:\n *         break\n *\n * return liq_price_right\n * ```\n *\n * ## For SHORT position\n *\n * ```\n * liq_price_right = calculate_liq_price( mark_price_i, position_qty_i, mmr_i )\n * liq_price_left = calculate_liq_price( mark_price_i, position_qty_i,\n *   Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(position_qty_i * liq_price_right)^(4/5))\n * )\n *\n * ITERATE 30 times:\n *     if liq_price_left >= liq_price_right:\n *         return liq_price_left\n *\n *     mid = ( liq_price_left + liq_price_right ) / 2\n *\n *     if compare_collateral_w_mm( mid ):\n *         liq_price_left = mid\n *     else:\n *         liq_price_right = mid\n *\n *     if (liq_price_right - liq_price_left) / (liq_price_left + liq_price_right) * 2 <= 0.0001:\n *         break\n *\n * return liq_price_left\n * ```\n *\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: {\n  markPrice: number;\n  symbol: string;\n  totalCollateral: number;\n  positionQty: number;\n  positions: Pick<\n    API.PositionExt,\n    \"position_qty\" | \"mark_price\" | \"mmr\" | \"symbol\"\n  >[];\n  MMR: number;\n  baseMMR: number;\n  baseIMR: number;\n  IMRFactor: number;\n  costPosition: number;\n}): number | null {\n  const {\n    positionQty,\n    markPrice,\n    totalCollateral,\n    positions,\n    MMR,\n    baseMMR,\n    baseIMR,\n    IMRFactor,\n    symbol,\n  } = inputs;\n\n  if (positionQty === 0 || totalCollateral === 0) {\n    return null;\n  }\n  const isLONG = positionQty > 0;\n\n  const otherPositions = positions.filter((item) => item.symbol !== symbol);\n\n  if (isLONG) {\n    let liqPriceLeft = calculateLiqPrice(\n      markPrice,\n      positionQty,\n      baseMMR,\n      totalCollateral,\n      otherPositions,\n    );\n    let liqPriceRight = calculateLiqPrice(\n      markPrice,\n      positionQty,\n      MMR,\n      totalCollateral,\n      otherPositions,\n    );\n\n    const compareCollateralWithMMFunc = compareCollateralWithMM({\n      totalCollateral,\n      positionQty,\n      markPrice,\n      baseIMR,\n      baseMMR,\n      IMRFactor,\n      positions: otherPositions,\n    });\n\n    for (let i = 0; i < MaxIterates; i++) {\n      if (liqPriceLeft.gte(liqPriceRight)) {\n        return liqPriceRight.toNumber();\n      }\n\n      const mid = new Decimal(liqPriceLeft).add(liqPriceRight).div(2);\n\n      if (compareCollateralWithMMFunc(mid)) {\n        liqPriceRight = mid;\n      } else {\n        liqPriceLeft = mid;\n      }\n\n      if (\n        liqPriceRight\n          .sub(liqPriceLeft)\n          .div(liqPriceLeft.add(liqPriceRight))\n          .mul(2)\n          .lte(CONVERGENCE_THRESHOLD)\n      ) {\n        break;\n      }\n    }\n    return liqPriceRight.toNumber();\n  } else {\n    // const decimalBaseMMR = new Decimal(baseMMR);\n    let liqPriceRight = calculateLiqPrice(\n      markPrice,\n      positionQty,\n      MMR,\n      totalCollateral,\n      otherPositions,\n    );\n\n    let liqPriceLeft = calculateLiqPrice(\n      markPrice,\n      positionQty,\n      Math.max(\n        baseIMR,\n        new Decimal(baseMMR)\n          .div(baseIMR)\n          .mul(IMRFactor)\n          .mul(\n            new Decimal(positionQty)\n              .mul(liqPriceRight)\n              .abs()\n              .toPower(IMRFactorPower),\n          )\n          .toNumber(),\n      ),\n      totalCollateral,\n      otherPositions,\n    );\n\n    const compareCollateralWithMMFunc = compareCollateralWithMM({\n      totalCollateral,\n      positionQty,\n      markPrice,\n      baseMMR,\n      baseIMR,\n      IMRFactor,\n      positions: otherPositions,\n    });\n\n    for (let i = 0; i < MaxIterates; i++) {\n      if (liqPriceLeft.gte(liqPriceRight)) {\n        return liqPriceLeft.toNumber();\n      }\n\n      const mid = liqPriceLeft.add(liqPriceRight).div(2);\n\n      if (compareCollateralWithMMFunc(mid)) {\n        liqPriceLeft = mid;\n      } else {\n        liqPriceRight = mid;\n      }\n\n      if (\n        liqPriceRight\n          .sub(liqPriceLeft)\n          .div(liqPriceLeft.add(liqPriceRight))\n          .mul(2)\n          .lte(CONVERGENCE_THRESHOLD)\n      ) {\n        break;\n      }\n\n      // return liqPriceLeft.toNumber();\n    }\n\n    return liqPriceLeft.toNumber();\n  }\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maintenanceMargin\n * @name Position maintenance margin\n * @formula Position maintenance margin = abs (position_qty_i  * mark_price_i * MMR_i )\n * @description\n * ## Term Definitions\n *\n * - **Position maintenance margin**: Single symbol maintenance margin\n * - **MMR_i**: Single symbol maintenance margin rate\n * - **Base MMR_i**: Single symbol base maintenance margin rate\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## MMR Formula\n *\n * MMR_i = Max(Base MMR_i, (Base MMR_i / Base IMR_i) * IMR Factor_i * Abs(Position Notional_i)^(4/5))\n *\n * ## Example\n *\n * **BTC Position maintenance margin** = abs(position_qty_i * mark_price_i * MMR_i) = abs(0.2 * 25986.2 * 0.05) = 259.86\n *\n * **BTC MMR_i** = Max(0.05, (0.05 / 0.1) * 0.0000002512 * 5197.2^(4/5)) = Max(0.05, 0.000117924809) = 0.05\n *\n * - BTC Base MMR_i = 0.05\n * - BTC Base IMR_i = 0.1\n * - BTC IMR Factor_i = 0.0000002512\n * - Abs(BTC Position Notional_i) = 5197.2\n * - position_qty_i = 0.2\n * - mark_price_i = 25986.2\n *\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: {\n  positionQty: number;\n  markPrice: number;\n  MMR: number;\n}) {\n  const { positionQty, markPrice, MMR } = inputs;\n\n  return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/** @deprecated Use inline type or the new input type instead */\nexport type LiqPriceInputs = {\n  markPrice: number;\n  totalCollateral: number;\n  positionQty: number;\n  positions: Pick<API.PositionExt, \"position_qty\" | \"mark_price\" | \"mmr\">[];\n  MMR: number;\n};\n\n/**\n * @formulaId unsettlementPnl\n * @name Position Unrealized PNL\n * @formula Position Unrealized PNL = position_qty_i * (mark_price_i - entry_price_i)\n * @description\n * ## Term Definitions\n *\n * - **Position Unrealized PNL**: Single symbol unrealized profit and loss\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * **ETH Position Unrealized PNL** = position_qty_i * (mark_price_i - entry_price_i) = -3 * (1638.41 - 1710.64) = 216.69\n *\n * - ETH position_qty_i = -3\n * - ETH mark_price_i = 1638.41\n * - ETH entry_price_i = 1710.64\n *\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of each position.\n */\nexport function unsettlementPnL(inputs: {\n  positionQty: number;\n  markPrice: number;\n  costPosition: number;\n  sumUnitaryFunding: number;\n  lastSumUnitaryFunding: number;\n}): number {\n  const {\n    positionQty,\n    markPrice,\n    costPosition,\n    sumUnitaryFunding,\n    lastSumUnitaryFunding,\n  } = inputs;\n\n  const qty = new Decimal(positionQty);\n\n  return qty\n    .mul(markPrice)\n    .sub(costPosition)\n    .sub(qty.mul(new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding)))\n    .toNumber();\n}\n\n/**\n * @formulaId totalUnsettlementPnL\n * @name Total Unsettlement PNL\n * @formula Unsettlement PNL = position_qty_i * mark_price_i - cost_position_i - position_qty_i * (sum_unitary_funding_i - last_sum_unitary_funding_i)\n * @description\n * ## Term Definitions\n *\n * - **total unsettlement PNL**: Sum of user account's unsettled PNL\n * - **mark_price_i**: Single symbol mark price\n * - **position_qty_i**: Single symbol position quantity\n * - **cost_position_i**: Single symbol notional snapshot from last settlement, `/v1/position`\n * - **sum_unitary_funding_i**: Single symbol current cumulative unit funding fee, `/v1/public/funding_rate`\n * - **last_sum_unitary_funding_i**: Single symbol cumulative unit funding fee from last settlement, `/v1/position`\n *\n * ## Example\n *\n * **BTC-PERP Unsettlement PNL** = 0.2 * 25986.2 - 5197.2 - 0.2 * (-1585.92 + 1583.92) = 0.44\n *\n * **ETH-PERP Unsettlement PNL** = -3 * 1638.41 + 4902.45 + 3 * (-52.728 + 50.728) = -18.78\n *\n * **Total Unsettlement PNL** = 0.44 - 18.78 = -18.34\n *\n * @param positions The array of positions.\n * @returns The total unrealized profit or loss of all positions.\n */\nexport function totalUnsettlementPnL(\n  positions: (API.Position & { sum_unitary_funding: number })[],\n): number {\n  if (!Array.isArray(positions) || positions.length === 0) {\n    return 0;\n  }\n\n  return positions.reduce((acc, cur) => {\n    return (\n      acc +\n      unsettlementPnL({\n        positionQty: cur.position_qty,\n        markPrice: cur.mark_price,\n        costPosition: cur.cost_position,\n        sumUnitaryFunding: cur.sum_unitary_funding,\n        lastSumUnitaryFunding: cur.last_sum_unitary_funding,\n      })\n    );\n  }, 0);\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId MMR\n * @name Position Maintenance Margin Rate\n * @formula MMR_i = Max(Base MMR_i, (Base MMR_i / Base IMR_i) * IMR Factor_i * Abs(Position Notional_i)^(4/5))\n * @description\n * ## Term Definitions\n *\n * - **MMR_i**: Single symbol maintenance margin rate\n * - **Base MMR_i**: Single symbol base maintenance margin rate\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## Example\n *\n * **BTC MMR_i** = Max(0.05, (0.05 / 0.1) * 0.0000002512 * 5197.2^(4/5)) = Max(0.05, 0.000117924809) = 0.05\n *\n * - BTC Base MMR_i = 0.05\n * - BTC Base IMR_i = 0.1\n * - BTC IMR Factor_i = 0.0000002512\n * - Abs(BTC Position Notional_i) = 5197.2\n * - position_qty_i = 0.2\n * - mark_price_i = 25986.2\n *\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: {\n  baseMMR: number;\n  baseIMR: number;\n  IMRFactor: number;\n  positionNotional: number;\n  IMR_factor_power: number;\n}): number {\n  const {\n    baseMMR,\n    baseIMR,\n    IMRFactor,\n    positionNotional,\n    IMR_factor_power = IMRFactorPower,\n  } = inputs;\n  return Math.max(\n    baseMMR,\n    new Decimal(baseMMR)\n      .div(baseIMR)\n      .mul(IMRFactor)\n      .mul(Math.pow(Math.abs(positionNotional), IMR_factor_power))\n      // .toPower(IMR_factor_power)\n      .toNumber(),\n  );\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Calculates the profit or loss for take profit.\n * @returns The profit or loss for take profit.\n */\nexport function estPnLForTP(inputs: {\n  positionQty: number;\n  entryPrice: number;\n  price: number;\n}): number {\n  return new Decimal(inputs.positionQty)\n    .mul(new Decimal(inputs.price).sub(inputs.entryPrice))\n    .toNumber();\n}\n\n/**\n * Calculates the estimated price for take profit.\n * This is the inverse of estPnLForTP: given PnL, calculates the price.\n * Formula: price = PnL / positionQty + entryPrice\n */\nexport function estPriceForTP(inputs: {\n  positionQty: number;\n  entryPrice: number;\n  pnl: number;\n}): number {\n  return new Decimal(inputs.pnl)\n    .div(inputs.positionQty)\n    .add(inputs.entryPrice)\n    .toNumber();\n}\n\n/**\n * Calculates the estimated offset for take profit.\n */\nexport function estOffsetForTP(inputs: {\n  price: number;\n  entryPrice: number;\n}): number {\n  return new Decimal(inputs.price).div(inputs.entryPrice).toNumber();\n}\n\n/**\n * Calculates the estimated price from offset for take profit.\n */\nexport function estPriceFromOffsetForTP(inputs: {\n  offset: number;\n  entryPrice: number;\n}): number {\n  return new Decimal(inputs.offset).add(inputs.entryPrice).toNumber();\n}\n\n/**\n * Calculates the PnL for stop loss.\n */\nexport function estPnLForSL(inputs: {\n  positionQty: number;\n  entryPrice: number;\n}): number {\n  return 0;\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maxPositionNotional\n * @description calculate the max position notional\n * @formula max_notional = ( (1/ (leverage * imr_factor) ) ^ (1/0.8)\n */\nexport function maxPositionNotional(inputs: {\n  /** symbol leverage */\n  leverage: number;\n  IMRFactor: number;\n}) {\n  const { leverage, IMRFactor } = inputs;\n  return new Decimal(1)\n    .div(new Decimal(leverage).mul(IMRFactor))\n    .pow(1 / 0.8)\n    .toNumber();\n}\n\n/**\n * symbol_leverage_max = 1 / ( imr_factor * notional ^ 0.8 )\n */\nexport function maxPositionLeverage(inputs: {\n  IMRFactor: number;\n  notional: number;\n}) {\n  const { IMRFactor, notional } = inputs;\n  return new Decimal(1)\n    .div(new Decimal(IMRFactor).mul(new Decimal(notional).pow(0.8)))\n    .toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower, IsoTakerFeeBuffer } from \"../constants\";\n\n/**\n * @formulaId liquidationPriceIsolated\n * @name Liquidation Price for Isolated Margin Position\n * @formula liquidation_price = (isolated_position_margin' - cost_position' - funding_adjustment) / (abs(position_qty') * MMR' - position_qty')\n * funding_adjustment = position_qty' * (sum_unitary_funding - last_sum_unitary_funding)\n * position_qty' = position_qty + order_side * order_qty\n * MMR' = max(base_MMR, (base_MMR / base_IMR) * IMR_factor * abs(position_qty' * reference_price)^(4/5))\n * @description\n *\n * ## Definition\n *\n * **liquidation_price**: Price at which the isolated margin position will be liquidated\n *\n * **isolated_position_margin'**: Isolated position margin after order execution (if applicable)\n *\n * **cost_position'**: Position cost after order execution (if applicable)\n *\n * **funding_adjustment**: Adjustment for funding fees\n *\n * **position_qty'**: Position quantity after order execution\n *\n * **MMR'**: Maintenance margin rate after order execution\n *\n * ## Scenarios\n *\n * ### 1. No Order (order_qty = 0)\n * - `isolated_position_margin' = isolated_position_margin`\n * - `cost_position' = cost_position`\n *\n * ### 2. Open/Add Position (position_qty = 0 or order_side = sign(position_qty))\n * - `isolated_position_margin' = isolated_position_margin + order_qty * reference_price * (1 / leverage + iso_taker_fee_buffer)`\n * - `cost_position' = cost_position + order_side * order_qty * reference_price`\n *\n * ### 3. Close/Reduce Position (order_side ≠ sign(position_qty) and sign(position_qty') = sign(position_qty))\n * - `isolated_position_margin' = isolated_position_margin * position_qty' / position_qty`\n * - `cost_position' = cost_position + order_side * order_qty * reference_price`\n *\n * ### 4. Flip Position (order_side ≠ sign(position_qty) and sign(position_qty') ≠ sign(position_qty))\n * - `isolated_position_margin' = abs(position_qty') * reference_price * (1 / leverage + iso_taker_fee_buffer)`\n * - `cost_position' = position_qty' * reference_price`\n *\n * ## Example\n *\n * ```\n * isolated_position_margin = 2000\n * cost_position = 100000\n * position_qty = 2 (long)\n * sum_unitary_funding = 0.001\n * last_sum_unitary_funding = 0.0008\n * base_MMR = 0.025\n * base_IMR = 0.04\n * IMR_factor = 0.0000001\n * reference_price = 50000\n * liquidation_price = (2000 - 100000 - 0.0004) / (2 * 0.025 - 2) ≈ 50256.41\n * ```\n *\n * @param inputs Input parameters for calculating liquidation price\n * @returns Liquidation price (in USDC) or null if invalid\n */\nexport function liquidationPriceIsolated(inputs: {\n  /**\n   * @description Current isolated position margin\n   */\n  isolatedPositionMargin: number;\n  /**\n   * @description Current position cost\n   */\n  costPosition: number;\n  /**\n   * @description Current position quantity (positive for long, negative for short)\n   */\n  positionQty: number;\n  /**\n   * @description Current cumulative unitary funding\n   */\n  sumUnitaryFunding: number;\n  /**\n   * @description Last cumulative unitary funding (at last settlement)\n   */\n  lastSumUnitaryFunding: number;\n  /**\n   * @description Base maintenance margin rate\n   */\n  baseMMR: number;\n  /**\n   * @description Base initial margin rate\n   */\n  baseIMR: number;\n  /**\n   * @description IMR calculation factor\n   */\n  IMRFactor: number;\n  /**\n   * @description Reference price (mark price for current position, or order price for estimated liquidation)\n   */\n  referencePrice?: number;\n  /**\n   * @description Order side (BUY = +1, SELL = -1) for calculating estimated liquidation after order execution\n   */\n  orderSide?: \"BUY\" | \"SELL\";\n  /**\n   * @description Order quantity for calculating estimated liquidation after order execution\n   */\n  orderQty?: number;\n  /**\n   * @description Leverage for the position\n   */\n  leverage: number;\n  /**\n   * @description Fee buffer reserved in isolated margin estimates (default: 0.0006)\n   */\n  isoTakerFeeBuffer?: number;\n}): number | null {\n  const {\n    isolatedPositionMargin,\n    costPosition,\n    positionQty,\n    sumUnitaryFunding,\n    lastSumUnitaryFunding,\n    baseMMR,\n    baseIMR,\n    IMRFactor,\n    referencePrice,\n    orderSide,\n    orderQty = 0,\n    leverage,\n    isoTakerFeeBuffer = IsoTakerFeeBuffer,\n  } = inputs;\n\n  // Use reference price or mark price (default to a reasonable value if not provided)\n  const refPrice = referencePrice ?? 0;\n  if (refPrice <= 0 && orderQty !== 0) {\n    return null;\n  }\n\n  // Calculate position_qty' after order execution\n  const orderSideMultiplier =\n    orderSide === \"BUY\" ? 1 : orderSide === \"SELL\" ? -1 : 0;\n  const newPositionQty = positionQty + orderSideMultiplier * orderQty;\n\n  if (newPositionQty === 0) {\n    return null; // No position after order execution\n  }\n\n  // Determine scenario and calculate isolated_position_margin' and cost_position'\n  let newIsolatedPositionMargin: Decimal;\n  let newCostPosition: Decimal;\n  const getMarginRate = () =>\n    new Decimal(1).div(leverage).add(isoTakerFeeBuffer);\n\n  if (orderQty === 0) {\n    // Scenario 1: No order\n    newIsolatedPositionMargin = new Decimal(isolatedPositionMargin);\n    newCostPosition = new Decimal(costPosition);\n  } else if (\n    positionQty === 0 ||\n    (orderSideMultiplier > 0 && positionQty > 0) ||\n    (orderSideMultiplier < 0 && positionQty < 0)\n  ) {\n    // Scenario 2: Open/Add position\n    newIsolatedPositionMargin = new Decimal(isolatedPositionMargin).add(\n      new Decimal(orderQty).mul(refPrice).mul(getMarginRate()),\n    );\n    newCostPosition = new Decimal(costPosition).add(\n      new Decimal(orderSideMultiplier).mul(orderQty).mul(refPrice),\n    );\n  } else {\n    const signPositionQty = positionQty > 0 ? 1 : -1;\n    const signNewPositionQty = newPositionQty > 0 ? 1 : -1;\n\n    if (signNewPositionQty === signPositionQty) {\n      // Scenario 3: Close/Reduce position\n      newIsolatedPositionMargin = new Decimal(isolatedPositionMargin)\n        .mul(newPositionQty)\n        .div(positionQty);\n      newCostPosition = new Decimal(costPosition).add(\n        new Decimal(orderSideMultiplier).mul(orderQty).mul(refPrice),\n      );\n    } else {\n      // Scenario 4: Flip position\n      newIsolatedPositionMargin = new Decimal(Math.abs(newPositionQty))\n        .mul(refPrice)\n        .mul(getMarginRate());\n      newCostPosition = new Decimal(newPositionQty).mul(refPrice);\n    }\n  }\n\n  // Calculate funding adjustment\n  const fundingAdjustment = new Decimal(newPositionQty).mul(\n    new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding),\n  );\n\n  // Calculate MMR' based on new position notional\n  const newPositionNotional = new Decimal(Math.abs(newPositionQty)).mul(\n    refPrice,\n  );\n  const dynamicMMR = new Decimal(baseMMR)\n    .div(baseIMR)\n    .mul(IMRFactor)\n    .mul(newPositionNotional.toPower(IMRFactorPower))\n    .toNumber();\n  const newMMR = Math.max(baseMMR, dynamicMMR);\n\n  // Calculate denominator: abs(position_qty') * MMR' - position_qty'\n  const denominator = new Decimal(Math.abs(newPositionQty))\n    .mul(newMMR)\n    .sub(newPositionQty);\n\n  if (denominator.isZero()) {\n    return null; // Invalid denominator\n  }\n\n  // Calculate liquidation price\n  const numerator = newIsolatedPositionMargin\n    .sub(newCostPosition)\n    .sub(fundingAdjustment);\n\n  const liquidationPrice = numerator.div(denominator).toNumber();\n\n  // Return null for invalid prices (negative or zero)\n  if (liquidationPrice <= 0) {\n    return null;\n  }\n\n  return liquidationPrice;\n}\n","export * from \"./totalValue\";\nexport * from \"./freeCollateral\";\nexport * from \"./freeCollateralUSDCOnly\";\nexport * from \"./totalCollateral\";\nexport * from \"./positionNotional\";\nexport * from \"./imr\";\nexport * from \"./ordersFilter\";\nexport * from \"./positionUtils\";\nexport * from \"./initialMargin\";\nexport * from \"./groupOrders\";\nexport * from \"./otherIMs\";\nexport * from \"./maxQty\";\nexport * from \"./maxQtyIsolated\";\nexport * from \"./marginRatio\";\nexport * from \"./unrealizedROI\";\nexport * from \"./leverage\";\nexport * from \"./availableBalance\";\nexport * from \"./mmr\";\nexport * from \"./collateral\";\nexport * from \"./ltv\";\nexport * from \"./maxWithdrawal\";\nexport * from \"./maxAddReduce\";\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type TotalValueInputs = {\n  totalUnsettlementPnL: number;\n  USDCHolding: number;\n  nonUSDCHolding: {\n    holding: number;\n    indexPrice: number;\n  }[];\n};\n\n/**\n * @formulaId totalValue\n * @name Total Value\n * @formula Total Value = total_holding + total_isolated_position_margin + total_unsettled_PNL, total_holding = usdc balance.holding + SUM(non-usdc balance.holding * mark price)\n * @description\n *\n * ## Definition\n *\n * **Total Value** = User's total asset value (denominated in USDC), including assets that cannot be used as collateral\n *\n * **Total holding** = Sum of all holding quantities in the user's account\n *\n * **usdc balance.holding** = USDC holding quantity\n *\n * **non-usdc balance.holding * mark price** = Value of non-USDC asset holdings (denominated in USDC)\n *\n * **total_isolated_position_margin** = Sum of all isolated margin position margins\n *\n * **holding**: Asset quantity held by the user, from `/v1/client/holding` or v2 Websocket API | Balance\n *\n * **mark price**: Current price of the asset, from v2 Websocket API | Balance\n *\n * **total unsettlement PNL** = Sum of user's account unsettled PNL (including both cross and isolated margin positions)\n *\n * ## Example\n *\n * ```\n * total_holding = 2000 + 1000 * 1.001 = 3001\n * total_isolated_position_margin = 500\n * total_unsettled_PNL = -18.34\n * Total Value = 3001 + 500 - 18.34 = 3482.66\n * ```\n */\nexport function totalValue(inputs: {\n  /**\n   * @description Total unsettled PNL of user account (including both cross and isolated margin positions)\n   */\n  totalUnsettlementPnL: number;\n  /**\n   * @description USDC holding quantity\n   */\n  USDCHolding: number;\n  /**\n   * @description Non-USDC holdings with their index prices\n   */\n  nonUSDCHolding: {\n    holding: number;\n    indexPrice: number;\n  }[];\n  /**\n   * @description Total isolated position margin (sum of all isolated margin positions). Pass 0 if no isolated margin positions exist.\n   * @default 0\n   */\n  totalIsolatedPositionMargin?: number;\n}): Decimal {\n  const {\n    totalUnsettlementPnL,\n    USDCHolding,\n    nonUSDCHolding,\n    totalIsolatedPositionMargin = 0,\n  } = inputs;\n  const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n    return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n  }, zero);\n  return nonUSDCHoldingValue\n    .add(USDCHolding)\n    .add(totalIsolatedPositionMargin)\n    .add(totalUnsettlementPnL);\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type FreeCollateralInputs = {\n  totalCollateral: Decimal;\n  totalInitialMarginWithOrders: number;\n};\n\n/**\n * @formulaId freeCollateral\n * @name Free Collateral\n * @formula Free Collateral = Total_collateral_value - total_initial_margin_with_orders\n * Total_collateral_value = (usdc balance.holding + usdc balance.pending_short_qty - usdc balance.isolated_order_frozen) + SUM(non-usdc balance.holding * mark price * discount) + total_cross_unsettled_PNL\n * total_initial_margin_with_orders = sum ( cross_position_notional_with_orders_i * cross_IMR_i (with_orders))\n * IMR_i (with_orders) = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n * position_notional_with_orders_i = abs( mark_price_i * position_qty_with_orders_i)\n * position_qty_with_orders_i = max[ abs(position_qty_i + sum_position_qty_buy_orders_i), abs(position_qty_i - sum_position_qty_sell_orders_i)]\n * @description\n *\n * ## Definition\n *\n * **Free collateral**: Total value of available margin in the user's account (denominated in USDC). For isolated margin mode, this only considers cross margin positions and orders.\n *\n * **Total_collateral_value**: Total value of collateral assets in the user's account (denominated in USDC). For isolated margin mode, includes cross margin unsettled PNL but excludes isolated order frozen amounts.\n * Use `totalCollateral` function with optional parameters (`usdcBalancePendingShortQty`, `usdcBalanceIsolatedOrderFrozen`, `totalCrossUnsettledPnL`) to calculate this value.\n *\n * **total_initial_margin_with_orders**: Total initial margin used by cross margin positions and orders (isolated margin positions are excluded).\n * Use `totalInitialMarginWithQty` function with `orders` parameter to calculate this value. The function automatically filters to cross margin only.\n *\n * **usdc balance.pending_short_qty**: USDC balance frozen for pending short orders\n *\n * **usdc balance.isolated_order_frozen**: USDC balance frozen for isolated margin orders\n *\n * **total_cross_unsettled_PNL**: Total unsettled PNL from cross margin positions only\n *\n * **initial_margin_i with order**: Initial margin for symbol i (considering both positions and orders)\n *\n * **IMR_i (with_orders)**: Initial margin rate for a single symbol (considering both position and order notional)\n *\n * **Symbol Leverage i**: Leverage for symbol i under current margin mode (cross/isolated). Use `position.leverage` when position exists; otherwise resolve by symbol + mode leverage source.\n *\n * **Base IMR i**: Base initial margin rate for a single symbol, from `/v1/public/info`\n *\n * **IMR Factor i**: IMR calculation factor for a single symbol, from `v1/client/info`\n *\n * **Position Notional i**: Sum of position notional for a single symbol\n *\n * **Order Notional i**: Sum of order notional for a single symbol\n *\n * **position_notional_with_orders_i**: Sum of position and order notional for a single symbol\n *\n * **mark_price_i**: Mark price for a single symbol\n *\n * **position_qty_with_orders_i**: Sum of position and order quantity for a single symbol\n *\n * **position_qty_i**: Position quantity for a single symbol\n *\n * **sum_position_qty_buy_orders_i**: Sum of long order quantity for a single symbol [algo orders should be ignored]\n *\n * **sum_position_qty_sell_orders_i**: Sum of short order quantity for a single symbol [algo orders should be ignored]\n *\n * ## Example\n *\n * ```\n * Total_collateral_value = (2000 + 100 - 200) + 1 * 2000 * 0.9 + 50 = 2050\n * total_initial_margin_with_orders = 1500\n * Free Collateral = 2050 - 1500 = 550\n * ```\n */\nexport function freeCollateral(inputs: {\n  /**\n   * @description Total collateral value\n   */\n  totalCollateral: Decimal;\n  /**\n   * @description Total initial margin with orders (for cross margin positions only)\n   */\n  totalInitialMarginWithOrders: number;\n}): Decimal {\n  const value = inputs.totalCollateral.sub(inputs.totalInitialMarginWithOrders);\n  // free collateral cannot be less than 0\n  return value.isNegative() ? zero : value;\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type FreeCollateralUSDCOnlyInputs = {\n  /**\n   * Free collateral (total_collateral_value - total_initial_margin_with_orders).\n   * @see freeCollateral\n   */\n  freeCollateral: Decimal;\n  /**\n   * Non-USDC token holdings; same structure as in totalCollateral.\n   * Each item contributes (capped_holding × index_price × discount) to the sum to subtract.\n   */\n  nonUSDCHolding: {\n    holding: number;\n    indexPrice: number;\n    collateralCap: number;\n    collateralRatio: Decimal;\n  }[];\n};\n\n/**\n * @formulaId freeCollateralUSDCOnly\n * @name Free Collateral (USDC Only)\n * @formula Free Collateral USDC Only = max(0, free_collateral - SUM(non_usdc_token.holding × mark_price × discount))\n * @description\n *\n * ## Definition\n *\n * **Free Collateral (USDC Only)**: Part of free collateral that is backed only by USDC (and unsettled PNL), i.e. excluding the value of non-USDC collateral.\n *\n * **free_collateral**: From freeCollateral (total_collateral_value - total_initial_margin_with_orders).\n *\n * **non_usdc_token.holding × mark_price × discount**: Same as in totalCollateral — value of each non-USDC asset (capped by collateralCap), using indexPrice as mark price and collateralRatio as discount.\n *\n * ## Example\n *\n * ```\n * free_collateral = 550\n * SUM(non_usdc.holding × mark_price × discount) = 1 * 2000 * 0.9 = 1800\n * Free Collateral USDC Only = max(0, 550 - 1800) = 0\n * ```\n */\nexport function freeCollateralUSDCOnly(\n  inputs: FreeCollateralUSDCOnlyInputs,\n): Decimal {\n  const { freeCollateral, nonUSDCHolding } = inputs;\n\n  const nonUSDCHoldingValue = nonUSDCHolding.reduce<Decimal>((acc, cur) => {\n    const finalHolding = Math.min(cur.holding, cur.collateralCap);\n    const value = new Decimal(finalHolding)\n      .mul(cur.collateralRatio)\n      .mul(cur.indexPrice);\n    return acc.add(value);\n  }, zero);\n\n  const value = freeCollateral.sub(nonUSDCHoldingValue);\n  return value.isNegative() ? zero : value;\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * @formulaId totalCollateral\n * @name Total Collateral\n * @formula Total collateral = usdc balance.holding + SUM(non-usdc balance.holding * mark price * discount) + total unsettlement PNL\n * @description\n *\n * ## Definition\n *\n * **discount**: Collateral substitution rate\n *\n * **Total collateral**: Total value of collateral assets in the user's account (denominated in USDC)\n *\n * **usdc balance.holding**: USDC holding quantity\n *\n * **non-usdc balance.holding * mark price**: Value of non-USDC asset holdings (denominated in USDC)\n *\n * **holding**: Asset quantity held by the user, from `/v1/client/holding` or v2 Websocket API | Balance\n *\n * **mark price**: Current price of the asset, from v2 Websocket API | Balance\n *\n * **total unsettlement PNL**: Sum of user's account unsettled PNL\n *\n * ## Example\n *\n * ```\n * Total collateral = 2000 + 1000 * 1.001 * 0 - 18.34 = 1981.66\n * total unsettlement PNL = -18.34\n * ```\n */\nexport function totalCollateral(inputs: {\n  USDCHolding: number;\n  nonUSDCHolding: {\n    holding: number;\n    indexPrice: number;\n    collateralCap: number;\n    collateralRatio: Decimal;\n  }[];\n  /**\n   * Sum of user's account unsettled PNL\n   */\n  unsettlementPnL: number;\n  /**\n   * @description USDC balance frozen for pending short orders (for freeCollateral calculation)\n   * @default 0\n   */\n  usdcBalancePendingShortQty?: number;\n  /**\n   * @description USDC balance frozen for isolated margin orders (for freeCollateral calculation)\n   * @default 0\n   */\n  usdcBalanceIsolatedOrderFrozen?: number;\n  /**\n   * @description Total cross margin unsettled PNL (for freeCollateral calculation). If provided, this will be used instead of unsettlementPnL.\n   */\n  totalCrossUnsettledPnL?: number;\n}): Decimal {\n  const {\n    USDCHolding,\n    nonUSDCHolding,\n    unsettlementPnL,\n    usdcBalancePendingShortQty = 0,\n    usdcBalanceIsolatedOrderFrozen = 0,\n    totalCrossUnsettledPnL,\n  } = inputs;\n\n  // Calculate USDC part: holding + pending_short_qty - isolated_order_frozen\n  const usdcPart = new Decimal(USDCHolding)\n    .add(usdcBalancePendingShortQty)\n    .sub(Math.abs(usdcBalanceIsolatedOrderFrozen));\n\n  // Calculate non-USDC holdings value\n  const nonUSDCHoldingValue = nonUSDCHolding.reduce<Decimal>((acc, cur) => {\n    const finalHolding = Math.min(cur.holding, cur.collateralCap);\n    const value = new Decimal(finalHolding)\n      .mul(cur.collateralRatio)\n      .mul(cur.indexPrice);\n    return acc.add(value);\n  }, zero);\n\n  // Use totalCrossUnsettledPnL if provided, otherwise use unsettlementPnL\n  const pnl =\n    totalCrossUnsettledPnL !== undefined\n      ? totalCrossUnsettledPnL\n      : unsettlementPnL;\n\n  return usdcPart.add(nonUSDCHoldingValue).add(pnl);\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(inputs: {\n  markPrice: number;\n  positionQtyWithOrders: number;\n}): Decimal {\n  return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\n/**\n *  Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(inputs: {\n  positionQty: number;\n  // Total quantity of buy orders for a symbol\n  buyOrdersQty: number;\n  // Total quantity of sell orders for a symbol\n  sellOrdersQty: number;\n}): number {\n  const { positionQty, buyOrdersQty, sellOrdersQty } = inputs;\n  const positionQtyDecimal = new Decimal(positionQty);\n  const qty = Math.max(\n    positionQtyDecimal.add(buyOrdersQty).abs().toNumber(),\n    positionQtyDecimal.sub(sellOrdersQty).abs().toNumber(),\n  );\n\n  return qty;\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId imr\n * @description\n * Initial margin rate for a symbol.\n * Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: {\n  /**\n   * effective symbol leverage (resolved by symbol + margin mode)\n   */\n  maxLeverage: number;\n  baseIMR: number;\n  IMR_Factor: number;\n  positionNotional: number;\n  ordersNotional: number;\n  IMR_factor_power?: number;\n}): number {\n  const {\n    maxLeverage,\n    baseIMR,\n    IMR_Factor,\n    positionNotional,\n    ordersNotional: orderNotional,\n    IMR_factor_power = IMRFactorPower,\n  } = inputs;\n  return Math.max(\n    1 / maxLeverage,\n    baseIMR,\n    new Decimal(IMR_Factor)\n      .mul(\n        new Decimal(positionNotional)\n          .add(orderNotional)\n          .abs()\n          .toPower(IMR_factor_power),\n      )\n      .toNumber(),\n  );\n}\n","import { API, OrderSide } from \"@orderly.network/types\";\n\nexport function buyOrdersFilter_by_symbol(\n  orders: API.Order[],\n  symbol: string,\n): API.Order[] {\n  return orders.filter(\n    (item) => item.symbol === symbol && item.side === OrderSide.BUY,\n  );\n}\n\nexport function sellOrdersFilter_by_symbol(\n  orders: API.Order[],\n  symbol: string,\n): API.Order[] {\n  return orders.filter(\n    (item) => item.symbol === symbol && item.side === OrderSide.SELL,\n  );\n}\n","import { API, OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\nimport {\n  buyOrdersFilter_by_symbol,\n  sellOrdersFilter_by_symbol,\n} from \"./ordersFilter\";\n\n/**\n * Get the quantity of a specified symbol from the list of positions.\n */\nexport function getQtyFromPositions(\n  positions: API.Position[],\n  symbol: string,\n): number {\n  if (!positions) {\n    return 0;\n  }\n  const position = positions.find((item) => item.symbol === symbol);\n  return position?.position_qty || 0;\n}\n\n/**\n * Get the quantity of long and short orders for a specified symbol from the list of orders.\n */\nexport function getQtyFromOrdersBySide(\n  orders: API.Order[],\n  symbol: string,\n  side: OrderSide,\n): number {\n  const ordersBySide =\n    side === OrderSide.SELL\n      ? sellOrdersFilter_by_symbol(orders, symbol)\n      : buyOrdersFilter_by_symbol(orders, symbol);\n  return ordersBySide.reduce((acc, cur) => {\n    return acc + cur.quantity;\n  }, 0);\n}\n\nexport function getPositonsAndOrdersNotionalBySymbol(inputs: {\n  positions: API.Position[];\n  orders: API.Order[];\n  symbol: string;\n  markPrice: number;\n}): number {\n  const { positions, orders, symbol, markPrice } = inputs;\n  const positionQty = getQtyFromPositions(positions, symbol);\n  const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n  const sellOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.SELL);\n\n  const markPriceDecimal = new Decimal(markPrice);\n\n  return markPriceDecimal\n    .mul(positionQty)\n    .add(markPriceDecimal.mul(new Decimal(buyOrdersQty).add(sellOrdersQty)))\n    .abs()\n    .toNumber();\n}\n","import { API, OrderSide, MarginMode } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\nimport {\n  positionNotionalWithOrder_by_symbol,\n  positionQtyWithOrders_by_symbol,\n} from \"./positionNotional\";\nimport { getQtyFromPositions, getQtyFromOrdersBySide } from \"./positionUtils\";\n\n/**\n * Calculate initial margin for a single symbol.\n * Formula: cross_position_notional_with_orders_i * cross_IMR_i\n */\nfunction calculateSymbolInitialMargin(params: {\n  symbol: string;\n  positionQty: number;\n  buyOrdersQty: number;\n  sellOrdersQty: number;\n  markPrice: number;\n  IMR_Factors: { [key: string]: number };\n  symbolInfo: any;\n  symbolMaxLeverage: number;\n}): number {\n  const {\n    symbol,\n    positionQty,\n    buyOrdersQty,\n    sellOrdersQty,\n    markPrice,\n    IMR_Factors,\n    symbolInfo,\n    symbolMaxLeverage,\n  } = params;\n\n  // Formula: cross_position_qty_with_orders_i = max[abs(pos + buy), abs(pos - sell)]\n  const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n    positionQty,\n    buyOrdersQty,\n    sellOrdersQty,\n  });\n\n  // Formula: cross_position_notional_with_orders_i = abs(mark_price * qty_with_orders)\n  const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({\n    markPrice,\n    positionQtyWithOrders,\n  });\n\n  const markPriceDecimal = new Decimal(markPrice);\n\n  // Formula: cross_IMR_i = Max(1/leverage, baseIMR, IMR_Factor * |posNotional + orderNotional|^(4/5))\n  // Cross Order Notional = mark_price * (buyOrdersQty - sellOrdersQty)\n  // Buy orders increase exposure (+), sell orders decrease exposure (-)\n  const imr = IMR({\n    positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n    ordersNotional: markPriceDecimal\n      .mul(new Decimal(buyOrdersQty).sub(sellOrdersQty))\n      .toNumber(),\n    maxLeverage: symbolMaxLeverage,\n    IMR_Factor: IMR_Factors[symbol],\n    baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n  });\n\n  return positionNotionalWithOrders.mul(imr).toNumber();\n}\n\nfunction IMR(inputs: {\n  maxLeverage: number;\n  baseIMR: number;\n  IMR_Factor: number;\n  positionNotional: number;\n  ordersNotional: number;\n  IMR_factor_power?: number;\n}): number {\n  const {\n    maxLeverage,\n    baseIMR,\n    IMR_Factor,\n    positionNotional,\n    ordersNotional: orderNotional,\n    IMR_factor_power = IMRFactorPower,\n  } = inputs;\n\n  const imr =\n    IMR_Factor === 0\n      ? 0\n      : new Decimal(IMR_Factor)\n          .mul(\n            new Decimal(positionNotional)\n              .add(orderNotional)\n              .abs()\n              .toPower(IMR_factor_power),\n          )\n          .toNumber();\n  return Math.max(1 / maxLeverage, baseIMR, imr);\n}\n\n/**\n * Calculate total initial margin with orders for cross margin positions.\n * Formula: total_initial_margin_with_orders = sum(cross_position_notional_with_orders_i * cross_IMR_i)\n *\n * @param positions - All positions (will be filtered to cross margin only)\n * @param orders - All orders (will be filtered to cross margin only)\n * @param markPrices - Mark prices by symbol\n * @param symbolInfo - Symbol info accessor\n * @param IMR_Factors - IMR factors by symbol\n * @param maxLeverageBySymbol - Symbol leverage map (symbol + margin mode)\n */\nexport function totalInitialMarginWithQty(inputs: {\n  positions: API.Position[];\n  orders: API.Order[];\n  markPrices: { [key: string]: number };\n  symbolInfo: any;\n  IMR_Factors: { [key: string]: number };\n  maxLeverageBySymbol?: Record<string, number>;\n}): number {\n  const {\n    positions,\n    orders,\n    markPrices,\n    IMR_Factors,\n    symbolInfo,\n    maxLeverageBySymbol,\n  } = inputs;\n\n  // Filter to cross margin only (isolated margin is excluded)\n  const crossPositions = positions.filter(\n    (p) => p.margin_mode !== MarginMode.ISOLATED,\n  );\n  const crossOrders = orders.filter(\n    (o) => o.margin_mode !== MarginMode.ISOLATED,\n  );\n  const crossLeverageBySymbol = crossPositions.reduce<Record<string, number>>(\n    (acc, position) => {\n      if (!acc[position.symbol] && position.leverage) {\n        acc[position.symbol] = position.leverage;\n      }\n      return acc;\n    },\n    {},\n  );\n\n  // Extract all symbols from both positions and orders\n  // (orders-only symbols should also be included in calculation)\n  const symbols = extractSymbols(crossPositions, crossOrders);\n\n  // Calculate initial margin for each symbol and sum\n  return symbols\n    .map((symbol) => {\n      const positionQty = getQtyFromPositions(crossPositions, symbol);\n      const markPrice = markPrices[symbol] || 0;\n      const buyOrdersQty = getQtyFromOrdersBySide(\n        crossOrders,\n        symbol,\n        OrderSide.BUY,\n      );\n      const sellOrdersQty = getQtyFromOrdersBySide(\n        crossOrders,\n        symbol,\n        OrderSide.SELL,\n      );\n      const symbolMaxLeverage =\n        crossLeverageBySymbol[symbol] ?? maxLeverageBySymbol?.[symbol] ?? 1;\n\n      return calculateSymbolInitialMargin({\n        symbol,\n        positionQty,\n        buyOrdersQty,\n        sellOrdersQty,\n        markPrice,\n        IMR_Factors,\n        symbolInfo,\n        symbolMaxLeverage,\n      });\n    })\n    .reduce((acc, margin) => acc.add(margin), zero)\n    .toNumber();\n}\n\nfunction extractSymbols(\n  positions: Pick<API.Position, \"symbol\">[],\n  orders: Pick<API.Order, \"symbol\">[],\n): string[] {\n  const symbols = new Set<string>();\n\n  positions.forEach((item) => {\n    symbols.add(item.symbol);\n  });\n\n  orders.forEach((item) => {\n    symbols.add(item.symbol);\n  });\n\n  return Array.from(symbols);\n}\n","import { API } from \"@orderly.network/types\";\n\n/**\n * Group orders by symbol, as a symbol can have multiple orders.\n */\nexport function groupOrdersBySymbol(orders: API.Order[]) {\n  const symbols: { [key: string]: API.Order[] } = {};\n\n  orders.forEach((item) => {\n    if (!symbols[item.symbol]) {\n      symbols[item.symbol] = [];\n    }\n\n    symbols[item.symbol].push(item);\n  });\n\n  return symbols;\n}\n\n/**\n * Extracts all unique symbols from positions and orders.\n * @param positions - An array of position objects.\n * @param orders - An array of order objects.\n * @returns An array of unique symbols.\n */\nexport function extractSymbols(\n  positions: Pick<API.Position, \"symbol\">[],\n  orders: Pick<API.Order, \"symbol\">[],\n): string[] {\n  const symbols = new Set<string>();\n\n  positions.forEach((item) => {\n    symbols.add(item.symbol);\n  });\n\n  orders.forEach((item) => {\n    symbols.add(item.symbol);\n  });\n\n  return Array.from(symbols);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { positionQtyWithOrders_by_symbol } from \"./positionNotional\";\nimport { positionNotionalWithOrder_by_symbol } from \"./positionNotional\";\nimport { getQtyFromPositions } from \"./positionUtils\";\n\nfunction IMR(inputs: {\n  maxLeverage: number;\n  baseIMR: number;\n  IMR_Factor: number;\n  positionNotional: number;\n  ordersNotional: number;\n  IMR_factor_power?: number;\n}): number {\n  const {\n    maxLeverage,\n    baseIMR,\n    IMR_Factor,\n    positionNotional,\n    ordersNotional: orderNotional,\n    IMR_factor_power = 4 / 5,\n  } = inputs;\n  return Math.max(\n    1 / maxLeverage,\n    baseIMR,\n    new Decimal(IMR_Factor)\n      .mul(\n        new Decimal(positionNotional)\n          .add(orderNotional)\n          .abs()\n          .toPower(IMR_factor_power),\n      )\n      .toNumber(),\n  );\n}\n\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: {\n  // the position list for other symbols except the current symbol\n  positions: API.Position[];\n  markPrices: { [key: string]: number };\n  symbolInfo: any;\n  IMR_Factors: { [key: string]: number };\n}): number {\n  const {\n    // orders,\n    positions,\n    IMR_Factors,\n    symbolInfo,\n    markPrices,\n  } = inputs;\n\n  const symbols = positions.map((item) => item.symbol);\n\n  return symbols\n    .reduce((acc, cur) => {\n      const symbol = cur;\n\n      if (typeof markPrices[symbol] === \"undefined\") {\n        console.warn(\"markPrices[%s] is undefined\", symbol);\n        return acc;\n      }\n\n      const markPriceDecimal = new Decimal(markPrices[symbol] || 0);\n\n      const position = positions.find((item) => item.symbol === symbol);\n\n      const positionQty = getQtyFromPositions(positions, symbol);\n      const positionNotional = markPriceDecimal.mul(positionQty).toNumber();\n\n      const buyOrdersQty = position!.pending_long_qty;\n      const sellOrdersQty = position!.pending_short_qty;\n\n      const ordersNotional = markPriceDecimal\n        .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n        .toNumber();\n\n      const IMR_Factor = IMR_Factors[symbol];\n\n      // IMR_Factor is possible to be 0\n      if (typeof IMR_Factor === \"undefined\") {\n        console.warn(\"IMR_Factor is not found:\", symbol);\n        return acc;\n      }\n\n      const imr = IMR({\n        // Use symbol + mode leverage from position directly.\n        maxLeverage: position?.leverage || 1,\n        IMR_Factor,\n        baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n        positionNotional,\n        ordersNotional,\n      });\n\n      const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n        positionQty,\n        buyOrdersQty,\n        sellOrdersQty,\n      });\n\n      const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({\n        markPrice: markPrices[symbol] || 0,\n        positionQtyWithOrders,\n      });\n\n      return acc.add(positionNotionalWithOrders.mul(imr));\n    }, zero)\n    .toNumber();\n}\n","import { OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\nexport type ResultOptions = {\n  dp: number;\n};\n\nexport type MaxQtyInputs = {\n  symbol: string;\n\n  /**\n   * @description Maximum quantity limit for opening a single position, /v1/public/info.base_max\n   */\n  baseMaxQty: number;\n  /**\n   * Total collateral of the user (denominated in USDC), can be calculated from totalCollateral.\n   * @see totalCollateral\n   */\n  totalCollateral: number;\n  maxLeverage: number;\n  baseIMR: number;\n  /**\n   * @see otherIMs\n   */\n  otherIMs: number;\n  markPrice: number;\n  // Quantity of open positions\n  positionQty: number;\n  // Quantity of long orders\n  buyOrdersQty: number;\n  // Quantity of short orders\n  sellOrdersQty: number;\n\n  IMR_Factor: number;\n\n  takerFeeRate: number;\n};\n\n/**\n * @formulaId maxQty\n * @name Max Order QTY\n * @description\n * ## Max Long Quantity Formula\n *\n * ```\n * max long qty = MIN (\n *   base max,\n *   (((Total_collateral_value - Other_IMs) / (Max(1 / Symbol Leverage i, Base IMR i) + 2 * futures_take_fee_rate * 0.0001) / mark_price_i) * 0.995 - position_qty_this_symbol - sum_buy_order_qty_this_symbol),\n *   ((((Total_collateral_value - Other_IMs) / IMR Factor i)^(1/1.8)) / mark_price_i - position_qty_this_symbol - sum_buy_order_qty_this_symbol) / (1 + 2 * futures_take_fee_rate * 0.0001) * 0.995\n * )\n * ```\n *\n * ## Max Short Quantity Formula\n *\n * ```\n * max short qty = MIN (\n *   base max,\n *   (((Total_collateral_value - Other_IMs) / (Max(1 / Symbol Leverage i, Base IMR i) + 2 * futures_take_fee_rate * 0.0001) / mark_price_i) * 0.995 + position_qty_this_symbol - sum_sell_order_qty_this_symbol),\n *   ((((Total_collateral_value - Other_IMs) / IMR Factor i)^(1/1.8)) / mark_price_i + position_qty_this_symbol - sum_sell_order_qty_this_symbol) / (1 + 2 * futures_take_fee_rate * 0.0001) * 0.995\n * )\n * ```\n *\n * ## Reduce Only Mode\n *\n * When reduce only is enabled:\n * - If `position_qty_i > 0`: max long qty = 0, max short qty = abs(position_qty_i)\n * - If `position_qty_i < 0`: max long qty = abs(position_qty_i), max short qty = 0\n * - If `position_qty_i = 0`: max long qty = 0, max short qty = 0\n *\n * ## Variable Definitions\n *\n * | Variable | Description | API Reference |\n * |----------|-------------|---------------|\n * | `max long qty` | Maximum long quantity for current symbol | |\n * | `max short qty` | Maximum short quantity for current symbol | |\n * | `base_max` | Maximum quantity limit for opening a single position | `/v1/public/info.base_max` |\n * | `Total_collateral_value` | Total value of collateral assets in user account (USDC denominated) | |\n * | `Other_IMs` | Initial margin occupied by all other symbols excluding current symbol | |\n * | `IMR_i (with_orders)` | Initial margin rate for a single symbol (considering both position/orders notional) | |\n * | `Symbol Leverage i` | Leverage for symbol i under current margin mode | `position.leverage` or symbol+mode leverage source |\n * | `Base IMR i` | Base initial margin rate for a single symbol | `/v1/public/info` |\n * | `IMR Factor i` | IMR calculation factor for a single symbol | `v1/client/info` |\n * | `Position Notional i` | Sum of position notional for a single symbol | |\n * | `Order Notional i` | Sum of order notional for a single symbol | |\n * | `position_notional_with_orders_i` | Sum of position/orders notional for a single symbol | |\n * | `mark_price_i` | Mark price for a single symbol | |\n * | `position_qty_with_orders_i` | Sum of position/orders quantity for a single symbol | |\n * | `position_qty_i` | Position quantity for a single symbol | |\n * | `sum_position_qty_buy_orders_i` | Sum of long order quantity for a single symbol [algo orders ignored] | |\n * | `sum_position_qty_sell_orders_i` | Sum of short order quantity for a single symbol [algo orders ignored] | |\n * | `futures_take_fee_rate` | User's futures taker fee rate | `GET /v1/client/info` |\n *\n * ## Calculation Details\n *\n * ```\n * Other_IMs = sum(position_notional_with_orders_i * IMR_i (with_orders)) // excluding current symbol\n *\n * IMR_i (with_orders) = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n *\n * position_notional_with_orders_i = abs(mark_price_i * position_qty_with_orders_i)\n *\n * position_qty_with_orders_i = max[abs(position_qty_i + sum_position_qty_buy_orders_i), abs(position_qty_i - sum_position_qty_sell_orders_i)]\n * ```\n *\n * ## Example Calculation\n *\n * **Given:**\n * - `futures_take_fee_rate = 8`\n * - `BTC base max = 20`\n * - `Total_collateral_value = 1981.66`\n * - `Other_IMs = ETH Initial Margin = 4915.23 * 0.1 = 491.523`\n * - `BTC mark_price_i = 25986.2`\n * - `BTC position_qty_this_symbol = 0.2`\n * - `sum_buy_order_qty_this_symbol = 0.3`\n * - `sum_sell_order_qty_this_symbol = -0.5`\n *\n * **Max Long Quantity:**\n * ```\n * max long qty = MIN(\n *   20 BTC,\n *   ((1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 - 0.2 - 0.3) = 0.0615815026 BTC,\n *   ((((1981.66 - 491.523) / 0.0000002512)^(1/1.8)) / 25986.2 - 0.2 - 0.3) / (1 + 2 * 8 * 0.0001) * 0.995 = 9.78216039 BTC\n * ) = 0.0615815026 BTC\n * ```\n *\n * **Max Short Quantity:**\n * ```\n * max short qty = MIN(\n *   20 BTC,\n *   ((1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 + 0.2 - 0.5) = 0.261581503 BTC,\n *   ((((1981.66 - 491.523) / 0.0000002512)^(1/1.8)) / 25986.2 + 0.2 - 0.5) / (1 + 2 * 8 * 0.0001) * 0.995 = 9.98084249726 BTC\n * ) = 0.261581503 BTC\n * ```\n *\n * ## Additional Examples\n *\n * **Base max qty calculation:**\n * ```\n * Base max qty = (1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 = 0.561581503 BTC\n * ```\n *\n * **Different position scenarios:**\n *\n * 1. **Short position -0.3 BTC:**\n *    - max long qty = 0.561581503 - (-0.3) = 0.861581503\n *    - max short qty = 0.561581503 + (-0.3) = 0.261581503\n *\n * 2. **Short position -0.3 BTC + sell orders 0.1:**\n *    - max long qty = 0.561581503 - (-0.3) = 0.861581503\n *    - max short qty = 0.561581503 + (-0.3) - 0.1 = 0.161581503\n *\n * 3. **Long position 0.3 BTC + buy orders 0.2 + sell orders 0.1:**\n *    - max long qty = 0.561581503 - 0.3 - 0.2 = 0.061581503\n *    - max short qty = 0.561581503 + 0.3 - 0.1 = 0.761581503\n *\n * ## Special Case: Insufficient Collateral\n *\n * When `totalCollatValue <= newTotalIM`:\n *\n * ```\n * newOrderSize_iter = ITERATE() return max(0, newOrderSize_iter * 99.5% + others)\n * ```\n *\n * **ITERATE() Algorithm:**\n * ```\n * ITERATE() {\n *     iteratorLeverage = min(1 / Symbol Leverage i, Base IMR i)\n *     iteratorStep = 2\n *\n *     // First iteration (30 times)\n *     for (i = 0; i < 30; i++) {\n *         iteratorLeverage = max(0, iteratorLeverage - iteratorStep)\n *         newOrderSize1 = (adjustedCollateral - othersIM) * iteratorLeverage / markPrice\n *         calculate afterTradeIM\n *         if (adjustedCollateral >= afterTradeIM) break\n *     }\n *\n *     leftLeverage = iteratorLeverage\n *     rightLeverage = min(symbolLeverage_i, leftLeverage + iteratorStep)\n *\n *     // Binary search (30 times)\n *     for (i = 0; i < 30; i++) {\n *         midLeverage = (leftLeverage + rightLeverage) / 2\n *         newOrderSize2 = (adjustedCollateral - othersIM) * midLeverage / markPrice\n *         calculate afterTradeIM\n *         precision = (adjustedCollateral - afterTradeIM) / adjustedCollateral\n *\n *         if (adjustedCollateral > afterTradeIM) {\n *             leftLeverage = midLeverage\n *             if (0 <= precision <= 0.5%) break\n *         } else {\n *             rightLeverage = midLeverage\n *         }\n *     }\n *\n *     return newOrderSize2\n * }\n * ```\n */\nexport function maxQty(\n  side: OrderSide,\n  inputs: MaxQtyInputs,\n  options?: ResultOptions,\n): number {\n  if (side === OrderSide.BUY) {\n    return maxQtyByLong(inputs);\n  }\n  return maxQtyByShort(inputs);\n}\n\nexport function maxQtyByLong(\n  inputs: Omit<MaxQtyInputs, \"side\">,\n  options?: ResultOptions,\n): number {\n  try {\n    const {\n      baseMaxQty,\n      totalCollateral,\n      otherIMs,\n      maxLeverage,\n      baseIMR,\n      markPrice,\n      IMR_Factor,\n      positionQty,\n      buyOrdersQty,\n      takerFeeRate,\n    } = inputs;\n\n    if (totalCollateral === 0) {\n      return 0;\n    }\n\n    const totalCollateralDecimal = new Decimal(totalCollateral);\n\n    const factor_1 = totalCollateralDecimal\n      .sub(otherIMs)\n      .div(\n        new Decimal(takerFeeRate)\n          .mul(2)\n          .mul(0.0001)\n          .add(Math.max(1 / maxLeverage, baseIMR)),\n      )\n      .div(markPrice)\n      .mul(0.995)\n      .sub(new Decimal(positionQty).add(buyOrdersQty))\n      .toNumber();\n\n    if (positionQty === 0 && buyOrdersQty === 0) {\n      return Math.min(baseMaxQty, factor_1);\n    }\n\n    if (IMR_Factor === 0) {\n      return Math.min(baseMaxQty, factor_1);\n    }\n\n    const factor_2 = totalCollateralDecimal\n      .sub(otherIMs)\n      .div(IMR_Factor)\n      .toPower(1 / 1.8)\n      .div(markPrice)\n      .sub(\n        new Decimal(positionQty).add(buyOrdersQty),\n        // .abs()\n        // .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n      )\n      .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n      .mul(0.995)\n      .toNumber();\n\n    return Math.min(baseMaxQty, factor_1, factor_2);\n  } catch (error) {\n    return 0;\n  }\n}\n\nexport function maxQtyByShort(\n  inputs: Omit<MaxQtyInputs, \"side\">,\n  options?: ResultOptions,\n): number {\n  try {\n    const {\n      baseMaxQty,\n      totalCollateral,\n      otherIMs,\n      maxLeverage,\n      baseIMR,\n      markPrice,\n      IMR_Factor,\n      positionQty,\n      buyOrdersQty,\n      sellOrdersQty,\n      takerFeeRate,\n    } = inputs;\n\n    const totalCollateralDecimal = new Decimal(totalCollateral);\n\n    const factor_1 = totalCollateralDecimal\n      .sub(otherIMs)\n      .div(\n        new Decimal(takerFeeRate)\n          .mul(2)\n          .mul(0.0001)\n          .add(Math.max(1 / maxLeverage, baseIMR)),\n      )\n      .div(markPrice)\n      .mul(0.995)\n      // .add(new Decimal(positionQty).add(sellOrdersQty))\n      .add(positionQty)\n      .sub(Math.abs(sellOrdersQty))\n      .toNumber();\n\n    if (positionQty === 0 && sellOrdersQty === 0) {\n      return Math.min(baseMaxQty, factor_1);\n    }\n\n    if (IMR_Factor === 0) {\n      return Math.min(baseMaxQty, factor_1);\n    }\n\n    const factor_2 = totalCollateralDecimal\n      .sub(otherIMs)\n      .div(IMR_Factor)\n      .toPower(1 / 1.8)\n      .div(markPrice)\n      // .add(\n      // new Decimal(positionQty)\n      //   .add(sellOrdersQty)\n      //   // .abs()\n      //   )\n      .add(positionQty)\n      .sub(sellOrdersQty)\n      .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n      .mul(0.995)\n      .toNumber();\n\n    return Math.min(baseMaxQty, factor_1, factor_2);\n  } catch (error) {\n    return 0;\n  }\n}\n","import { OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\nimport { IsoTakerFeeBuffer, MaxQtySafetyFactor } from \"../constants\";\n\n/**\n * @formulaId maxQtyIsolated\n * @name Maximum Tradeable Quantity for Isolated Margin\n * @formula max_notional = min((1 / leverage / imr_factor)^(5/4), symbol_max_notional)\n * @description\n *\n * ## Definition\n *\n * **maxQtyIsolated**: Maximum tradeable quantity for isolated margin positions\n *\n * This function calculates the maximum quantity that can be traded for an isolated margin position,\n * considering available balance, leverage, position limits, and pending orders.\n *\n * ## Business Rules\n *\n * ### For BUY Orders:\n * - If `reduce_only == False` and `position_qty >= 0` (long or no position): Use simplified formula\n * - If `reduce_only == False` and `position_qty < 0` (short position): Use binary search iteration\n * - If `reduce_only == True`: Return `MAX(0, -position_qty)` (can only reduce short position)\n *\n * ### For SELL Orders:\n * - If `reduce_only == False` and `position_qty <= 0` (short or no position): Use simplified formula\n * - If `reduce_only == False` and `position_qty > 0` (long position): Use binary search iteration\n * - If `reduce_only == True`: Return `MAX(0, position_qty)` (can only reduce long position)\n *\n * ### Binary Search Algorithm:\n * - Used for reverse position scenarios (e.g., buying when holding short position)\n * - Maximum 30 iterations\n * - Searches for maximum quantity that satisfies: `iso_order_frozen <= available_balance` and `open_notional <= max_notional`\n *\n * ## Example\n *\n * ```\n * order_side = BUY\n * reduce_only = False\n * position_qty = 5 (long)\n * available_balance = 1000 USDC\n * leverage = 25\n * mark_price = 100000 USDC\n * current_order_reference_price = 99900 USDC\n * max_notional = 10059467.44 USDC\n * pending_long_notional = 299200 USDC\n * max_qty = MIN(1000 / (1 / 25 + 0.0006) / 99900 * 0.995, (10059467.44 - 100000 * 5 - 299200) / 99900) = 0.245 BTC\n * ```\n *\n * @param inputs Input parameters for calculating maximum tradeable quantity\n * @returns Maximum tradeable quantity\n */\nexport function isolatedMarginRate(inputs: {\n  leverage: number;\n  isoTakerFeeBuffer?: number;\n}): Decimal {\n  return new Decimal(1)\n    .div(inputs.leverage)\n    .add(inputs.isoTakerFeeBuffer ?? IsoTakerFeeBuffer);\n}\n\nexport function maxQtyForIsolatedMargin(inputs: {\n  /**\n   * @description Trading symbol\n   */\n  symbol: string;\n  /**\n   * @description Order side (BUY or SELL)\n   */\n  orderSide: OrderSide;\n  /**\n   * @description Current order reference price\n   */\n  currentOrderReferencePrice: number;\n  /**\n   * @description Available balance (USDC)\n   */\n  availableBalance: number;\n  /**\n   * @description Leverage for the trading pair\n   */\n  leverage: number;\n  /**\n   * @description Base initial margin rate\n   */\n  baseIMR: number;\n  /**\n   * @description IMR calculation factor\n   */\n  IMR_Factor: number;\n  /**\n   * @description Mark price\n   */\n  markPrice: number;\n  /**\n   * @description Current position quantity (positive for long, negative for short)\n   */\n  positionQty: number;\n  /**\n   * @description Pending long orders (excluding current order)\n   */\n  pendingLongOrders: Array<{ referencePrice: number; quantity: number }>;\n  /**\n   * @description Pending sell orders (excluding current order)\n   */\n  pendingSellOrders: Array<{ referencePrice: number; quantity: number }>;\n  /**\n   * @description Already frozen margin for long orders\n   */\n  isoOrderFrozenLong: number;\n  /**\n   * @description Already frozen margin for short orders\n   */\n  isoOrderFrozenShort: number;\n  /**\n   * @description Maximum notional value for the symbol\n   */\n  symbolMaxNotional: number;\n  /**\n   * @description Precision threshold for binary search (default: 1)\n   */\n  epsilon?: number;\n  /**\n   * @description Fee buffer reserved in isolated frozen margin (default: 0.0006)\n   */\n  isoTakerFeeBuffer?: number;\n}): number {\n  const {\n    orderSide,\n    currentOrderReferencePrice,\n    availableBalance,\n    leverage,\n    IMR_Factor,\n    markPrice,\n    positionQty,\n    pendingLongOrders,\n    pendingSellOrders,\n    symbolMaxNotional,\n    epsilon = 1,\n    isoTakerFeeBuffer = IsoTakerFeeBuffer,\n  } = inputs;\n\n  const marginRate = isolatedMarginRate({ leverage, isoTakerFeeBuffer });\n\n  // Calculate max_notional\n  const maxNotional = Math.min(\n    new Decimal(1)\n      .div(new Decimal(leverage).mul(IMR_Factor))\n      .pow(5 / 4)\n      .toNumber(),\n    symbolMaxNotional,\n  );\n\n  // Handle BUY orders\n  if (orderSide === OrderSide.BUY) {\n    if (positionQty >= 0) {\n      // Long position or no position - use simplified formula\n      const pendingLongNotional = pendingLongOrders.reduce(\n        (acc, order) =>\n          acc +\n          new Decimal(order.referencePrice).mul(order.quantity).toNumber(),\n        0,\n      );\n      const maxQtyByBalance = new Decimal(availableBalance)\n        .div(marginRate)\n        .div(currentOrderReferencePrice)\n        .mul(MaxQtySafetyFactor)\n        .toNumber();\n      const maxQtyByNotional = new Decimal(maxNotional)\n        .sub(new Decimal(markPrice).mul(positionQty))\n        .sub(pendingLongNotional)\n        .div(currentOrderReferencePrice)\n        .toNumber();\n      return Math.max(0, Math.min(maxQtyByBalance, maxQtyByNotional));\n    } else {\n      // Short position - use binary search\n      return maxQtyIsolatedBinarySearch(\n        {\n          currentOrderReferencePrice,\n          availableBalance,\n          leverage,\n          baseIMR: inputs.baseIMR,\n          IMR_Factor,\n          positionQty,\n          pendingLongOrders,\n          pendingSellOrders,\n          isoOrderFrozenLong: inputs.isoOrderFrozenLong,\n          isoOrderFrozenShort: inputs.isoOrderFrozenShort,\n          isoTakerFeeBuffer,\n        },\n        maxNotional,\n        epsilon,\n        OrderSide.BUY,\n      );\n    }\n  } else {\n    // SELL orders\n    if (positionQty <= 0) {\n      // Short position or no position - use simplified formula\n      const pendingSellNotional = pendingSellOrders.reduce(\n        (acc, order) =>\n          acc +\n          new Decimal(order.referencePrice).mul(order.quantity).toNumber(),\n        0,\n      );\n      const maxQtyByBalance = new Decimal(availableBalance)\n        .div(marginRate)\n        .div(currentOrderReferencePrice)\n        .mul(MaxQtySafetyFactor)\n        .toNumber();\n      // Use abs(position_qty) for short positions\n      const maxQtyByNotional = new Decimal(maxNotional)\n        .sub(new Decimal(markPrice).mul(Math.abs(positionQty)))\n        .sub(pendingSellNotional)\n        .div(currentOrderReferencePrice)\n        .toNumber();\n      return Math.max(0, Math.min(maxQtyByBalance, maxQtyByNotional));\n    } else {\n      // Long position - use binary search\n      return maxQtyIsolatedBinarySearch(\n        {\n          currentOrderReferencePrice,\n          availableBalance,\n          leverage,\n          baseIMR: inputs.baseIMR,\n          IMR_Factor,\n          positionQty,\n          pendingLongOrders,\n          pendingSellOrders,\n          isoOrderFrozenLong: inputs.isoOrderFrozenLong,\n          isoOrderFrozenShort: inputs.isoOrderFrozenShort,\n          isoTakerFeeBuffer,\n        },\n        maxNotional,\n        epsilon,\n        OrderSide.SELL,\n      );\n    }\n  }\n}\n\n/**\n * Binary search algorithm for calculating maxQtyIsolated in reverse position scenarios\n * @param inputs Input parameters\n * @param maxNotional Maximum notional value\n * @param epsilon Precision threshold\n * @param orderSide Order side (BUY or SELL)\n * @returns Maximum tradeable quantity\n */\nfunction maxQtyIsolatedBinarySearch(\n  inputs: {\n    currentOrderReferencePrice: number;\n    availableBalance: number;\n    leverage: number;\n    baseIMR: number;\n    IMR_Factor: number;\n    positionQty: number;\n    pendingLongOrders: Array<{ referencePrice: number; quantity: number }>;\n    pendingSellOrders: Array<{ referencePrice: number; quantity: number }>;\n    isoOrderFrozenLong: number;\n    isoOrderFrozenShort: number;\n    isoTakerFeeBuffer: number;\n  },\n  maxNotional: number,\n  epsilon: number,\n  orderSide: OrderSide,\n): number {\n  const {\n    currentOrderReferencePrice,\n    availableBalance,\n    leverage,\n    positionQty,\n    pendingLongOrders,\n    pendingSellOrders,\n    isoOrderFrozenLong,\n    isoOrderFrozenShort,\n    isoTakerFeeBuffer,\n  } = inputs;\n  // baseIMR and IMR_Factor are kept in the interface for future use but not currently used in binary search\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  const _baseIMR = inputs.baseIMR;\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  const _IMR_Factor = inputs.IMR_Factor;\n\n  // Calculate sum of pending orders quantity\n  const pendingOrdersQty =\n    orderSide === OrderSide.BUY\n      ? pendingLongOrders.reduce((acc, order) => acc + order.quantity, 0)\n      : pendingSellOrders.reduce((acc, order) => acc + order.quantity, 0);\n\n  // Initialize search interval\n  let left = Math.max(0, Math.max(0, Math.abs(positionQty)) - pendingOrdersQty);\n  let right = new Decimal(maxNotional)\n    .div(currentOrderReferencePrice)\n    .add(Math.abs(positionQty))\n    .toNumber();\n\n  // Binary search (max 30 iterations)\n  for (let i = 0; i < 30; i++) {\n    const mid = (left + right) / 2;\n\n    const pendingOrders =\n      orderSide === OrderSide.BUY ? pendingLongOrders : pendingSellOrders;\n    const existingFrozen =\n      orderSide === OrderSide.BUY ? isoOrderFrozenLong : isoOrderFrozenShort;\n    const totalOrderNotional = pendingOrders.reduce(\n      (acc, order) =>\n        acc.add(new Decimal(order.referencePrice).mul(order.quantity)),\n      new Decimal(mid).mul(currentOrderReferencePrice),\n    );\n    const orderFrozen = totalOrderNotional\n      .mul(isolatedMarginRate({ leverage, isoTakerFeeBuffer }))\n      .sub(existingFrozen);\n\n    // Calculate open notional after order execution\n    const newPositionQty =\n      orderSide === OrderSide.BUY ? positionQty + mid : positionQty - mid;\n    const openNotional = new Decimal(Math.abs(newPositionQty)).mul(\n      currentOrderReferencePrice,\n    );\n\n    // Check conditions\n    const frozenOk = orderFrozen.lte(availableBalance);\n    const notionalOk = openNotional.lte(maxNotional);\n\n    if (frozenOk && notionalOk) {\n      left = mid;\n      // Early termination if precision is reached\n      if (new Decimal(availableBalance).sub(orderFrozen).lte(epsilon)) {\n        break;\n      }\n    } else {\n      right = mid;\n    }\n  }\n\n  return Math.max(0, left);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n  inputs: {\n    totalCollateral: number;\n    markPrices: { [key: string]: number };\n    positions: API.Position[];\n  },\n  dp?: number,\n): number {\n  const { totalCollateral, markPrices, positions } = inputs;\n\n  if (totalCollateral === 0) {\n    return 0;\n  }\n\n  const totalCollateralDecimal = new Decimal(totalCollateral);\n\n  const totalPositionNotional = positions.reduce((acc, cur) => {\n    const markPrice = markPrices[cur.symbol] || 0;\n    return acc.add(new Decimal(cur.position_qty).mul(markPrice).abs());\n  }, zero);\n\n  if (totalPositionNotional.eq(zero)) {\n    return 0;\n  }\n\n  return totalCollateralDecimal.div(totalPositionNotional).toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId totalUnrealizedROI\n * @name Total Unrealized ROI\n * @formula Total Unrealized ROI = Total Unrealized PNL / ( Total Value - Total Unrealized PNL ) * 100%\n * @description\n *\n * ## Definition\n *\n * **Total Unrealized PNL** = Sum of unrealized profit and loss for all current positions of the user\n *\n * **Total Value** = User's total asset value (denominated in USDC), including assets that cannot be used as collateral\n *\n * ## Example\n *\n * ```\n * Total Unrealized ROI = 200.53 / ( 2982.66 - 200.53 ) * 100% = 7.21%\n * Total Unrealized PNL = 200.53\n * Total Value = 2982.66\n * ```\n */\nexport function totalUnrealizedROI(inputs: {\n  totalUnrealizedPnL: number;\n  totalValue: number;\n}) {\n  const { totalUnrealizedPnL, totalValue } = inputs;\n\n  return new Decimal(totalUnrealizedPnL)\n    .div(totalValue - totalUnrealizedPnL)\n    .toNumber();\n}\n","/**\n * current account leverage\n */\nexport function currentLeverage(totalMarginRatio: number) {\n  if (totalMarginRatio === 0) {\n    return 0;\n  }\n  return 1 / totalMarginRatio;\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\nexport function availableBalance(inputs: {\n  USDCHolding: number;\n  unsettlementPnL: number;\n}) {\n  const { USDCHolding, unsettlementPnL } = inputs;\n\n  return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\n/**\n * @formulaId availableBalanceForIsolatedMargin\n * @name Available Balance for Isolated Margin\n * @formula availableBalanceForIsolatedMargin = max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0)))\n * @description\n *\n * ## Definition\n *\n * max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0))), where\n *\n * **USDC_balance** = User's USDC balance\n *\n * **free_collateral** = Available collateral in the user's account (for cross margin trading)\n *\n * **total_cross_unsettled_pnl**  = sum( unsettled_PNL_i ) across all cross margin positions\n */\nexport function availableBalanceForIsolatedMargin(inputs: {\n  USDCHolding: number;\n  totalCrossUnsettledPnL: number;\n  freeCollateral: number;\n}): number {\n  return Math.max(\n    0,\n    Math.min(\n      inputs.USDCHolding,\n      new Decimal(inputs.freeCollateral)\n        .sub(Math.max(inputs.totalCrossUnsettledPnL, 0))\n        .toNumber(),\n    ),\n  );\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId mmr\n * @name Total Maintenance Margin Ratio\n * @formula Total Maintenance Margin Ratio = sum(Position maintenance margin) / total_position_notional * 100%, total_position_notional = sum(abs(position_qty_i * mark_price_i))\n * @description\n *\n * ## Definition\n *\n * **Total Maintenance Margin Ratio** = User's account maintenance margin ratio\n *\n * **sum(Position maintenance margin)** = Total maintenance margin of all user positions (denominated in USDC)\n *\n * **total_position_notional** = Sum of notional value of current positions\n *\n * **position_qty_i** = Position quantity for a single symbol\n *\n * **mark_price_i** = Mark price for a single symbol\n *\n * ## Example\n *\n * ```\n * Total Margin Ratio = 505.61 / 10112.43 * 100% = 4.99988628%\n * total_position_notional = 10112.43\n * abs(BTC position notional) = 5197.2\n * abs(ETH position notional) = 4915.23\n * sum(Position maintenance margin) = 505.61\n * BTC position MM = 259.86\n * ETH position MM = 245.75\n * ```\n *\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: {\n  // Total Maintenance Margin of all positions of the user (USDC)\n  positionsMMR: number;\n  /**\n   * Notional sum of all positions,\n   * positions.totalNotional()\n   */\n  positionsNotional: number;\n}): number | null {\n  // If the user does not have any positions, return null\n  if (inputs.positionsNotional === 0) {\n    return null;\n  }\n  if (inputs.positionsMMR === 0) {\n    return null;\n  }\n  return new Decimal(inputs.positionsMMR)\n    .div(inputs.positionsNotional)\n    .toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\nexport const collateralRatio = (params: {\n  baseWeight: number;\n  discountFactor: number | null;\n  collateralQty: number;\n  collateralCap: number;\n  indexPrice: number;\n}) => {\n  const {\n    baseWeight,\n    discountFactor,\n    collateralQty,\n    collateralCap,\n    indexPrice,\n  } = params;\n\n  // if collateralCap is -1, it means the collateral is unlimited\n  const cap = collateralCap === -1 ? collateralQty : collateralCap;\n\n  const K = new Decimal(1.2);\n  const DCF = new Decimal(discountFactor || 0);\n  const qty = new Decimal(Math.min(collateralQty, cap));\n\n  const notionalAbs = qty.mul(indexPrice).abs();\n  const dynamicWeight = DCF.mul(notionalAbs.toPower(IMRFactorPower));\n  const result = K.div(new Decimal(1).add(dynamicWeight));\n\n  return result.lt(baseWeight) ? result : new Decimal(baseWeight);\n};\n\n/** collateral_value_i = min(collateral_qty_i , collateral_cap_i) * weight_i * index_price_i */\nexport const collateralContribution = (params: {\n  collateralQty: number;\n  collateralCap: number;\n  collateralRatio: number;\n  indexPrice: number;\n}) => {\n  const { collateralQty, collateralCap, collateralRatio, indexPrice } = params;\n\n  // if collateralCap is -1, it means the collateral is unlimited\n  const cap = collateralCap === -1 ? collateralQty : collateralCap;\n\n  return new Decimal(Math.min(collateralQty, cap))\n    .mul(collateralRatio)\n    .mul(indexPrice)\n    .toNumber();\n};\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport const LTV = (params: {\n  usdcBalance: number;\n  upnl: number;\n  assets: Array<{ qty: number; indexPrice: number; weight: number }>;\n}) => {\n  const { usdcBalance, upnl, assets } = params;\n\n  const usdcLoss = new Decimal(Math.min(usdcBalance, 0)).abs();\n  const upnlLoss = new Decimal(Math.min(upnl, 0)).abs();\n  const numerator = usdcLoss.add(upnlLoss);\n\n  const collateralSum = assets.reduce<Decimal>((acc, asset) => {\n    return acc.add(\n      new Decimal(Math.max(asset.qty, 0))\n        .mul(new Decimal(asset.indexPrice))\n        .mul(new Decimal(asset.weight)),\n    );\n  }, zero);\n\n  const denominator = collateralSum.add(new Decimal(Math.max(upnl, 0)));\n\n  if (numerator.isZero() || denominator.isZero()) {\n    return 0;\n  }\n\n  return numerator.div(denominator).toNumber();\n};\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * max(0, min(USDC_balance, free_collateral - max(upnl, 0)))\n */\nexport const maxWithdrawalUSDC = (inputs: {\n  USDCBalance: number;\n  freeCollateral: Decimal;\n  upnl: number;\n}) => {\n  const { USDCBalance, freeCollateral, upnl } = inputs;\n  const value = Math.min(\n    new Decimal(USDCBalance).toNumber(),\n    new Decimal(freeCollateral).sub(Math.max(upnl, 0)).toNumber(),\n  );\n  return Math.max(0, value);\n};\n\n/**\n *\n * Other collateral: min(collateral_qty_i, free_collateral / (index_price_i × weight_i)\n * Other collateral with negative USDC: min(collateral_qty_i, free_collateral / (index_price_i × (1 + buffer) × weight_i)\n * buffer: 0.2%\n */\nexport const maxWithdrawalOtherCollateral = (inputs: {\n  USDCBalance: number;\n  collateralQty: number;\n  freeCollateral: Decimal;\n  indexPrice: number;\n  weight: Decimal;\n}) => {\n  const { USDCBalance, collateralQty, freeCollateral, indexPrice, weight } =\n    inputs;\n  const usdcBalance = new Decimal(USDCBalance);\n  const denominator = usdcBalance.isNegative()\n    ? new Decimal(indexPrice).mul(weight).mul(new Decimal(1).add(0.002))\n    : new Decimal(indexPrice).mul(weight);\n  if (denominator.isZero()) {\n    return zero;\n  }\n  const qty = new Decimal(collateralQty);\n  const maxQtyByValue = new Decimal(freeCollateral).div(denominator);\n  return maxQtyByValue.lt(qty) ? maxQtyByValue : qty;\n};\n\nexport const calcMinimumReceived = (inputs: {\n  amount: number;\n  slippage: number;\n}) => {\n  const { amount, slippage } = inputs;\n  const slippageRatio = new Decimal(slippage).div(100);\n  return new Decimal(amount)\n    .mul(new Decimal(1).minus(slippageRatio))\n    .toNumber();\n};\n","import { availableBalanceForIsolatedMargin } from \"./availableBalance\";\n\n/**\n * @formulaId maxAdd\n * @name Maximum Margin Addition for Isolated Position\n * @formula max_add = max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0)))\n * @description\n *\n * ## Definition\n *\n * **max_add**: Maximum amount of margin that can be added to an isolated margin position\n *\n * **USDC_balance**: User's USDC balance\n *\n * **free_collateral**: Available collateral in the user's account (for cross margin trading)\n *\n * **total_cross_unsettled_pnl**: Total unsettled PNL from cross margin positions only\n *\n * ## Business Rules\n *\n * - Maximum add amount cannot exceed available USDC balance\n * - Maximum add amount cannot exceed free collateral minus cross margin unrealized profit\n * - Cross margin unrealized profit reduces available funds for adding isolated margin\n *\n * ## Example\n *\n * ```\n * USDC_balance = 500\n * free_collateral = 300\n * total_cross_unsettled_pnl = 100 (profit)\n * max_add = max(0, min(500, 300 - max(100, 0))) = max(0, min(500, 200)) = 200\n * ```\n *\n * @param inputs Input parameters for calculating maximum margin addition\n * @returns Maximum margin that can be added (in USDC)\n */\nexport function maxAdd(inputs: {\n  /**\n   * @description USDC balance\n   */\n  USDCHolding: number;\n  /**\n   * @description Free collateral (available for cross margin trading)\n   */\n  freeCollateral: number;\n  /**\n   * @description Total cross margin unsettled PNL\n   */\n  totalCrossUnsettledPnL: number;\n}): number {\n  return availableBalanceForIsolatedMargin(inputs);\n}\n\n/**\n * @formulaId maxReduce\n * @name Maximum Margin Reduction for Isolated Position\n * @formula max_reduce = max(0, isolated_position_margin - position_notional * imr + min(0, position_unsettled_pnl))\n * @description\n *\n * ## Definition\n *\n * **max_reduce**: Maximum amount of margin that can be reduced from an isolated margin position\n *\n * **isolated_position_margin**: Current margin allocated to the isolated position\n *\n * **position_notional**: Notional value of the isolated position\n *\n * **imr**: Initial margin rate for the isolated position\n *\n * **position_unsettled_pnl**: Unrealized PNL of the isolated position\n *\n * ## Business Rules\n *\n * - Maximum reduce amount cannot exceed current isolated position margin\n * - Unrealized losses increase the maximum reducible amount\n * - Position notional and IMR determine the minimum required margin\n *\n * ## Example\n *\n * ```\n * isolated_position_margin = 1000\n * position_notional = 5000\n * imr = 0.02\n * position_unsettled_pnl = -100 (loss)\n * max_reduce = max(0, 1000 - 5000 * 0.02 + min(0, -100)) = max(0, 1000 - 100 - 100) = 800\n * ```\n *\n * @param inputs Input parameters for calculating maximum margin reduction\n * @returns Maximum margin that can be reduced (in USDC)\n */\nexport function maxReduce(inputs: {\n  /**\n   * @description Current margin allocated to the isolated position\n   */\n  isolatedPositionMargin: number;\n  /**\n   * @description Notional value of the isolated position\n   */\n  positionNotional: number;\n  /**\n   * @description Initial margin rate for the isolated position\n   */\n  imr: number;\n  /**\n   * @description Unrealized PNL of the isolated position\n   */\n  positionUnsettledPnL: number;\n}): number {\n  const {\n    isolatedPositionMargin,\n    positionNotional,\n    imr,\n    positionUnsettledPnL,\n  } = inputs;\n\n  const minRequiredMargin = positionNotional * imr;\n  const pnlAdjustment = Math.min(0, positionUnsettledPnL);\n\n  return Math.max(\n    0,\n    isolatedPositionMargin - minRequiredMargin + pnlAdjustment,\n  );\n}\n","import {\n  OrderSide,\n  OrderType,\n  API as orderUtils,\n} from \"@orderly.network/types\";\nimport { Decimal, getTPSLDirection, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower, IsoTakerFeeBuffer } from \"./constants\";\n\n// ============ Backward Compatibility Types ============\n/** @deprecated Use inline type or the new input type instead */\nexport type EstimatedLiquidationPriceInputs = {\n  totalCollateral: number;\n  markPrice: number;\n  baseMMR: number;\n  baseIMR: number;\n  IMR_Factor: number;\n  orderFee: number;\n  positions: Pick<\n    orderUtils.PositionExt,\n    \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n  >[];\n  newOrder: {\n    symbol: string;\n    qty: number;\n    price: number;\n  };\n};\n\n/** @deprecated Use inline type or the new input type instead */\nexport type EstimatedLeverageInputs = {\n  totalCollateral: number;\n  positions: Pick<\n    orderUtils.PositionExt,\n    \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n  >[];\n  newOrder: {\n    symbol: string;\n    qty: number;\n    price: number;\n  };\n};\n// ====================================================\n\n/**\n * Maximum price when placing an order\n */\nexport function maxPrice(markprice: number, range: number) {\n  return markprice * (1 + range);\n}\n\n/**\n * Minimum price when placing an order\n */\nexport function minPrice(markprice: number, range: number) {\n  return markprice * (1 - range);\n}\n\n/**\n * Scope price when placing an order\n * @returns number\n */\nexport function scopePrice(\n  price: number,\n  scope: number,\n  side: \"BUY\" | \"SELL\",\n): number {\n  if (side === \"BUY\") {\n    return price * (1 - scope);\n  }\n  return price * (1 + scope);\n}\n\n/**\n * Calculate the order fee\n */\nexport function orderFee(inputs: {\n  /**\n   * Order quantity\n   */\n  qty: number;\n  price: number;\n  futuresTakeFeeRate: number;\n}): number {\n  return new Decimal(inputs.qty)\n    .mul(inputs.price)\n    .mul(inputs.futuresTakeFeeRate)\n    .toNumber();\n}\n\n/**\n * Calculate reference price for a **new order** based on business rules.\n *\n * The reference price is used by risk / margin formulas as the effective\n * execution price when the user is preparing a new order.\n *\n * Business rules (simplified):\n *\n * - LIMIT\n *   - BUY:   `reference = limit_price`\n *   - SELL:  `reference = max(limit_price, Bid1)`\n *   - If `limit_price` is not provided: same as MARKET\n *\n * - MARKET\n *   - BUY:   `reference = Ask1`\n *   - SELL:  `reference = Bid1`\n *\n * - STOP MARKET\n *   - If `stop_price` provided: `reference = stop_price`\n *   - Else: same as MARKET\n *\n * - STOP LIMIT\n *   - If `limit_price` provided: `reference = limit_price`\n *   - Else: same as MARKET\n *\n * - TRAILING STOP\n *   - If `trigger_price` provided: `reference = trigger_price`\n *   - Else: same as MARKET\n *\n * - BBO (LIMIT with ASK / BID as `orderTypeExt`)\n *   - BUY + ASK  => `reference = Ask1`\n *   - SELL + BID => `reference = Bid1`\n *   - BUY + BID  => `reference = Bid1`\n *   - SELL + ASK => `reference = Ask1`\n *\n * @param order     Lightweight description of the new order\n * @param askPrice  Ask1 price from orderbook\n * @param bidPrice  Bid1 price from orderbook\n * @returns Reference price or null if it cannot be determined\n */\nexport function getOrderReferencePrice(\n  order: {\n    /**\n     * @description Order type (e.g. LIMIT, MARKET, STOP_LIMIT, STOP_MARKET, TRAILING_STOP, ASK, BID)\n     */\n    orderType: OrderType;\n    /**\n     * @description Extended order type for BBO orders (ASK / BID as LIMIT extensions)\n     */\n    orderTypeExt?: OrderType;\n    /**\n     * @description Order side (BUY or SELL)\n     */\n    side: OrderSide;\n    /**\n     * @description User input LIMIT price (for LIMIT / STOP_LIMIT orders)\n     */\n    limitPrice?: number;\n    /**\n     * @description Trigger price (for STOP_MARKET / STOP_LIMIT / TRAILING_STOP orders)\n     */\n    triggerPrice?: number;\n  },\n  askPrice: number,\n  bidPrice: number,\n): number | null {\n  /**\n   * Helper: get MARKET-style reference price using best bid/ask.\n   */\n  const getMarketRefPrice = (): number | null => {\n    if (order.side === OrderSide.BUY) {\n      return askPrice > 0 ? askPrice : null;\n    }\n    return bidPrice > 0 ? bidPrice : null;\n  };\n\n  const isValidPrice = (price?: number): price is number =>\n    typeof price === \"number\" && Number.isFinite(price) && price > 0;\n\n  const { orderType, orderTypeExt, side } = order;\n  const limitPrice = isValidPrice(order.limitPrice)\n    ? order.limitPrice\n    : undefined;\n  const triggerPrice = isValidPrice(order.triggerPrice)\n    ? order.triggerPrice\n    : undefined;\n\n  // ---- BBO orders (LIMIT + ASK/BID extension) ----\n  if (\n    orderType === OrderType.LIMIT &&\n    (orderTypeExt === OrderType.ASK || orderTypeExt === OrderType.BID)\n  ) {\n    // BID / ASK reference rules\n    if (side === OrderSide.BUY) {\n      // BUY ASK / BUY BID\n      return orderTypeExt === OrderType.ASK\n        ? isValidPrice(askPrice)\n          ? askPrice\n          : null\n        : isValidPrice(bidPrice)\n          ? bidPrice\n          : null;\n    }\n\n    // SELL ASK / SELL BID\n    return orderTypeExt === OrderType.ASK\n      ? isValidPrice(askPrice)\n        ? askPrice\n        : null\n      : isValidPrice(bidPrice)\n        ? bidPrice\n        : null;\n  }\n\n  switch (orderType) {\n    case OrderType.LIMIT:\n    case OrderType.IOC:\n    case OrderType.FOK:\n    case OrderType.POST_ONLY: {\n      // LIMIT-family orders follow the same reference rules\n      if (!limitPrice) {\n        // No limit price yet -> behave as MARKET order\n        return getMarketRefPrice();\n      }\n\n      if (side === OrderSide.BUY) {\n        // LIMIT BUY: reference = limit price\n        return limitPrice;\n      }\n\n      // LIMIT SELL: reference = max(limit_price, Bid1)\n      const effectiveBid = isValidPrice(bidPrice) ? bidPrice : 0;\n      return Math.max(limitPrice, effectiveBid);\n    }\n\n    case OrderType.MARKET: {\n      return getMarketRefPrice();\n    }\n\n    case OrderType.STOP_MARKET: {\n      if (triggerPrice) {\n        // STOP price explicitly provided\n        return triggerPrice;\n      }\n      // Same as MARKET when stop price not provided\n      return getMarketRefPrice();\n    }\n\n    case OrderType.STOP_LIMIT: {\n      if (limitPrice) {\n        // Use LIMIT price for both BUY / SELL\n        return limitPrice;\n      }\n      // Same as MARKET when limit price not provided\n      return getMarketRefPrice();\n    }\n\n    case OrderType.TRAILING_STOP: {\n      if (triggerPrice) {\n        return triggerPrice;\n      }\n      // Fallback: behave as MARKET when trigger not defined yet\n      return getMarketRefPrice();\n    }\n\n    default:\n      // For unsupported order types we do not guess a reference price\n      return null;\n  }\n}\n\n/**\n * @formulaId estLiqPriceIsolated\n * @name Est. Position liq. Price (Isolated Margin)\n * @description\n * Estimate the liquidation price for an isolated-margin position after placing a new order.\n *\n * The underlying formula is:\n *\n * \\[\n * liquidation\\_price =\n * \\frac{\n *   isolated\\_position\\_margin' - cost\\_position' - funding\\_adjustment\n * }{\n *   |position\\_qty'| \\cdot MMR' - position\\_qty'\n * }\n * \\]\n *\n * Where:\n * - `position_qty' = positionQty + orderSide * orderQty`\n * - `funding_adjustment = position_qty' * (sumUnitaryFunding - lastSumUnitaryFunding)`\n * - `MMR' = max(baseMMR, (baseMMR / baseIMR) * IMR_Factor * abs(position_qty' * reference_price)^(4/5))`\n *\n * Notes:\n * - This function only considers a **single isolated position** (no cross-margin collateral or other symbols).\n * - `newOrder.qty > 0` is treated as a BUY, `newOrder.qty < 0` as a SELL.\n *\n * @param inputs Estimation inputs for isolated-margin liquidation price\n * @returns Estimated liquidation price (in quote currency), or 0 when invalid / no position\n */\nexport function estLiqPriceIsolated(inputs: {\n  /**\n   * @description Current isolated margin of the position\n   */\n  isolatedPositionMargin: number;\n  /**\n   * @description Current position cost (qty * average entry price)\n   */\n  costPosition: number;\n  /**\n   * @description Current position quantity (positive for long, negative for short)\n   */\n  positionQty: number;\n  /**\n   * @description Current cumulative unitary funding\n   */\n  sumUnitaryFunding: number;\n  /**\n   * @description Last cumulative unitary funding at the last settlement\n   */\n  lastSumUnitaryFunding: number;\n  /**\n   * @description Current mark price of the symbol\n   */\n  markPrice: number;\n  /**\n   * @description Base maintenance margin rate\n   */\n  baseMMR: number;\n  /**\n   * @description Base initial margin rate\n   */\n  baseIMR: number;\n  /**\n   * @description IMR calculation factor\n   */\n  IMR_Factor: number;\n  /**\n   * @description Leverage for this isolated position\n   */\n  leverage: number;\n  /**\n   * @description Fee buffer reserved in isolated margin estimates (default: 0.0006)\n   */\n  isoTakerFeeBuffer?: number;\n  /**\n   * @description New order information used for estimation\n   */\n  newOrder: {\n    /**\n     * @description Symbol of the order (kept for interface consistency)\n     */\n    symbol: string;\n    /**\n     * @description Order quantity (positive for BUY, negative for SELL)\n     */\n    qty: number;\n    /**\n     * @description Order price (reference price when opening / adding / flipping)\n     */\n    price: number;\n  };\n}): number {\n  const {\n    isolatedPositionMargin,\n    costPosition,\n    positionQty,\n    sumUnitaryFunding,\n    lastSumUnitaryFunding,\n    markPrice,\n    baseMMR,\n    baseIMR,\n    IMR_Factor: IMRFactor,\n    leverage,\n    isoTakerFeeBuffer = IsoTakerFeeBuffer,\n    newOrder,\n  } = inputs;\n\n  // newOrder.qty is signed: positive for BUY, negative for SELL\n  const signedOrderQty = newOrder?.qty ?? 0;\n\n  // Calculate new position quantity after order execution\n  const newPositionQty = positionQty + signedOrderQty;\n\n  // No position after order execution - cannot compute liquidation price\n  if (newPositionQty === 0) {\n    return 0;\n  }\n\n  // Reference price for margin/cost calculations\n  const orderRefPrice = newOrder?.price ?? markPrice;\n\n  // Validate reference prices\n  if (markPrice <= 0 || (signedOrderQty !== 0 && orderRefPrice <= 0)) {\n    return 0;\n  }\n\n  // Helper: check if two values have the same sign (both positive or both negative)\n  const isSameSign = (a: number, b: number) =>\n    (a > 0 && b > 0) || (a < 0 && b < 0);\n\n  // Determine order scenario based on position and order relationship\n  type OrderScenario = \"NO_ORDER\" | \"OPEN_ADD\" | \"REDUCE\" | \"FLIP\";\n  const getScenario = (): OrderScenario => {\n    if (signedOrderQty === 0) return \"NO_ORDER\";\n    if (positionQty === 0 || isSameSign(signedOrderQty, positionQty))\n      return \"OPEN_ADD\";\n    if (isSameSign(positionQty, newPositionQty)) return \"REDUCE\";\n    return \"FLIP\";\n  };\n\n  // Pre-compute Decimal instances to avoid redundant allocations\n  const decNewPositionQty = new Decimal(newPositionQty);\n  const decAbsNewPositionQty = decNewPositionQty.abs();\n  const decCostPosition = new Decimal(costPosition);\n  const decIsolatedMargin = new Decimal(isolatedPositionMargin);\n  const decOrderCost = new Decimal(signedOrderQty).mul(orderRefPrice);\n  const getMarginRate = () =>\n    new Decimal(1).div(leverage).add(isoTakerFeeBuffer);\n\n  // Calculate isolated_position_margin' and cost_position' based on scenario\n  let newIsolatedPositionMargin: Decimal;\n  let newCostPosition: Decimal;\n\n  switch (getScenario()) {\n    case \"NO_ORDER\":\n      // Use current values unchanged\n      newIsolatedPositionMargin = decIsolatedMargin;\n      newCostPosition = decCostPosition;\n      break;\n\n    case \"OPEN_ADD\":\n      // Add margin based on order notional with isolated fee buffer.\n      newIsolatedPositionMargin = decIsolatedMargin.add(\n        new Decimal(Math.abs(signedOrderQty))\n          .mul(orderRefPrice)\n          .mul(getMarginRate()),\n      );\n      newCostPosition = decCostPosition.add(decOrderCost);\n      break;\n\n    case \"REDUCE\":\n      // Margin proportionally reduced based on remaining position ratio\n      newIsolatedPositionMargin = decIsolatedMargin\n        .mul(newPositionQty)\n        .div(positionQty);\n      newCostPosition = decCostPosition.add(decOrderCost);\n      break;\n\n    case \"FLIP\":\n      // Completely new position in opposite direction\n      newIsolatedPositionMargin = decAbsNewPositionQty\n        .mul(orderRefPrice)\n        .mul(getMarginRate());\n      newCostPosition = decNewPositionQty.mul(orderRefPrice);\n      break;\n  }\n\n  // Calculate funding adjustment: position_qty' * (sumUnitaryFunding - lastSumUnitaryFunding)\n  const fundingAdjustment = decNewPositionQty.mul(\n    new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding),\n  );\n\n  // Calculate MMR' based on new position notional (using mark price for MMR calculation)\n  const newPositionNotional = decAbsNewPositionQty.mul(markPrice);\n  const dynamicMMR = new Decimal(baseMMR)\n    .div(baseIMR)\n    .mul(IMRFactor)\n    .mul(newPositionNotional.toPower(IMRFactorPower))\n    .toNumber();\n  const newMMR = Math.max(baseMMR, dynamicMMR);\n\n  // Calculate denominator: abs(position_qty') * MMR' - position_qty'\n  const denominator = decAbsNewPositionQty.mul(newMMR).sub(decNewPositionQty);\n\n  if (denominator.isZero()) {\n    return 0;\n  }\n\n  // Calculate liquidation price: (margin' - cost' - funding) / denominator\n  const liquidationPrice = newIsolatedPositionMargin\n    .sub(newCostPosition)\n    .sub(fundingAdjustment)\n    .div(denominator)\n    .toNumber();\n\n  return Math.max(0, liquidationPrice);\n}\n\n/**\n * @formulaId estLiqPrice\n * @name Est. Position liq. Price\n * @description\n *\n * ## When user has positions:\n *\n * ```\n * Est. liq. Position Price = max(mark_price_i + (total_collateral_value - new_total_MM - order_fee) / (abs(position_qty_i + new_order_qty_i) * new_MMRi - (position_qty_i + new_order_qty_i)), 0)\n * ```\n *\n * ## When user has no positions:\n *\n * ```\n * Est. liq. Position Price = max(order_price_i + (total_collateral_value - new_total_MM - order_fee) / (abs(position_qty_i + new_order_qty_i) * new_MMRi - (position_qty_i + new_order_qty_i)), 0)\n * ```\n *\n * ## Formula Components:\n *\n * - `order_fee = new_order_qty_i * order_price_i * futures_take_fee_rate`\n * - `new_total_MM = sum(abs(position_qty_i * mark_price_i + new_order_qty_i * order_price_i)) * MMRi)`\n * - `new_MMRi = Max(Base_MMR_i, (Base_MMR_i / Base_IMR_i) * IMR_Factor_i * Abs(position_qty_i * mark_price_i + new_order_qty_i * limit_price_i)^(4/5))`\n *\n * ## Order Price Determination:\n *\n * ### Market Order:\n * - **Long order**: `order_price_i = ask0`\n * - **Short order**: `order_price_i = bid0`\n *\n * ### Limit Order:\n *\n * #### Long order:\n * - If `limit_price >= ask0`: `order_price_i = ask0`\n * - If `limit_price < ask0`: `order_price_i = limit_price`\n *\n * #### Short order:\n * - If `limit_price <= bid0`: `order_price_i = bid0`\n * - If `limit_price > bid0`: `order_price_i = limit_price`\n *\n * ## Parameter Definitions:\n *\n * | Parameter | Description |\n * |-----------|-------------|\n * | `Est. Position liq. Price` | Estimated liquidation price for the position |\n * | `position_qty_i` | Position quantity for a single symbol |\n * | `mark_price_i` | Mark price for a single symbol |\n * | `total_collateral_value` | Total asset value of user's account margin (USDC denominated) |\n * | `new_order_qty_i` | Symbol quantity when user prepares to open position (positive for long, negative for short) |\n * | `new_total_MM` | Sum of current position maintenance margin (including prepared order maintenance margin) |\n * | `new_MMR_i` | Maintenance margin rate for a single symbol (including prepared order notional consideration) |\n * | `Base_MMR_i` | Base maintenance margin rate for a single symbol |\n * | `Base_IMR_i` | Base initial margin rate for a single symbol |\n * | `IMR_Factor_i` | IMR calculation factor for a single symbol, from v1/client/info |\n * | `Position_Notional_i` | Sum of position notional for a single symbol |\n * | `order_fee` | Estimated order fee when user prepares to open position |\n * | `futures_take_fee_rate` | User's futures take fee rate, from GET /v1/client/info |\n * | `order_price_i` | Estimated execution price when user prepares to open position |\n * | `limit_price` | Price entered by user when preparing to open position |\n * | `ask0` | Minimum ask price from orderbook |\n * | `bid0` | Maximum bid price from orderbook |\n *\n * ## Examples:\n *\n * ### Market Order Example:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n * futures_take_fee_rate = 0.06%\n *\n * **Result**: BTC Est. Position liq. Price = 21268.7316\n *\n * ### Limit Order Example 1:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, limit price = 25000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n *\n * **Result**: BTC Est. Position liq. Price = 21250.9772\n *\n * ### Limit Order Example 2:\n * Short BTC qty = -0.1, mark price = 25986.2, bid0 = 25900, limit price = 25000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n *\n * **Result**: BTC Est. Position liq. Price = 9102.17368\n *\n * ### No Position Example:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, limit price = 25000\n *\n * **Result**: BTC Est. Position liq. Price = 5472\n *\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: {\n  totalCollateral: number;\n  markPrice: number;\n  baseMMR: number;\n  baseIMR: number;\n  IMR_Factor: number;\n  orderFee: number;\n  positions: {\n    position_qty: number;\n    mark_price: number;\n    symbol: string;\n    mmr: number;\n  }[];\n  newOrder: {\n    symbol: string;\n    qty: number;\n    price: number;\n  };\n}): number {\n  const {\n    positions,\n    newOrder,\n    totalCollateral,\n    markPrice,\n    baseIMR,\n    baseMMR,\n    orderFee,\n    IMR_Factor,\n  } = inputs;\n  // opened positions for the symbol\n  let currentPosition:\n    | Pick<\n        orderUtils.PositionExt,\n        \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n      >\n    | undefined = undefined;\n\n  let newTotalMM = zero;\n\n  const hasPosition =\n    positions.filter((item) => item.position_qty > 0).length > 0;\n\n  const basePrice = hasPosition ? markPrice : newOrder.price;\n\n  const newOrderNotional = new Decimal(newOrder.qty).mul(newOrder.price);\n\n  for (let index = 0; index < positions.length; index++) {\n    const position = positions[index];\n    let notional = new Decimal(position.position_qty).mul(position.mark_price);\n    if (newOrder.symbol === position.symbol) {\n      currentPosition = position;\n      notional = notional.add(newOrderNotional);\n    }\n\n    newTotalMM = newTotalMM.add(notional.abs().mul(position.mmr));\n  }\n\n  // if no position\n  if (!currentPosition) {\n    newTotalMM = newTotalMM.add(newOrderNotional.mul(baseMMR));\n  }\n\n  const newMMR = Math.max(\n    baseMMR,\n    new Decimal(baseMMR)\n      .div(baseIMR)\n      .mul(IMR_Factor)\n      .mul(\n        newOrderNotional\n          .add(\n            !!currentPosition\n              ? new Decimal(currentPosition.position_qty).mul(\n                  currentPosition.mark_price,\n                )\n              : zero,\n          )\n          .abs(),\n      )\n      .toPower(4 / 5)\n      .toNumber(),\n  );\n\n  // console.log(\"new MMR\", newMMR, newTotalMM.toNumber());\n\n  const newQty = new Decimal(newOrder.qty).add(\n    currentPosition?.position_qty ?? 0,\n  );\n\n  if (newQty.eq(0)) {\n    return 0;\n  }\n\n  const denominator = newQty.abs().mul(newMMR).sub(newQty);\n\n  if (denominator.eq(zero)) {\n    return 0;\n  }\n\n  const price = new Decimal(basePrice)\n    .add(\n      new Decimal(totalCollateral)\n        .sub(newTotalMM)\n        .sub(orderFee)\n        .div(denominator),\n    )\n    .toNumber();\n\n  return Math.max(0, price);\n}\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: {\n  totalCollateral: number;\n  positions: Pick<\n    orderUtils.PositionExt,\n    \"position_qty\" | \"mark_price\" | \"symbol\"\n  >[];\n  newOrder: {\n    symbol: string;\n    qty: number;\n    price: number;\n  };\n}): number | null {\n  const { totalCollateral, positions, newOrder } = inputs;\n  if (totalCollateral <= 0) {\n    return null;\n  }\n  let hasPosition = false;\n  let sumPositionNotional = positions.reduce((acc, cur) => {\n    let count = new Decimal(cur.position_qty).mul(cur.mark_price);\n    // acc = acc.add(\n    //   new Decimal(cur.position_qty).mul(cur.mark_price)\n    //   // .abs()\n    // );\n\n    if (cur.symbol === newOrder.symbol) {\n      hasPosition = true;\n      // acc = acc.add(new Decimal(newOrder.qty).mul(newOrder.price));\n      count = count.add(new Decimal(newOrder.qty).mul(newOrder.price));\n    }\n\n    return acc.add(count.abs());\n  }, zero);\n\n  if (!hasPosition) {\n    sumPositionNotional = sumPositionNotional.add(\n      new Decimal(newOrder.qty).mul(newOrder.price).abs(),\n    );\n  }\n\n  if (sumPositionNotional.eq(zero)) {\n    return null;\n  }\n\n  const totalMarginRatio = new Decimal(totalCollateral).div(\n    sumPositionNotional,\n  );\n\n  return new Decimal(1)\n    .div(totalMarginRatio)\n    .toDecimalPlaces(2, Decimal.ROUND_HALF_EVEN)\n    .toNumber();\n}\n\n// ROI = (close price - order_price) / order_price × leverage × direction\n// leverage = MIN( current_account_leverage, symbol_leverage)\nexport function tpslROI(inputs: {\n  side: OrderSide;\n  type: \"tp\" | \"sl\";\n  closePrice: number;\n  orderPrice: number;\n  leverage: number;\n}) {\n  const direction = getTPSLDirection({\n    side: inputs.side,\n    type: inputs.type,\n    closePrice: inputs.closePrice,\n    orderPrice: inputs.orderPrice,\n  });\n\n  const { closePrice, orderPrice, leverage } = inputs;\n  return new Decimal(closePrice)\n    .minus(orderPrice)\n    .div(orderPrice)\n    .mul(leverage)\n    .abs()\n    .mul(direction)\n    .toNumber();\n}\n"]}