@kodiak-finance/orderly-perp 4.8.18 → 4.8.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -583,6 +583,13 @@ type EstimatedLeverageInputs = {
583
583
  * @returns number
584
584
  */
585
585
  declare function estLeverage(inputs: EstimatedLeverageInputs): number | null;
586
+ declare function tpslROI(inputs: {
587
+ side: OrderSide;
588
+ type: "tp" | "sl";
589
+ closePrice: number;
590
+ orderPrice: number;
591
+ leverage: number;
592
+ }): number;
586
593
 
587
594
  type order_EstimatedLeverageInputs = EstimatedLeverageInputs;
588
595
  type order_EstimatedLiquidationPriceInputs = EstimatedLiquidationPriceInputs;
@@ -592,8 +599,9 @@ declare const order_maxPrice: typeof maxPrice;
592
599
  declare const order_minPrice: typeof minPrice;
593
600
  declare const order_orderFee: typeof orderFee;
594
601
  declare const order_scopePrice: typeof scopePrice;
602
+ declare const order_tpslROI: typeof tpslROI;
595
603
  declare namespace order {
596
- export { type order_EstimatedLeverageInputs as EstimatedLeverageInputs, type order_EstimatedLiquidationPriceInputs as EstimatedLiquidationPriceInputs, order_estLeverage as estLeverage, order_estLiqPrice as estLiqPrice, order_maxPrice as maxPrice, order_minPrice as minPrice, order_orderFee as orderFee, order_scopePrice as scopePrice };
604
+ export { type order_EstimatedLeverageInputs as EstimatedLeverageInputs, type order_EstimatedLiquidationPriceInputs as EstimatedLiquidationPriceInputs, order_estLeverage as estLeverage, order_estLiqPrice as estLiqPrice, order_maxPrice as maxPrice, order_minPrice as minPrice, order_orderFee as orderFee, order_scopePrice as scopePrice, order_tpslROI as tpslROI };
597
605
  }
598
606
 
599
607
  export { account, order, order as orderUtils, positions, _default as version };
package/dist/index.d.ts CHANGED
@@ -583,6 +583,13 @@ type EstimatedLeverageInputs = {
583
583
  * @returns number
584
584
  */
585
585
  declare function estLeverage(inputs: EstimatedLeverageInputs): number | null;
586
+ declare function tpslROI(inputs: {
587
+ side: OrderSide;
588
+ type: "tp" | "sl";
589
+ closePrice: number;
590
+ orderPrice: number;
591
+ leverage: number;
592
+ }): number;
586
593
 
587
594
  type order_EstimatedLeverageInputs = EstimatedLeverageInputs;
588
595
  type order_EstimatedLiquidationPriceInputs = EstimatedLiquidationPriceInputs;
@@ -592,8 +599,9 @@ declare const order_maxPrice: typeof maxPrice;
592
599
  declare const order_minPrice: typeof minPrice;
593
600
  declare const order_orderFee: typeof orderFee;
594
601
  declare const order_scopePrice: typeof scopePrice;
602
+ declare const order_tpslROI: typeof tpslROI;
595
603
  declare namespace order {
596
- export { type order_EstimatedLeverageInputs as EstimatedLeverageInputs, type order_EstimatedLiquidationPriceInputs as EstimatedLiquidationPriceInputs, order_estLeverage as estLeverage, order_estLiqPrice as estLiqPrice, order_maxPrice as maxPrice, order_minPrice as minPrice, order_orderFee as orderFee, order_scopePrice as scopePrice };
604
+ export { type order_EstimatedLeverageInputs as EstimatedLeverageInputs, type order_EstimatedLiquidationPriceInputs as EstimatedLiquidationPriceInputs, order_estLeverage as estLeverage, order_estLiqPrice as estLiqPrice, order_maxPrice as maxPrice, order_minPrice as minPrice, order_orderFee as orderFee, order_scopePrice as scopePrice, order_tpslROI as tpslROI };
597
605
  }
598
606
 
599
607
  export { account, order, order as orderUtils, positions, _default as version };
package/dist/index.js CHANGED
@@ -410,7 +410,7 @@ function otherIMs(inputs) {
410
410
  const sellOrdersQty = position.pending_short_qty;
411
411
  const ordersNotional = markPriceDecimal.mul(new import_orderly_utils2.Decimal(buyOrdersQty).add(sellOrdersQty)).toNumber();
412
412
  const IMR_Factor = IMR_Factors[symbol];
413
- if (!IMR_Factor) {
413
+ if (typeof IMR_Factor === "undefined") {
414
414
  console.warn("IMR_Factor is not found:", symbol);
415
415
  return acc;
416
416
  }
@@ -466,6 +466,9 @@ function maxQtyByLong(inputs, options) {
466
466
  if (positionQty === 0 && buyOrdersQty === 0) {
467
467
  return Math.min(baseMaxQty, factor_1);
468
468
  }
469
+ if (IMR_Factor === 0) {
470
+ return Math.min(baseMaxQty, factor_1);
471
+ }
469
472
  const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).sub(
470
473
  new import_orderly_utils2.Decimal(positionQty).add(buyOrdersQty)
471
474
  // .abs()
@@ -498,6 +501,9 @@ function maxQtyByShort(inputs, options) {
498
501
  if (positionQty === 0 && sellOrdersQty === 0) {
499
502
  return Math.min(baseMaxQty, factor_1);
500
503
  }
504
+ if (IMR_Factor === 0) {
505
+ return Math.min(baseMaxQty, factor_1);
506
+ }
501
507
  const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).add(positionQty).sub(sellOrdersQty).div(new import_orderly_utils2.Decimal(takerFeeRate).mul(2).mul(1e-4).add(1)).mul(0.995).toNumber();
502
508
  return Math.min(baseMaxQty, factor_1, factor_2);
503
509
  } catch (error) {
@@ -555,7 +561,7 @@ var collateralRatio = (params) => {
555
561
  const DCF = new import_orderly_utils2.Decimal(discountFactor || 0);
556
562
  const qty = new import_orderly_utils2.Decimal(Math.min(collateralQty, cap));
557
563
  const notionalAbs = qty.mul(indexPrice).abs();
558
- const dynamicWeight = DCF.mul(notionalAbs).toPower(IMRFactorPower);
564
+ const dynamicWeight = DCF.mul(notionalAbs.toPower(IMRFactorPower));
559
565
  const result = K.div(new import_orderly_utils2.Decimal(1).add(dynamicWeight));
560
566
  return result.lt(baseWeight) ? result : new import_orderly_utils2.Decimal(baseWeight);
561
567
  };
@@ -617,7 +623,8 @@ __export(order_exports, {
617
623
  maxPrice: () => maxPrice,
618
624
  minPrice: () => minPrice,
619
625
  orderFee: () => orderFee,
620
- scopePrice: () => scopePrice
626
+ scopePrice: () => scopePrice,
627
+ tpslROI: () => tpslROI
621
628
  });
622
629
  var import_orderly_utils3 = require("@kodiak-finance/orderly-utils");
623
630
  function maxPrice(markprice, range) {
@@ -716,6 +723,16 @@ function estLeverage(inputs) {
716
723
  );
717
724
  return new import_orderly_utils3.Decimal(1).div(totalMarginRatio2).toDecimalPlaces(2, import_orderly_utils3.Decimal.ROUND_HALF_EVEN).toNumber();
718
725
  }
726
+ function tpslROI(inputs) {
727
+ const direction = (0, import_orderly_utils3.getTPSLDirection)({
728
+ side: inputs.side,
729
+ type: inputs.type,
730
+ closePrice: inputs.closePrice,
731
+ orderPrice: inputs.orderPrice
732
+ });
733
+ const { closePrice, orderPrice, leverage } = inputs;
734
+ return new import_orderly_utils3.Decimal(closePrice).minus(orderPrice).div(orderPrice).mul(leverage).abs().mul(direction).toNumber();
735
+ }
719
736
  // Annotate the CommonJS export names for ESM import in node:
720
737
  0 && (module.exports = {
721
738
  account,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/version.ts","../src/positions.ts","../src/constants.ts","../src/account.ts","../src/order.ts"],"sourcesContent":["export { default as version } from \"./version\";\nexport * as positions from \"./positions\";\nexport * as account from \"./account\";\nexport * as orderUtils from \"./order\";\n\nexport * as order from \"./order\";\n","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__[\"@kodiak-finance/orderly-perp\"] = \"4.7.4\";\n}\n\nexport default \"4.7.4\";\n","import { API } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\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 * Calculates the total notional value of all positions.\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\nexport type UnrealPnLInputs = {\n markPrice: number;\n openPrice: number;\n qty: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of a single position.\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position.\n */\nexport function unrealizedPnL(inputs: UnrealPnLInputs): number {\n return new Decimal(inputs.qty)\n .mul(inputs.markPrice - inputs.openPrice)\n .toNumber();\n}\n\nexport type UnrealPnLROIInputs = {\n positionQty: number;\n openPrice: number;\n IMR: number;\n unrealizedPnL: number;\n};\n\n/**\n * Calculates the return on investment (ROI) of a single position's unrealized profit or loss.\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: UnrealPnLROIInputs): 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 * Calculates the total unrealized profit or loss of all positions.\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\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 * Calculates the liquidation price of a single position.\n * @param inputs The inputs for calculating the liquidation price.\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: LiqPriceInputs): number | null {\n const { markPrice, totalCollateral, positions, positionQty, MMR } = inputs;\n\n // console.log(\"inputs\", inputs);\n\n if (positionQty === 0 || totalCollateral === 0) {\n return null;\n }\n\n // totalNotional of all poisitions\n const totalNotional = positions.reduce<Decimal>((acc, cur) => {\n return acc.add(\n new Decimal(notional(cur.position_qty, cur.mark_price)).mul(cur.mmr),\n );\n }, zero);\n\n return Math.max(\n new Decimal(markPrice)\n .add(\n new Decimal(totalCollateral)\n .sub(totalNotional)\n .div(new Decimal(positionQty).abs().mul(MMR).sub(positionQty)),\n )\n .toNumber(),\n 0,\n );\n}\n\nexport type MMInputs = {\n positionQty: number;\n markPrice: number;\n MMR: number;\n};\n\n/**\n * Calculates the maintenance margin of a position.\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: MMInputs) {\n const { positionQty, markPrice, MMR } = inputs;\n\n return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n\nexport type UnsettlementPnLInputs = {\n positionQty: number;\n markPrice: number;\n costPosition: number;\n sumUnitaryFunding: number;\n lastSumUnitaryFunding: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of each position.\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: UnsettlementPnLInputs): 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\nexport type TotalUnsettlementPnLInputs = {\n positions: (API.Position & {\n sum_unitary_funding: number;\n })[];\n sumUnitaryFunding: number;\n};\n\n/**\n * Calculates the total unrealized profit or loss of all positions.\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\nexport type MMRInputs = {\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n positionNotional: number;\n IMR_factor_power: number;\n};\n\n/**\n * Calculates the maintenance margin requirement (MMR) of a position.\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: MMRInputs): 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\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 */\nexport function estPriceForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n pnl: number;\n}): number {\n return new Decimal(inputs.pnl)\n .add(inputs.entryPrice)\n .div(inputs.positionQty)\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\n/**\n * calculate the max position notional\n * 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","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n","import { API, OrderSide } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\n\nexport type ResultOptions = {\n dp: number;\n};\n\nexport type TotalValueInputs = {\n totalUnsettlementPnL: number;\n\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n};\n\n/**\n * User's total asset value (denominated in USDC), including assets that cannot be used as collateral.\n */\nexport function totalValue(inputs: TotalValueInputs): Decimal {\n const { totalUnsettlementPnL, USDCHolding, nonUSDCHolding } = inputs;\n const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n }, zero);\n return nonUSDCHoldingValue.add(USDCHolding).add(totalUnsettlementPnL);\n}\n\n/**\n * Total value of available collateral in the user's account (denominated in USDC).\n */\nexport type FreeCollateralInputs = {\n // Total collateral\n totalCollateral: Decimal;\n // Total initial margin with orders\n totalInitialMarginWithOrders: number;\n};\n/**\n * Calculate free collateral.\n */\nexport function freeCollateral(inputs: FreeCollateralInputs): 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\nexport type TotalCollateralValueInputs = {\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n unsettlementPnL: number;\n};\n\n/**\n * Calculate total collateral.\n */\nexport function totalCollateral(inputs: TotalCollateralValueInputs): Decimal {\n const { USDCHolding, nonUSDCHolding, unsettlementPnL } = inputs;\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 return new Decimal(USDCHolding).add(nonUSDCHoldingValue).add(unsettlementPnL);\n}\n\nexport function initialMarginWithOrder() {}\n\nexport type PositionNotionalWithOrderInputs = {\n markPrice: number;\n positionQtyWithOrders: number;\n};\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(\n inputs: PositionNotionalWithOrderInputs,\n): Decimal {\n return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\nexport type PositionQtyWithOrderInputs = {\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};\n/**\n * Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(\n inputs: PositionQtyWithOrderInputs,\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\nexport type IMRInputs = {\n /**\n * effective max leverage\n */\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n};\n\n/**\n * Initial margin rate for a symbol.\n * Max(1 / Max Account Leverage, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: IMRInputs): 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\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\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\nexport type TotalInitialMarginWithOrdersInputs = {\n positions: API.Position[];\n orders: API.Order[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n} & Pick<IMRInputs, \"maxLeverage\">;\n\n/**\n * @deprecated\n * Calculate the total initial margin used by the user (including positions and orders).\n */\nexport function totalInitialMarginWithOrders(\n inputs: TotalInitialMarginWithOrdersInputs,\n): number {\n const {\n positions,\n orders,\n markPrices,\n IMR_Factors,\n maxLeverage,\n symbolInfo,\n } = inputs;\n\n const symbols = extractSymbols(positions, orders);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const positionQty = getQtyFromPositions(positions, symbol);\n const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n const sellOrdersQty = getQtyFromOrdersBySide(\n orders,\n symbol,\n OrderSide.SELL,\n );\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage,\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\n\nexport function totalInitialMarginWithQty(inputs: {\n positions: API.Position[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n}) {\n const { positions, markPrices, IMR_Factors, symbolInfo } = inputs;\n const symbols = positions.map((item) => item.symbol);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const position = positions.find((item) => item.symbol === symbol);\n const positionQty = position?.position_qty || 0;\n\n const buyOrdersQty = position?.pending_long_qty || 0;\n const sellOrdersQty = position?.pending_short_qty || 0;\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage: maxLeverage({\n symbolLeverage: position?.leverage ?? inputs.maxLeverage,\n accountLeverage: inputs.maxLeverage,\n }),\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\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\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\nexport type OtherIMsInputs = {\n // the position list for other symbols except the current symbol\n positions: API.Position[];\n markPrices: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n};\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: OtherIMsInputs): 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 if (!IMR_Factor) {\n console.warn(\"IMR_Factor is not found:\", symbol);\n return acc;\n }\n\n const imr = IMR({\n maxLeverage: maxLeverage({\n symbolLeverage: position!.leverage,\n accountLeverage: inputs.maxLeverage,\n }),\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\nexport type MaxQtyInputs = {\n symbol: string;\n\n // Maximum quantity limit for opening a single position, /v1/public/info.base_max\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 * Maximum order quantity.\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 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 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\nexport type TotalMarginRatioInputs = {\n totalCollateral: number;\n markPrices: { [key: string]: number };\n positions: API.Position[];\n};\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n inputs: TotalMarginRatioInputs,\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\nexport type TotalUnrealizedROIInputs = {\n totalUnrealizedPnL: number;\n totalValue: number;\n};\n\n/**\n * totalUnrealizedROI\n */\nexport function totalUnrealizedROI(inputs: TotalUnrealizedROIInputs) {\n const { totalUnrealizedPnL, totalValue } = inputs;\n\n return new Decimal(totalUnrealizedPnL)\n .div(totalValue - totalUnrealizedPnL)\n .toNumber();\n}\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\nexport type AvailableBalanceInputs = {\n USDCHolding: number;\n unsettlementPnL: number;\n};\nexport function availableBalance(inputs: AvailableBalanceInputs) {\n const { USDCHolding, unsettlementPnL } = inputs;\n\n return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\nexport type AccountMMRInputs = {\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};\n\n/**\n * total maintenance margin ratio\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: AccountMMRInputs): 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\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\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\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\n/**\n * @deprecated This method will be removed soon. Please update your code to use symbolLeverage directly.\n */\n// Warning: The maxLeverage method will be deprecated soon. Please use symbolLeverage directly and update all related calls as soon as possible.\nexport const maxLeverage = (inputs: {\n symbolLeverage?: number;\n accountLeverage: number;\n}) => {\n const { symbolLeverage, accountLeverage } = inputs;\n\n return symbolLeverage ?? 1;\n};\n","import { API as orderUtils } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { notional } from \"./positions\";\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\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/**\n * Estimated liquidation price\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: EstimatedLiquidationPriceInputs): 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\nexport type EstimatedLeverageInputs = {\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};\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: EstimatedLeverageInputs): 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"],"mappings":"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","names":["IMR","totalCollateral","MMR","totalNotional","notional","MMR","import_orderly_utils","totalUnsettlementPnL","unsettlementPnL","maxLeverage","totalCollateral","otherIMs","totalUnrealizedPnL","totalValue","totalMarginRatio","MMR","collateralRatio","freeCollateral","import_orderly_utils","totalCollateral","orderFee","notional","totalMarginRatio"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/version.ts","../src/positions.ts","../src/constants.ts","../src/account.ts","../src/order.ts"],"sourcesContent":["export { default as version } from \"./version\";\nexport * as positions from \"./positions\";\nexport * as account from \"./account\";\nexport * as orderUtils from \"./order\";\n\nexport * as order from \"./order\";\n","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__[\"@kodiak-finance/orderly-perp\"] = \"4.7.4\";\n}\n\nexport default \"4.7.4\";\n","import { API } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\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 * Calculates the total notional value of all positions.\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\nexport type UnrealPnLInputs = {\n markPrice: number;\n openPrice: number;\n qty: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of a single position.\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position.\n */\nexport function unrealizedPnL(inputs: UnrealPnLInputs): number {\n return new Decimal(inputs.qty)\n .mul(inputs.markPrice - inputs.openPrice)\n .toNumber();\n}\n\nexport type UnrealPnLROIInputs = {\n positionQty: number;\n openPrice: number;\n IMR: number;\n unrealizedPnL: number;\n};\n\n/**\n * Calculates the return on investment (ROI) of a single position's unrealized profit or loss.\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: UnrealPnLROIInputs): 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 * Calculates the total unrealized profit or loss of all positions.\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\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 * Calculates the liquidation price of a single position.\n * @param inputs The inputs for calculating the liquidation price.\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: LiqPriceInputs): number | null {\n const { markPrice, totalCollateral, positions, positionQty, MMR } = inputs;\n\n // console.log(\"inputs\", inputs);\n\n if (positionQty === 0 || totalCollateral === 0) {\n return null;\n }\n\n // totalNotional of all poisitions\n const totalNotional = positions.reduce<Decimal>((acc, cur) => {\n return acc.add(\n new Decimal(notional(cur.position_qty, cur.mark_price)).mul(cur.mmr),\n );\n }, zero);\n\n return Math.max(\n new Decimal(markPrice)\n .add(\n new Decimal(totalCollateral)\n .sub(totalNotional)\n .div(new Decimal(positionQty).abs().mul(MMR).sub(positionQty)),\n )\n .toNumber(),\n 0,\n );\n}\n\nexport type MMInputs = {\n positionQty: number;\n markPrice: number;\n MMR: number;\n};\n\n/**\n * Calculates the maintenance margin of a position.\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: MMInputs) {\n const { positionQty, markPrice, MMR } = inputs;\n\n return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n\nexport type UnsettlementPnLInputs = {\n positionQty: number;\n markPrice: number;\n costPosition: number;\n sumUnitaryFunding: number;\n lastSumUnitaryFunding: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of each position.\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: UnsettlementPnLInputs): 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\nexport type TotalUnsettlementPnLInputs = {\n positions: (API.Position & {\n sum_unitary_funding: number;\n })[];\n sumUnitaryFunding: number;\n};\n\n/**\n * Calculates the total unrealized profit or loss of all positions.\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\nexport type MMRInputs = {\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n positionNotional: number;\n IMR_factor_power: number;\n};\n\n/**\n * Calculates the maintenance margin requirement (MMR) of a position.\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: MMRInputs): 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\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 */\nexport function estPriceForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n pnl: number;\n}): number {\n return new Decimal(inputs.pnl)\n .add(inputs.entryPrice)\n .div(inputs.positionQty)\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\n/**\n * calculate the max position notional\n * 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","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n","import { API, OrderSide } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\n\nexport type ResultOptions = {\n dp: number;\n};\n\nexport type TotalValueInputs = {\n totalUnsettlementPnL: number;\n\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n};\n\n/**\n * User's total asset value (denominated in USDC), including assets that cannot be used as collateral.\n */\nexport function totalValue(inputs: TotalValueInputs): Decimal {\n const { totalUnsettlementPnL, USDCHolding, nonUSDCHolding } = inputs;\n const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n }, zero);\n return nonUSDCHoldingValue.add(USDCHolding).add(totalUnsettlementPnL);\n}\n\n/**\n * Total value of available collateral in the user's account (denominated in USDC).\n */\nexport type FreeCollateralInputs = {\n // Total collateral\n totalCollateral: Decimal;\n // Total initial margin with orders\n totalInitialMarginWithOrders: number;\n};\n/**\n * Calculate free collateral.\n */\nexport function freeCollateral(inputs: FreeCollateralInputs): 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\nexport type TotalCollateralValueInputs = {\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n unsettlementPnL: number;\n};\n\n/**\n * Calculate total collateral.\n */\nexport function totalCollateral(inputs: TotalCollateralValueInputs): Decimal {\n const { USDCHolding, nonUSDCHolding, unsettlementPnL } = inputs;\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 return new Decimal(USDCHolding).add(nonUSDCHoldingValue).add(unsettlementPnL);\n}\n\nexport function initialMarginWithOrder() {}\n\nexport type PositionNotionalWithOrderInputs = {\n markPrice: number;\n positionQtyWithOrders: number;\n};\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(\n inputs: PositionNotionalWithOrderInputs,\n): Decimal {\n return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\nexport type PositionQtyWithOrderInputs = {\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};\n/**\n * Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(\n inputs: PositionQtyWithOrderInputs,\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\nexport type IMRInputs = {\n /**\n * effective max leverage\n */\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n};\n\n/**\n * Initial margin rate for a symbol.\n * Max(1 / Max Account Leverage, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: IMRInputs): 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\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\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\nexport type TotalInitialMarginWithOrdersInputs = {\n positions: API.Position[];\n orders: API.Order[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n} & Pick<IMRInputs, \"maxLeverage\">;\n\n/**\n * @deprecated\n * Calculate the total initial margin used by the user (including positions and orders).\n */\nexport function totalInitialMarginWithOrders(\n inputs: TotalInitialMarginWithOrdersInputs,\n): number {\n const {\n positions,\n orders,\n markPrices,\n IMR_Factors,\n maxLeverage,\n symbolInfo,\n } = inputs;\n\n const symbols = extractSymbols(positions, orders);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const positionQty = getQtyFromPositions(positions, symbol);\n const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n const sellOrdersQty = getQtyFromOrdersBySide(\n orders,\n symbol,\n OrderSide.SELL,\n );\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage,\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\n\nexport function totalInitialMarginWithQty(inputs: {\n positions: API.Position[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n}) {\n const { positions, markPrices, IMR_Factors, symbolInfo } = inputs;\n const symbols = positions.map((item) => item.symbol);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const position = positions.find((item) => item.symbol === symbol);\n const positionQty = position?.position_qty || 0;\n\n const buyOrdersQty = position?.pending_long_qty || 0;\n const sellOrdersQty = position?.pending_short_qty || 0;\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage: maxLeverage({\n symbolLeverage: position?.leverage ?? inputs.maxLeverage,\n accountLeverage: inputs.maxLeverage,\n }),\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\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\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\nexport type OtherIMsInputs = {\n // the position list for other symbols except the current symbol\n positions: API.Position[];\n markPrices: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n};\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: OtherIMsInputs): 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 maxLeverage: maxLeverage({\n symbolLeverage: position!.leverage,\n accountLeverage: inputs.maxLeverage,\n }),\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\nexport type MaxQtyInputs = {\n symbol: string;\n\n // Maximum quantity limit for opening a single position, /v1/public/info.base_max\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 * Maximum order quantity.\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\nexport type TotalMarginRatioInputs = {\n totalCollateral: number;\n markPrices: { [key: string]: number };\n positions: API.Position[];\n};\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n inputs: TotalMarginRatioInputs,\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\nexport type TotalUnrealizedROIInputs = {\n totalUnrealizedPnL: number;\n totalValue: number;\n};\n\n/**\n * totalUnrealizedROI\n */\nexport function totalUnrealizedROI(inputs: TotalUnrealizedROIInputs) {\n const { totalUnrealizedPnL, totalValue } = inputs;\n\n return new Decimal(totalUnrealizedPnL)\n .div(totalValue - totalUnrealizedPnL)\n .toNumber();\n}\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\nexport type AvailableBalanceInputs = {\n USDCHolding: number;\n unsettlementPnL: number;\n};\nexport function availableBalance(inputs: AvailableBalanceInputs) {\n const { USDCHolding, unsettlementPnL } = inputs;\n\n return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\nexport type AccountMMRInputs = {\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};\n\n/**\n * total maintenance margin ratio\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: AccountMMRInputs): 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\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\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\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\n/**\n * @deprecated This method will be removed soon. Please update your code to use symbolLeverage directly.\n */\n// Warning: The maxLeverage method will be deprecated soon. Please use symbolLeverage directly and update all related calls as soon as possible.\nexport const maxLeverage = (inputs: {\n symbolLeverage?: number;\n accountLeverage: number;\n}) => {\n const { symbolLeverage, accountLeverage } = inputs;\n\n return symbolLeverage ?? 1;\n};\n","import { OrderSide, API as orderUtils } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, getTPSLDirection, zero } from \"@kodiak-finance/orderly-utils\";\nimport { notional } from \"./positions\";\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\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/**\n * Estimated liquidation price\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: EstimatedLiquidationPriceInputs): 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\nexport type EstimatedLeverageInputs = {\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};\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: EstimatedLeverageInputs): 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"],"mappings":"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","names":["IMR","totalCollateral","MMR","totalNotional","notional","MMR","import_orderly_utils","totalUnsettlementPnL","unsettlementPnL","maxLeverage","totalCollateral","otherIMs","totalUnrealizedPnL","totalValue","totalMarginRatio","MMR","collateralRatio","freeCollateral","import_orderly_utils","totalCollateral","orderFee","notional","totalMarginRatio"]}
package/dist/index.mjs CHANGED
@@ -386,7 +386,7 @@ function otherIMs(inputs) {
386
386
  const sellOrdersQty = position.pending_short_qty;
387
387
  const ordersNotional = markPriceDecimal.mul(new Decimal2(buyOrdersQty).add(sellOrdersQty)).toNumber();
388
388
  const IMR_Factor = IMR_Factors[symbol];
389
- if (!IMR_Factor) {
389
+ if (typeof IMR_Factor === "undefined") {
390
390
  console.warn("IMR_Factor is not found:", symbol);
391
391
  return acc;
392
392
  }
@@ -442,6 +442,9 @@ function maxQtyByLong(inputs, options) {
442
442
  if (positionQty === 0 && buyOrdersQty === 0) {
443
443
  return Math.min(baseMaxQty, factor_1);
444
444
  }
445
+ if (IMR_Factor === 0) {
446
+ return Math.min(baseMaxQty, factor_1);
447
+ }
445
448
  const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).sub(
446
449
  new Decimal2(positionQty).add(buyOrdersQty)
447
450
  // .abs()
@@ -474,6 +477,9 @@ function maxQtyByShort(inputs, options) {
474
477
  if (positionQty === 0 && sellOrdersQty === 0) {
475
478
  return Math.min(baseMaxQty, factor_1);
476
479
  }
480
+ if (IMR_Factor === 0) {
481
+ return Math.min(baseMaxQty, factor_1);
482
+ }
477
483
  const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).add(positionQty).sub(sellOrdersQty).div(new Decimal2(takerFeeRate).mul(2).mul(1e-4).add(1)).mul(0.995).toNumber();
478
484
  return Math.min(baseMaxQty, factor_1, factor_2);
479
485
  } catch (error) {
@@ -531,7 +537,7 @@ var collateralRatio = (params) => {
531
537
  const DCF = new Decimal2(discountFactor || 0);
532
538
  const qty = new Decimal2(Math.min(collateralQty, cap));
533
539
  const notionalAbs = qty.mul(indexPrice).abs();
534
- const dynamicWeight = DCF.mul(notionalAbs).toPower(IMRFactorPower);
540
+ const dynamicWeight = DCF.mul(notionalAbs.toPower(IMRFactorPower));
535
541
  const result = K.div(new Decimal2(1).add(dynamicWeight));
536
542
  return result.lt(baseWeight) ? result : new Decimal2(baseWeight);
537
543
  };
@@ -593,9 +599,10 @@ __export(order_exports, {
593
599
  maxPrice: () => maxPrice,
594
600
  minPrice: () => minPrice,
595
601
  orderFee: () => orderFee,
596
- scopePrice: () => scopePrice
602
+ scopePrice: () => scopePrice,
603
+ tpslROI: () => tpslROI
597
604
  });
598
- import { Decimal as Decimal3, zero as zero3 } from "@kodiak-finance/orderly-utils";
605
+ import { Decimal as Decimal3, getTPSLDirection, zero as zero3 } from "@kodiak-finance/orderly-utils";
599
606
  function maxPrice(markprice, range) {
600
607
  return markprice * (1 + range);
601
608
  }
@@ -692,6 +699,16 @@ function estLeverage(inputs) {
692
699
  );
693
700
  return new Decimal3(1).div(totalMarginRatio2).toDecimalPlaces(2, Decimal3.ROUND_HALF_EVEN).toNumber();
694
701
  }
702
+ function tpslROI(inputs) {
703
+ const direction = getTPSLDirection({
704
+ side: inputs.side,
705
+ type: inputs.type,
706
+ closePrice: inputs.closePrice,
707
+ orderPrice: inputs.orderPrice
708
+ });
709
+ const { closePrice, orderPrice, leverage } = inputs;
710
+ return new Decimal3(closePrice).minus(orderPrice).div(orderPrice).mul(leverage).abs().mul(direction).toNumber();
711
+ }
695
712
  export {
696
713
  account_exports as account,
697
714
  order_exports as order,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts","../src/positions.ts","../src/constants.ts","../src/account.ts","../src/order.ts"],"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__[\"@kodiak-finance/orderly-perp\"] = \"4.7.4\";\n}\n\nexport default \"4.7.4\";\n","import { API } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\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 * Calculates the total notional value of all positions.\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\nexport type UnrealPnLInputs = {\n markPrice: number;\n openPrice: number;\n qty: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of a single position.\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position.\n */\nexport function unrealizedPnL(inputs: UnrealPnLInputs): number {\n return new Decimal(inputs.qty)\n .mul(inputs.markPrice - inputs.openPrice)\n .toNumber();\n}\n\nexport type UnrealPnLROIInputs = {\n positionQty: number;\n openPrice: number;\n IMR: number;\n unrealizedPnL: number;\n};\n\n/**\n * Calculates the return on investment (ROI) of a single position's unrealized profit or loss.\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: UnrealPnLROIInputs): 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 * Calculates the total unrealized profit or loss of all positions.\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\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 * Calculates the liquidation price of a single position.\n * @param inputs The inputs for calculating the liquidation price.\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: LiqPriceInputs): number | null {\n const { markPrice, totalCollateral, positions, positionQty, MMR } = inputs;\n\n // console.log(\"inputs\", inputs);\n\n if (positionQty === 0 || totalCollateral === 0) {\n return null;\n }\n\n // totalNotional of all poisitions\n const totalNotional = positions.reduce<Decimal>((acc, cur) => {\n return acc.add(\n new Decimal(notional(cur.position_qty, cur.mark_price)).mul(cur.mmr),\n );\n }, zero);\n\n return Math.max(\n new Decimal(markPrice)\n .add(\n new Decimal(totalCollateral)\n .sub(totalNotional)\n .div(new Decimal(positionQty).abs().mul(MMR).sub(positionQty)),\n )\n .toNumber(),\n 0,\n );\n}\n\nexport type MMInputs = {\n positionQty: number;\n markPrice: number;\n MMR: number;\n};\n\n/**\n * Calculates the maintenance margin of a position.\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: MMInputs) {\n const { positionQty, markPrice, MMR } = inputs;\n\n return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n\nexport type UnsettlementPnLInputs = {\n positionQty: number;\n markPrice: number;\n costPosition: number;\n sumUnitaryFunding: number;\n lastSumUnitaryFunding: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of each position.\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: UnsettlementPnLInputs): 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\nexport type TotalUnsettlementPnLInputs = {\n positions: (API.Position & {\n sum_unitary_funding: number;\n })[];\n sumUnitaryFunding: number;\n};\n\n/**\n * Calculates the total unrealized profit or loss of all positions.\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\nexport type MMRInputs = {\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n positionNotional: number;\n IMR_factor_power: number;\n};\n\n/**\n * Calculates the maintenance margin requirement (MMR) of a position.\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: MMRInputs): 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\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 */\nexport function estPriceForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n pnl: number;\n}): number {\n return new Decimal(inputs.pnl)\n .add(inputs.entryPrice)\n .div(inputs.positionQty)\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\n/**\n * calculate the max position notional\n * 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","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n","import { API, OrderSide } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\n\nexport type ResultOptions = {\n dp: number;\n};\n\nexport type TotalValueInputs = {\n totalUnsettlementPnL: number;\n\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n};\n\n/**\n * User's total asset value (denominated in USDC), including assets that cannot be used as collateral.\n */\nexport function totalValue(inputs: TotalValueInputs): Decimal {\n const { totalUnsettlementPnL, USDCHolding, nonUSDCHolding } = inputs;\n const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n }, zero);\n return nonUSDCHoldingValue.add(USDCHolding).add(totalUnsettlementPnL);\n}\n\n/**\n * Total value of available collateral in the user's account (denominated in USDC).\n */\nexport type FreeCollateralInputs = {\n // Total collateral\n totalCollateral: Decimal;\n // Total initial margin with orders\n totalInitialMarginWithOrders: number;\n};\n/**\n * Calculate free collateral.\n */\nexport function freeCollateral(inputs: FreeCollateralInputs): 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\nexport type TotalCollateralValueInputs = {\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n unsettlementPnL: number;\n};\n\n/**\n * Calculate total collateral.\n */\nexport function totalCollateral(inputs: TotalCollateralValueInputs): Decimal {\n const { USDCHolding, nonUSDCHolding, unsettlementPnL } = inputs;\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 return new Decimal(USDCHolding).add(nonUSDCHoldingValue).add(unsettlementPnL);\n}\n\nexport function initialMarginWithOrder() {}\n\nexport type PositionNotionalWithOrderInputs = {\n markPrice: number;\n positionQtyWithOrders: number;\n};\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(\n inputs: PositionNotionalWithOrderInputs,\n): Decimal {\n return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\nexport type PositionQtyWithOrderInputs = {\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};\n/**\n * Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(\n inputs: PositionQtyWithOrderInputs,\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\nexport type IMRInputs = {\n /**\n * effective max leverage\n */\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n};\n\n/**\n * Initial margin rate for a symbol.\n * Max(1 / Max Account Leverage, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: IMRInputs): 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\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\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\nexport type TotalInitialMarginWithOrdersInputs = {\n positions: API.Position[];\n orders: API.Order[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n} & Pick<IMRInputs, \"maxLeverage\">;\n\n/**\n * @deprecated\n * Calculate the total initial margin used by the user (including positions and orders).\n */\nexport function totalInitialMarginWithOrders(\n inputs: TotalInitialMarginWithOrdersInputs,\n): number {\n const {\n positions,\n orders,\n markPrices,\n IMR_Factors,\n maxLeverage,\n symbolInfo,\n } = inputs;\n\n const symbols = extractSymbols(positions, orders);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const positionQty = getQtyFromPositions(positions, symbol);\n const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n const sellOrdersQty = getQtyFromOrdersBySide(\n orders,\n symbol,\n OrderSide.SELL,\n );\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage,\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\n\nexport function totalInitialMarginWithQty(inputs: {\n positions: API.Position[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n}) {\n const { positions, markPrices, IMR_Factors, symbolInfo } = inputs;\n const symbols = positions.map((item) => item.symbol);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const position = positions.find((item) => item.symbol === symbol);\n const positionQty = position?.position_qty || 0;\n\n const buyOrdersQty = position?.pending_long_qty || 0;\n const sellOrdersQty = position?.pending_short_qty || 0;\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage: maxLeverage({\n symbolLeverage: position?.leverage ?? inputs.maxLeverage,\n accountLeverage: inputs.maxLeverage,\n }),\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\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\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\nexport type OtherIMsInputs = {\n // the position list for other symbols except the current symbol\n positions: API.Position[];\n markPrices: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n};\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: OtherIMsInputs): 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 if (!IMR_Factor) {\n console.warn(\"IMR_Factor is not found:\", symbol);\n return acc;\n }\n\n const imr = IMR({\n maxLeverage: maxLeverage({\n symbolLeverage: position!.leverage,\n accountLeverage: inputs.maxLeverage,\n }),\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\nexport type MaxQtyInputs = {\n symbol: string;\n\n // Maximum quantity limit for opening a single position, /v1/public/info.base_max\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 * Maximum order quantity.\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 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 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\nexport type TotalMarginRatioInputs = {\n totalCollateral: number;\n markPrices: { [key: string]: number };\n positions: API.Position[];\n};\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n inputs: TotalMarginRatioInputs,\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\nexport type TotalUnrealizedROIInputs = {\n totalUnrealizedPnL: number;\n totalValue: number;\n};\n\n/**\n * totalUnrealizedROI\n */\nexport function totalUnrealizedROI(inputs: TotalUnrealizedROIInputs) {\n const { totalUnrealizedPnL, totalValue } = inputs;\n\n return new Decimal(totalUnrealizedPnL)\n .div(totalValue - totalUnrealizedPnL)\n .toNumber();\n}\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\nexport type AvailableBalanceInputs = {\n USDCHolding: number;\n unsettlementPnL: number;\n};\nexport function availableBalance(inputs: AvailableBalanceInputs) {\n const { USDCHolding, unsettlementPnL } = inputs;\n\n return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\nexport type AccountMMRInputs = {\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};\n\n/**\n * total maintenance margin ratio\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: AccountMMRInputs): 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\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\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\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\n/**\n * @deprecated This method will be removed soon. Please update your code to use symbolLeverage directly.\n */\n// Warning: The maxLeverage method will be deprecated soon. Please use symbolLeverage directly and update all related calls as soon as possible.\nexport const maxLeverage = (inputs: {\n symbolLeverage?: number;\n accountLeverage: number;\n}) => {\n const { symbolLeverage, accountLeverage } = inputs;\n\n return symbolLeverage ?? 1;\n};\n","import { API as orderUtils } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { notional } from \"./positions\";\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\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/**\n * Estimated liquidation price\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: EstimatedLiquidationPriceInputs): 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\nexport type EstimatedLeverageInputs = {\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};\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: EstimatedLeverageInputs): 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"],"mappings":"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","names":["IMR","totalCollateral","MMR","totalNotional","notional","MMR","Decimal","zero","totalUnsettlementPnL","Decimal","zero","unsettlementPnL","maxLeverage","totalCollateral","otherIMs","totalUnrealizedPnL","totalValue","totalMarginRatio","MMR","collateralRatio","freeCollateral","Decimal","zero","totalCollateral","orderFee","notional","totalMarginRatio"]}
1
+ {"version":3,"sources":["../src/version.ts","../src/positions.ts","../src/constants.ts","../src/account.ts","../src/order.ts"],"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__[\"@kodiak-finance/orderly-perp\"] = \"4.7.4\";\n}\n\nexport default \"4.7.4\";\n","import { API } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\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 * Calculates the total notional value of all positions.\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\nexport type UnrealPnLInputs = {\n markPrice: number;\n openPrice: number;\n qty: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of a single position.\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position.\n */\nexport function unrealizedPnL(inputs: UnrealPnLInputs): number {\n return new Decimal(inputs.qty)\n .mul(inputs.markPrice - inputs.openPrice)\n .toNumber();\n}\n\nexport type UnrealPnLROIInputs = {\n positionQty: number;\n openPrice: number;\n IMR: number;\n unrealizedPnL: number;\n};\n\n/**\n * Calculates the return on investment (ROI) of a single position's unrealized profit or loss.\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: UnrealPnLROIInputs): 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 * Calculates the total unrealized profit or loss of all positions.\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\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 * Calculates the liquidation price of a single position.\n * @param inputs The inputs for calculating the liquidation price.\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: LiqPriceInputs): number | null {\n const { markPrice, totalCollateral, positions, positionQty, MMR } = inputs;\n\n // console.log(\"inputs\", inputs);\n\n if (positionQty === 0 || totalCollateral === 0) {\n return null;\n }\n\n // totalNotional of all poisitions\n const totalNotional = positions.reduce<Decimal>((acc, cur) => {\n return acc.add(\n new Decimal(notional(cur.position_qty, cur.mark_price)).mul(cur.mmr),\n );\n }, zero);\n\n return Math.max(\n new Decimal(markPrice)\n .add(\n new Decimal(totalCollateral)\n .sub(totalNotional)\n .div(new Decimal(positionQty).abs().mul(MMR).sub(positionQty)),\n )\n .toNumber(),\n 0,\n );\n}\n\nexport type MMInputs = {\n positionQty: number;\n markPrice: number;\n MMR: number;\n};\n\n/**\n * Calculates the maintenance margin of a position.\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: MMInputs) {\n const { positionQty, markPrice, MMR } = inputs;\n\n return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n\nexport type UnsettlementPnLInputs = {\n positionQty: number;\n markPrice: number;\n costPosition: number;\n sumUnitaryFunding: number;\n lastSumUnitaryFunding: number;\n};\n\n/**\n * Calculates the unrealized profit or loss of each position.\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: UnsettlementPnLInputs): 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\nexport type TotalUnsettlementPnLInputs = {\n positions: (API.Position & {\n sum_unitary_funding: number;\n })[];\n sumUnitaryFunding: number;\n};\n\n/**\n * Calculates the total unrealized profit or loss of all positions.\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\nexport type MMRInputs = {\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n positionNotional: number;\n IMR_factor_power: number;\n};\n\n/**\n * Calculates the maintenance margin requirement (MMR) of a position.\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: MMRInputs): 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\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 */\nexport function estPriceForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n pnl: number;\n}): number {\n return new Decimal(inputs.pnl)\n .add(inputs.entryPrice)\n .div(inputs.positionQty)\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\n/**\n * calculate the max position notional\n * 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","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n","import { API, OrderSide } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, zero } from \"@kodiak-finance/orderly-utils\";\nimport { IMRFactorPower } from \"./constants\";\n\nexport type ResultOptions = {\n dp: number;\n};\n\nexport type TotalValueInputs = {\n totalUnsettlementPnL: number;\n\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n};\n\n/**\n * User's total asset value (denominated in USDC), including assets that cannot be used as collateral.\n */\nexport function totalValue(inputs: TotalValueInputs): Decimal {\n const { totalUnsettlementPnL, USDCHolding, nonUSDCHolding } = inputs;\n const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n }, zero);\n return nonUSDCHoldingValue.add(USDCHolding).add(totalUnsettlementPnL);\n}\n\n/**\n * Total value of available collateral in the user's account (denominated in USDC).\n */\nexport type FreeCollateralInputs = {\n // Total collateral\n totalCollateral: Decimal;\n // Total initial margin with orders\n totalInitialMarginWithOrders: number;\n};\n/**\n * Calculate free collateral.\n */\nexport function freeCollateral(inputs: FreeCollateralInputs): 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\nexport type TotalCollateralValueInputs = {\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n unsettlementPnL: number;\n};\n\n/**\n * Calculate total collateral.\n */\nexport function totalCollateral(inputs: TotalCollateralValueInputs): Decimal {\n const { USDCHolding, nonUSDCHolding, unsettlementPnL } = inputs;\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 return new Decimal(USDCHolding).add(nonUSDCHoldingValue).add(unsettlementPnL);\n}\n\nexport function initialMarginWithOrder() {}\n\nexport type PositionNotionalWithOrderInputs = {\n markPrice: number;\n positionQtyWithOrders: number;\n};\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(\n inputs: PositionNotionalWithOrderInputs,\n): Decimal {\n return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\nexport type PositionQtyWithOrderInputs = {\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};\n/**\n * Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(\n inputs: PositionQtyWithOrderInputs,\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\nexport type IMRInputs = {\n /**\n * effective max leverage\n */\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n};\n\n/**\n * Initial margin rate for a symbol.\n * Max(1 / Max Account Leverage, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: IMRInputs): 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\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\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\nexport type TotalInitialMarginWithOrdersInputs = {\n positions: API.Position[];\n orders: API.Order[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n} & Pick<IMRInputs, \"maxLeverage\">;\n\n/**\n * @deprecated\n * Calculate the total initial margin used by the user (including positions and orders).\n */\nexport function totalInitialMarginWithOrders(\n inputs: TotalInitialMarginWithOrdersInputs,\n): number {\n const {\n positions,\n orders,\n markPrices,\n IMR_Factors,\n maxLeverage,\n symbolInfo,\n } = inputs;\n\n const symbols = extractSymbols(positions, orders);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const positionQty = getQtyFromPositions(positions, symbol);\n const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n const sellOrdersQty = getQtyFromOrdersBySide(\n orders,\n symbol,\n OrderSide.SELL,\n );\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage,\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\n\nexport function totalInitialMarginWithQty(inputs: {\n positions: API.Position[];\n // account: API.AccountInfo;\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n}) {\n const { positions, markPrices, IMR_Factors, symbolInfo } = inputs;\n const symbols = positions.map((item) => item.symbol);\n\n const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {\n const symbol = cur;\n const position = positions.find((item) => item.symbol === symbol);\n const positionQty = position?.position_qty || 0;\n\n const buyOrdersQty = position?.pending_long_qty || 0;\n const sellOrdersQty = position?.pending_short_qty || 0;\n\n const markPrice = markPrices[symbol] || 0;\n\n //---\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n //---\n const position_notional_with_orders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n //----\n const markPriceDecimal = new Decimal(markPrice);\n\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber(),\n maxLeverage: maxLeverage({\n symbolLeverage: position?.leverage ?? inputs.maxLeverage,\n accountLeverage: inputs.maxLeverage,\n }),\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return position_notional_with_orders.mul(imr).add(acc).toNumber();\n }, 0);\n\n return total_initial_margin_with_orders;\n}\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\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\nexport type OtherIMsInputs = {\n // the position list for other symbols except the current symbol\n positions: API.Position[];\n markPrices: { [key: string]: number };\n /**\n * account max leverage\n */\n maxLeverage: number;\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n};\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: OtherIMsInputs): 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 maxLeverage: maxLeverage({\n symbolLeverage: position!.leverage,\n accountLeverage: inputs.maxLeverage,\n }),\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\nexport type MaxQtyInputs = {\n symbol: string;\n\n // Maximum quantity limit for opening a single position, /v1/public/info.base_max\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 * Maximum order quantity.\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\nexport type TotalMarginRatioInputs = {\n totalCollateral: number;\n markPrices: { [key: string]: number };\n positions: API.Position[];\n};\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n inputs: TotalMarginRatioInputs,\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\nexport type TotalUnrealizedROIInputs = {\n totalUnrealizedPnL: number;\n totalValue: number;\n};\n\n/**\n * totalUnrealizedROI\n */\nexport function totalUnrealizedROI(inputs: TotalUnrealizedROIInputs) {\n const { totalUnrealizedPnL, totalValue } = inputs;\n\n return new Decimal(totalUnrealizedPnL)\n .div(totalValue - totalUnrealizedPnL)\n .toNumber();\n}\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\nexport type AvailableBalanceInputs = {\n USDCHolding: number;\n unsettlementPnL: number;\n};\nexport function availableBalance(inputs: AvailableBalanceInputs) {\n const { USDCHolding, unsettlementPnL } = inputs;\n\n return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\nexport type AccountMMRInputs = {\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};\n\n/**\n * total maintenance margin ratio\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: AccountMMRInputs): 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\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\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\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\n/**\n * @deprecated This method will be removed soon. Please update your code to use symbolLeverage directly.\n */\n// Warning: The maxLeverage method will be deprecated soon. Please use symbolLeverage directly and update all related calls as soon as possible.\nexport const maxLeverage = (inputs: {\n symbolLeverage?: number;\n accountLeverage: number;\n}) => {\n const { symbolLeverage, accountLeverage } = inputs;\n\n return symbolLeverage ?? 1;\n};\n","import { OrderSide, API as orderUtils } from \"@kodiak-finance/orderly-types\";\nimport { Decimal, getTPSLDirection, zero } from \"@kodiak-finance/orderly-utils\";\nimport { notional } from \"./positions\";\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\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/**\n * Estimated liquidation price\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: EstimatedLiquidationPriceInputs): 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\nexport type EstimatedLeverageInputs = {\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};\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: EstimatedLeverageInputs): 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"],"mappings":"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","names":["IMR","totalCollateral","MMR","totalNotional","notional","MMR","Decimal","zero","totalUnsettlementPnL","Decimal","zero","unsettlementPnL","maxLeverage","totalCollateral","otherIMs","totalUnrealizedPnL","totalValue","totalMarginRatio","MMR","collateralRatio","freeCollateral","Decimal","zero","totalCollateral","orderFee","notional","totalMarginRatio"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodiak-finance/orderly-perp",
3
- "version": "4.8.18",
3
+ "version": "4.8.19",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -21,11 +21,11 @@
21
21
  "tsup": "^7.1.0",
22
22
  "typedoc": "^0.26.5",
23
23
  "typescript": "^5.1.6",
24
- "tsconfig": "0.11.17"
24
+ "tsconfig": "0.11.18"
25
25
  },
26
26
  "dependencies": {
27
- "@kodiak-finance/orderly-types": "2.8.18",
28
- "@kodiak-finance/orderly-utils": "2.8.18"
27
+ "@kodiak-finance/orderly-types": "2.8.19",
28
+ "@kodiak-finance/orderly-utils": "2.8.19"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"