@kodiak-finance/orderly-perp 4.7.4

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.js ADDED
@@ -0,0 +1,727 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ account: () => account_exports,
24
+ order: () => order_exports,
25
+ orderUtils: () => order_exports,
26
+ positions: () => positions_exports,
27
+ version: () => version_default
28
+ });
29
+ module.exports = __toCommonJS(src_exports);
30
+
31
+ // src/version.ts
32
+ if (typeof window !== "undefined") {
33
+ window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
34
+ window.__ORDERLY_VERSION__["@kodiak-finance/orderly-perp"] = "4.7.4";
35
+ }
36
+ var version_default = "4.7.4";
37
+
38
+ // src/positions.ts
39
+ var positions_exports = {};
40
+ __export(positions_exports, {
41
+ MMR: () => MMR,
42
+ estOffsetForTP: () => estOffsetForTP,
43
+ estPnLForSL: () => estPnLForSL,
44
+ estPnLForTP: () => estPnLForTP,
45
+ estPriceForTP: () => estPriceForTP,
46
+ estPriceFromOffsetForTP: () => estPriceFromOffsetForTP,
47
+ liqPrice: () => liqPrice,
48
+ maintenanceMargin: () => maintenanceMargin,
49
+ maxPositionLeverage: () => maxPositionLeverage,
50
+ maxPositionNotional: () => maxPositionNotional,
51
+ notional: () => notional,
52
+ totalNotional: () => totalNotional,
53
+ totalUnrealizedPnL: () => totalUnrealizedPnL,
54
+ totalUnsettlementPnL: () => totalUnsettlementPnL,
55
+ unrealizedPnL: () => unrealizedPnL,
56
+ unrealizedPnLROI: () => unrealizedPnLROI,
57
+ unsettlementPnL: () => unsettlementPnL
58
+ });
59
+ var import_orderly_utils = require("@kodiak-finance/orderly-utils");
60
+
61
+ // src/constants.ts
62
+ var IMRFactorPower = 4 / 5;
63
+
64
+ // src/positions.ts
65
+ function notional(qty, mark_price) {
66
+ return new import_orderly_utils.Decimal(qty).mul(mark_price).abs().toNumber();
67
+ }
68
+ function totalNotional(positions) {
69
+ return positions.reduce((acc, cur) => {
70
+ return acc + notional(cur.position_qty, cur.mark_price);
71
+ }, 0);
72
+ }
73
+ function unrealizedPnL(inputs) {
74
+ return new import_orderly_utils.Decimal(inputs.qty).mul(inputs.markPrice - inputs.openPrice).toNumber();
75
+ }
76
+ function unrealizedPnLROI(inputs) {
77
+ const { openPrice, IMR: IMR2 } = inputs;
78
+ if (inputs.unrealizedPnL === 0 || inputs.positionQty === 0 || openPrice === 0 || IMR2 === 0)
79
+ return 0;
80
+ return new import_orderly_utils.Decimal(inputs.unrealizedPnL).div(new import_orderly_utils.Decimal(Math.abs(inputs.positionQty)).mul(openPrice).mul(IMR2)).toNumber();
81
+ }
82
+ function totalUnrealizedPnL(positions) {
83
+ return positions.reduce((acc, cur) => {
84
+ return acc + unrealizedPnL({
85
+ qty: cur.position_qty,
86
+ openPrice: cur.average_open_price,
87
+ markPrice: cur.mark_price
88
+ });
89
+ }, 0);
90
+ }
91
+ function liqPrice(inputs) {
92
+ const { markPrice, totalCollateral: totalCollateral2, positions, positionQty, MMR: MMR3 } = inputs;
93
+ if (positionQty === 0 || totalCollateral2 === 0) {
94
+ return null;
95
+ }
96
+ const totalNotional2 = positions.reduce((acc, cur) => {
97
+ return acc.add(
98
+ new import_orderly_utils.Decimal(notional(cur.position_qty, cur.mark_price)).mul(cur.mmr)
99
+ );
100
+ }, import_orderly_utils.zero);
101
+ return Math.max(
102
+ new import_orderly_utils.Decimal(markPrice).add(
103
+ new import_orderly_utils.Decimal(totalCollateral2).sub(totalNotional2).div(new import_orderly_utils.Decimal(positionQty).abs().mul(MMR3).sub(positionQty))
104
+ ).toNumber(),
105
+ 0
106
+ );
107
+ }
108
+ function maintenanceMargin(inputs) {
109
+ const { positionQty, markPrice, MMR: MMR3 } = inputs;
110
+ return new import_orderly_utils.Decimal(positionQty).mul(markPrice).mul(MMR3).abs().toNumber();
111
+ }
112
+ function unsettlementPnL(inputs) {
113
+ const {
114
+ positionQty,
115
+ markPrice,
116
+ costPosition,
117
+ sumUnitaryFunding,
118
+ lastSumUnitaryFunding
119
+ } = inputs;
120
+ const qty = new import_orderly_utils.Decimal(positionQty);
121
+ return qty.mul(markPrice).sub(costPosition).sub(qty.mul(new import_orderly_utils.Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding))).toNumber();
122
+ }
123
+ function totalUnsettlementPnL(positions) {
124
+ if (!Array.isArray(positions) || positions.length === 0) {
125
+ return 0;
126
+ }
127
+ return positions.reduce((acc, cur) => {
128
+ return acc + unsettlementPnL({
129
+ positionQty: cur.position_qty,
130
+ markPrice: cur.mark_price,
131
+ costPosition: cur.cost_position,
132
+ sumUnitaryFunding: cur.sum_unitary_funding,
133
+ lastSumUnitaryFunding: cur.last_sum_unitary_funding
134
+ });
135
+ }, 0);
136
+ }
137
+ function MMR(inputs) {
138
+ const {
139
+ baseMMR,
140
+ baseIMR,
141
+ IMRFactor,
142
+ positionNotional,
143
+ IMR_factor_power = IMRFactorPower
144
+ } = inputs;
145
+ return Math.max(
146
+ baseMMR,
147
+ new import_orderly_utils.Decimal(baseMMR).div(baseIMR).mul(IMRFactor).mul(Math.pow(Math.abs(positionNotional), IMR_factor_power)).toNumber()
148
+ );
149
+ }
150
+ function estPnLForTP(inputs) {
151
+ return new import_orderly_utils.Decimal(inputs.positionQty).mul(new import_orderly_utils.Decimal(inputs.price).sub(inputs.entryPrice)).toNumber();
152
+ }
153
+ function estPriceForTP(inputs) {
154
+ return new import_orderly_utils.Decimal(inputs.pnl).add(inputs.entryPrice).div(inputs.positionQty).toNumber();
155
+ }
156
+ function estOffsetForTP(inputs) {
157
+ return new import_orderly_utils.Decimal(inputs.price).div(inputs.entryPrice).toNumber();
158
+ }
159
+ function estPriceFromOffsetForTP(inputs) {
160
+ return new import_orderly_utils.Decimal(inputs.offset).add(inputs.entryPrice).toNumber();
161
+ }
162
+ function estPnLForSL(inputs) {
163
+ return 0;
164
+ }
165
+ function maxPositionNotional(inputs) {
166
+ const { leverage, IMRFactor } = inputs;
167
+ return new import_orderly_utils.Decimal(1).div(new import_orderly_utils.Decimal(leverage).mul(IMRFactor)).pow(1 / 0.8).toNumber();
168
+ }
169
+ function maxPositionLeverage(inputs) {
170
+ const { IMRFactor, notional: notional2 } = inputs;
171
+ return new import_orderly_utils.Decimal(1).div(new import_orderly_utils.Decimal(IMRFactor).mul(new import_orderly_utils.Decimal(notional2).pow(0.8))).toNumber();
172
+ }
173
+
174
+ // src/account.ts
175
+ var account_exports = {};
176
+ __export(account_exports, {
177
+ IMR: () => IMR,
178
+ LTV: () => LTV,
179
+ MMR: () => MMR2,
180
+ availableBalance: () => availableBalance,
181
+ buyOrdersFilter_by_symbol: () => buyOrdersFilter_by_symbol,
182
+ calcMinimumReceived: () => calcMinimumReceived,
183
+ collateralContribution: () => collateralContribution,
184
+ collateralRatio: () => collateralRatio,
185
+ currentLeverage: () => currentLeverage,
186
+ extractSymbols: () => extractSymbols,
187
+ freeCollateral: () => freeCollateral,
188
+ getPositonsAndOrdersNotionalBySymbol: () => getPositonsAndOrdersNotionalBySymbol,
189
+ getQtyFromOrdersBySide: () => getQtyFromOrdersBySide,
190
+ getQtyFromPositions: () => getQtyFromPositions,
191
+ groupOrdersBySymbol: () => groupOrdersBySymbol,
192
+ initialMarginWithOrder: () => initialMarginWithOrder,
193
+ maxLeverage: () => maxLeverage,
194
+ maxQty: () => maxQty,
195
+ maxQtyByLong: () => maxQtyByLong,
196
+ maxQtyByShort: () => maxQtyByShort,
197
+ maxWithdrawalOtherCollateral: () => maxWithdrawalOtherCollateral,
198
+ maxWithdrawalUSDC: () => maxWithdrawalUSDC,
199
+ otherIMs: () => otherIMs,
200
+ positionNotionalWithOrder_by_symbol: () => positionNotionalWithOrder_by_symbol,
201
+ positionQtyWithOrders_by_symbol: () => positionQtyWithOrders_by_symbol,
202
+ sellOrdersFilter_by_symbol: () => sellOrdersFilter_by_symbol,
203
+ totalCollateral: () => totalCollateral,
204
+ totalInitialMarginWithOrders: () => totalInitialMarginWithOrders,
205
+ totalInitialMarginWithQty: () => totalInitialMarginWithQty,
206
+ totalMarginRatio: () => totalMarginRatio,
207
+ totalUnrealizedROI: () => totalUnrealizedROI,
208
+ totalValue: () => totalValue
209
+ });
210
+ var import_orderly_types = require("@kodiak-finance/orderly-types");
211
+ var import_orderly_utils2 = require("@kodiak-finance/orderly-utils");
212
+ function totalValue(inputs) {
213
+ const { totalUnsettlementPnL: totalUnsettlementPnL2, USDCHolding, nonUSDCHolding } = inputs;
214
+ const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {
215
+ return new import_orderly_utils2.Decimal(cur.holding).mul(cur.indexPrice).add(acc);
216
+ }, import_orderly_utils2.zero);
217
+ return nonUSDCHoldingValue.add(USDCHolding).add(totalUnsettlementPnL2);
218
+ }
219
+ function freeCollateral(inputs) {
220
+ const value = inputs.totalCollateral.sub(inputs.totalInitialMarginWithOrders);
221
+ return value.isNegative() ? import_orderly_utils2.zero : value;
222
+ }
223
+ function totalCollateral(inputs) {
224
+ const { USDCHolding, nonUSDCHolding, unsettlementPnL: unsettlementPnL2 } = inputs;
225
+ const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {
226
+ const finalHolding = Math.min(cur.holding, cur.collateralCap);
227
+ const value = new import_orderly_utils2.Decimal(finalHolding).mul(cur.collateralRatio).mul(cur.indexPrice);
228
+ return acc.add(value);
229
+ }, import_orderly_utils2.zero);
230
+ return new import_orderly_utils2.Decimal(USDCHolding).add(nonUSDCHoldingValue).add(unsettlementPnL2);
231
+ }
232
+ function initialMarginWithOrder() {
233
+ }
234
+ function positionNotionalWithOrder_by_symbol(inputs) {
235
+ return new import_orderly_utils2.Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);
236
+ }
237
+ function positionQtyWithOrders_by_symbol(inputs) {
238
+ const { positionQty, buyOrdersQty, sellOrdersQty } = inputs;
239
+ const positionQtyDecimal = new import_orderly_utils2.Decimal(positionQty);
240
+ const qty = Math.max(
241
+ positionQtyDecimal.add(buyOrdersQty).abs().toNumber(),
242
+ positionQtyDecimal.sub(sellOrdersQty).abs().toNumber()
243
+ );
244
+ return qty;
245
+ }
246
+ function IMR(inputs) {
247
+ const {
248
+ maxLeverage: maxLeverage2,
249
+ baseIMR,
250
+ IMR_Factor,
251
+ positionNotional,
252
+ ordersNotional: orderNotional,
253
+ IMR_factor_power = IMRFactorPower
254
+ } = inputs;
255
+ return Math.max(
256
+ 1 / maxLeverage2,
257
+ baseIMR,
258
+ new import_orderly_utils2.Decimal(IMR_Factor).mul(
259
+ new import_orderly_utils2.Decimal(positionNotional).add(orderNotional).abs().toPower(IMR_factor_power)
260
+ ).toNumber()
261
+ );
262
+ }
263
+ function buyOrdersFilter_by_symbol(orders, symbol) {
264
+ return orders.filter(
265
+ (item) => item.symbol === symbol && item.side === import_orderly_types.OrderSide.BUY
266
+ );
267
+ }
268
+ function sellOrdersFilter_by_symbol(orders, symbol) {
269
+ return orders.filter(
270
+ (item) => item.symbol === symbol && item.side === import_orderly_types.OrderSide.SELL
271
+ );
272
+ }
273
+ function getQtyFromPositions(positions, symbol) {
274
+ if (!positions) {
275
+ return 0;
276
+ }
277
+ const position = positions.find((item) => item.symbol === symbol);
278
+ return (position == null ? void 0 : position.position_qty) || 0;
279
+ }
280
+ function getQtyFromOrdersBySide(orders, symbol, side) {
281
+ const ordersBySide = side === import_orderly_types.OrderSide.SELL ? sellOrdersFilter_by_symbol(orders, symbol) : buyOrdersFilter_by_symbol(orders, symbol);
282
+ return ordersBySide.reduce((acc, cur) => {
283
+ return acc + cur.quantity;
284
+ }, 0);
285
+ }
286
+ function getPositonsAndOrdersNotionalBySymbol(inputs) {
287
+ const { positions, orders, symbol, markPrice } = inputs;
288
+ const positionQty = getQtyFromPositions(positions, symbol);
289
+ const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, import_orderly_types.OrderSide.BUY);
290
+ const sellOrdersQty = getQtyFromOrdersBySide(orders, symbol, import_orderly_types.OrderSide.SELL);
291
+ const markPriceDecimal = new import_orderly_utils2.Decimal(markPrice);
292
+ return markPriceDecimal.mul(positionQty).add(markPriceDecimal.mul(new import_orderly_utils2.Decimal(buyOrdersQty).add(sellOrdersQty))).abs().toNumber();
293
+ }
294
+ function totalInitialMarginWithOrders(inputs) {
295
+ const {
296
+ positions,
297
+ orders,
298
+ markPrices,
299
+ IMR_Factors,
300
+ maxLeverage: maxLeverage2,
301
+ symbolInfo
302
+ } = inputs;
303
+ const symbols = extractSymbols(positions, orders);
304
+ const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {
305
+ const symbol = cur;
306
+ const positionQty = getQtyFromPositions(positions, symbol);
307
+ const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, import_orderly_types.OrderSide.BUY);
308
+ const sellOrdersQty = getQtyFromOrdersBySide(
309
+ orders,
310
+ symbol,
311
+ import_orderly_types.OrderSide.SELL
312
+ );
313
+ const markPrice = markPrices[symbol] || 0;
314
+ const positionQtyWithOrders = positionQtyWithOrders_by_symbol({
315
+ positionQty,
316
+ buyOrdersQty,
317
+ sellOrdersQty
318
+ });
319
+ const position_notional_with_orders = positionNotionalWithOrder_by_symbol({
320
+ markPrice,
321
+ positionQtyWithOrders
322
+ });
323
+ const markPriceDecimal = new import_orderly_utils2.Decimal(markPrice);
324
+ const imr = IMR({
325
+ positionNotional: markPriceDecimal.mul(positionQty).toNumber(),
326
+ ordersNotional: markPriceDecimal.mul(new import_orderly_utils2.Decimal(buyOrdersQty).add(sellOrdersQty)).toNumber(),
327
+ maxLeverage: maxLeverage2,
328
+ IMR_Factor: IMR_Factors[symbol],
329
+ baseIMR: symbolInfo[symbol]("base_imr", 0)
330
+ });
331
+ return position_notional_with_orders.mul(imr).add(acc).toNumber();
332
+ }, 0);
333
+ return total_initial_margin_with_orders;
334
+ }
335
+ function totalInitialMarginWithQty(inputs) {
336
+ const { positions, markPrices, IMR_Factors, symbolInfo } = inputs;
337
+ const symbols = positions.map((item) => item.symbol);
338
+ const total_initial_margin_with_orders = symbols.reduce((acc, cur) => {
339
+ var _a;
340
+ const symbol = cur;
341
+ const position = positions.find((item) => item.symbol === symbol);
342
+ const positionQty = (position == null ? void 0 : position.position_qty) || 0;
343
+ const buyOrdersQty = (position == null ? void 0 : position.pending_long_qty) || 0;
344
+ const sellOrdersQty = (position == null ? void 0 : position.pending_short_qty) || 0;
345
+ const markPrice = markPrices[symbol] || 0;
346
+ const positionQtyWithOrders = positionQtyWithOrders_by_symbol({
347
+ positionQty,
348
+ buyOrdersQty,
349
+ sellOrdersQty
350
+ });
351
+ const position_notional_with_orders = positionNotionalWithOrder_by_symbol({
352
+ markPrice,
353
+ positionQtyWithOrders
354
+ });
355
+ const markPriceDecimal = new import_orderly_utils2.Decimal(markPrice);
356
+ const imr = IMR({
357
+ positionNotional: markPriceDecimal.mul(positionQty).toNumber(),
358
+ ordersNotional: markPriceDecimal.mul(new import_orderly_utils2.Decimal(buyOrdersQty).add(sellOrdersQty)).toNumber(),
359
+ maxLeverage: maxLeverage({
360
+ symbolLeverage: (_a = position == null ? void 0 : position.leverage) != null ? _a : inputs.maxLeverage,
361
+ accountLeverage: inputs.maxLeverage
362
+ }),
363
+ IMR_Factor: IMR_Factors[symbol],
364
+ baseIMR: symbolInfo[symbol]("base_imr", 0)
365
+ });
366
+ return position_notional_with_orders.mul(imr).add(acc).toNumber();
367
+ }, 0);
368
+ return total_initial_margin_with_orders;
369
+ }
370
+ function groupOrdersBySymbol(orders) {
371
+ const symbols = {};
372
+ orders.forEach((item) => {
373
+ if (!symbols[item.symbol]) {
374
+ symbols[item.symbol] = [];
375
+ }
376
+ symbols[item.symbol].push(item);
377
+ });
378
+ return symbols;
379
+ }
380
+ function extractSymbols(positions, orders) {
381
+ const symbols = /* @__PURE__ */ new Set();
382
+ positions.forEach((item) => {
383
+ symbols.add(item.symbol);
384
+ });
385
+ orders.forEach((item) => {
386
+ symbols.add(item.symbol);
387
+ });
388
+ return Array.from(symbols);
389
+ }
390
+ function otherIMs(inputs) {
391
+ const {
392
+ // orders,
393
+ positions,
394
+ IMR_Factors,
395
+ symbolInfo,
396
+ markPrices
397
+ } = inputs;
398
+ const symbols = positions.map((item) => item.symbol);
399
+ return symbols.reduce((acc, cur) => {
400
+ const symbol = cur;
401
+ if (typeof markPrices[symbol] === "undefined") {
402
+ console.warn("markPrices[%s] is undefined", symbol);
403
+ return acc;
404
+ }
405
+ const markPriceDecimal = new import_orderly_utils2.Decimal(markPrices[symbol] || 0);
406
+ const position = positions.find((item) => item.symbol === symbol);
407
+ const positionQty = getQtyFromPositions(positions, symbol);
408
+ const positionNotional = markPriceDecimal.mul(positionQty).toNumber();
409
+ const buyOrdersQty = position.pending_long_qty;
410
+ const sellOrdersQty = position.pending_short_qty;
411
+ const ordersNotional = markPriceDecimal.mul(new import_orderly_utils2.Decimal(buyOrdersQty).add(sellOrdersQty)).toNumber();
412
+ const IMR_Factor = IMR_Factors[symbol];
413
+ if (!IMR_Factor) {
414
+ console.warn("IMR_Factor is not found:", symbol);
415
+ return acc;
416
+ }
417
+ const imr = IMR({
418
+ maxLeverage: maxLeverage({
419
+ symbolLeverage: position.leverage,
420
+ accountLeverage: inputs.maxLeverage
421
+ }),
422
+ IMR_Factor,
423
+ baseIMR: symbolInfo[symbol]("base_imr", 0),
424
+ positionNotional,
425
+ ordersNotional
426
+ });
427
+ const positionQtyWithOrders = positionQtyWithOrders_by_symbol({
428
+ positionQty,
429
+ buyOrdersQty,
430
+ sellOrdersQty
431
+ });
432
+ const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({
433
+ markPrice: markPrices[symbol] || 0,
434
+ positionQtyWithOrders
435
+ });
436
+ return acc.add(positionNotionalWithOrders.mul(imr));
437
+ }, import_orderly_utils2.zero).toNumber();
438
+ }
439
+ function maxQty(side, inputs, options) {
440
+ if (side === import_orderly_types.OrderSide.BUY) {
441
+ return maxQtyByLong(inputs);
442
+ }
443
+ return maxQtyByShort(inputs);
444
+ }
445
+ function maxQtyByLong(inputs, options) {
446
+ try {
447
+ const {
448
+ baseMaxQty,
449
+ totalCollateral: totalCollateral2,
450
+ otherIMs: otherIMs2,
451
+ maxLeverage: maxLeverage2,
452
+ baseIMR,
453
+ markPrice,
454
+ IMR_Factor,
455
+ positionQty,
456
+ buyOrdersQty,
457
+ takerFeeRate
458
+ } = inputs;
459
+ if (totalCollateral2 === 0) {
460
+ return 0;
461
+ }
462
+ const totalCollateralDecimal = new import_orderly_utils2.Decimal(totalCollateral2);
463
+ const factor_1 = totalCollateralDecimal.sub(otherIMs2).div(
464
+ new import_orderly_utils2.Decimal(takerFeeRate).mul(2).mul(1e-4).add(Math.max(1 / maxLeverage2, baseIMR))
465
+ ).div(markPrice).mul(0.995).sub(new import_orderly_utils2.Decimal(positionQty).add(buyOrdersQty)).toNumber();
466
+ if (positionQty === 0 && buyOrdersQty === 0) {
467
+ return Math.min(baseMaxQty, factor_1);
468
+ }
469
+ const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).sub(
470
+ new import_orderly_utils2.Decimal(positionQty).add(buyOrdersQty)
471
+ // .abs()
472
+ // .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))
473
+ ).div(new import_orderly_utils2.Decimal(takerFeeRate).mul(2).mul(1e-4).add(1)).mul(0.995).toNumber();
474
+ return Math.min(baseMaxQty, factor_1, factor_2);
475
+ } catch (error) {
476
+ return 0;
477
+ }
478
+ }
479
+ function maxQtyByShort(inputs, options) {
480
+ try {
481
+ const {
482
+ baseMaxQty,
483
+ totalCollateral: totalCollateral2,
484
+ otherIMs: otherIMs2,
485
+ maxLeverage: maxLeverage2,
486
+ baseIMR,
487
+ markPrice,
488
+ IMR_Factor,
489
+ positionQty,
490
+ buyOrdersQty,
491
+ sellOrdersQty,
492
+ takerFeeRate
493
+ } = inputs;
494
+ const totalCollateralDecimal = new import_orderly_utils2.Decimal(totalCollateral2);
495
+ const factor_1 = totalCollateralDecimal.sub(otherIMs2).div(
496
+ new import_orderly_utils2.Decimal(takerFeeRate).mul(2).mul(1e-4).add(Math.max(1 / maxLeverage2, baseIMR))
497
+ ).div(markPrice).mul(0.995).add(positionQty).sub(Math.abs(sellOrdersQty)).toNumber();
498
+ if (positionQty === 0 && sellOrdersQty === 0) {
499
+ return Math.min(baseMaxQty, factor_1);
500
+ }
501
+ 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
+ return Math.min(baseMaxQty, factor_1, factor_2);
503
+ } catch (error) {
504
+ return 0;
505
+ }
506
+ }
507
+ function totalMarginRatio(inputs, dp) {
508
+ const { totalCollateral: totalCollateral2, markPrices, positions } = inputs;
509
+ if (totalCollateral2 === 0) {
510
+ return 0;
511
+ }
512
+ const totalCollateralDecimal = new import_orderly_utils2.Decimal(totalCollateral2);
513
+ const totalPositionNotional = positions.reduce((acc, cur) => {
514
+ const markPrice = markPrices[cur.symbol] || 0;
515
+ return acc.add(new import_orderly_utils2.Decimal(cur.position_qty).mul(markPrice).abs());
516
+ }, import_orderly_utils2.zero);
517
+ if (totalPositionNotional.eq(import_orderly_utils2.zero)) {
518
+ return 0;
519
+ }
520
+ return totalCollateralDecimal.div(totalPositionNotional).toNumber();
521
+ }
522
+ function totalUnrealizedROI(inputs) {
523
+ const { totalUnrealizedPnL: totalUnrealizedPnL2, totalValue: totalValue2 } = inputs;
524
+ return new import_orderly_utils2.Decimal(totalUnrealizedPnL2).div(totalValue2 - totalUnrealizedPnL2).toNumber();
525
+ }
526
+ function currentLeverage(totalMarginRatio2) {
527
+ if (totalMarginRatio2 === 0) {
528
+ return 0;
529
+ }
530
+ return 1 / totalMarginRatio2;
531
+ }
532
+ function availableBalance(inputs) {
533
+ const { USDCHolding, unsettlementPnL: unsettlementPnL2 } = inputs;
534
+ return new import_orderly_utils2.Decimal(USDCHolding).add(unsettlementPnL2).toNumber();
535
+ }
536
+ function MMR2(inputs) {
537
+ if (inputs.positionsNotional === 0) {
538
+ return null;
539
+ }
540
+ if (inputs.positionsMMR === 0) {
541
+ return null;
542
+ }
543
+ return new import_orderly_utils2.Decimal(inputs.positionsMMR).div(inputs.positionsNotional).toNumber();
544
+ }
545
+ var collateralRatio = (params) => {
546
+ const {
547
+ baseWeight,
548
+ discountFactor,
549
+ collateralQty,
550
+ collateralCap,
551
+ indexPrice
552
+ } = params;
553
+ const cap = collateralCap === -1 ? collateralQty : collateralCap;
554
+ const K = new import_orderly_utils2.Decimal(1.2);
555
+ const DCF = new import_orderly_utils2.Decimal(discountFactor || 0);
556
+ const qty = new import_orderly_utils2.Decimal(Math.min(collateralQty, cap));
557
+ const notionalAbs = qty.mul(indexPrice).abs();
558
+ const dynamicWeight = DCF.mul(notionalAbs).toPower(IMRFactorPower);
559
+ const result = K.div(new import_orderly_utils2.Decimal(1).add(dynamicWeight));
560
+ return result.lt(baseWeight) ? result : new import_orderly_utils2.Decimal(baseWeight);
561
+ };
562
+ var collateralContribution = (params) => {
563
+ const { collateralQty, collateralCap, collateralRatio: collateralRatio2, indexPrice } = params;
564
+ const cap = collateralCap === -1 ? collateralQty : collateralCap;
565
+ return new import_orderly_utils2.Decimal(Math.min(collateralQty, cap)).mul(collateralRatio2).mul(indexPrice).toNumber();
566
+ };
567
+ var LTV = (params) => {
568
+ const { usdcBalance, upnl, assets } = params;
569
+ const usdcLoss = new import_orderly_utils2.Decimal(Math.min(usdcBalance, 0)).abs();
570
+ const upnlLoss = new import_orderly_utils2.Decimal(Math.min(upnl, 0)).abs();
571
+ const numerator = usdcLoss.add(upnlLoss);
572
+ const collateralSum = assets.reduce((acc, asset) => {
573
+ return acc.add(
574
+ new import_orderly_utils2.Decimal(Math.max(asset.qty, 0)).mul(new import_orderly_utils2.Decimal(asset.indexPrice)).mul(new import_orderly_utils2.Decimal(asset.weight))
575
+ );
576
+ }, import_orderly_utils2.zero);
577
+ const denominator = collateralSum.add(new import_orderly_utils2.Decimal(Math.max(upnl, 0)));
578
+ if (numerator.isZero() || denominator.isZero()) {
579
+ return 0;
580
+ }
581
+ return numerator.div(denominator).toNumber();
582
+ };
583
+ var maxWithdrawalUSDC = (inputs) => {
584
+ const { USDCBalance, freeCollateral: freeCollateral2, upnl } = inputs;
585
+ const value = Math.min(
586
+ new import_orderly_utils2.Decimal(USDCBalance).toNumber(),
587
+ new import_orderly_utils2.Decimal(freeCollateral2).sub(Math.max(upnl, 0)).toNumber()
588
+ );
589
+ return Math.max(0, value);
590
+ };
591
+ var maxWithdrawalOtherCollateral = (inputs) => {
592
+ const { USDCBalance, collateralQty, freeCollateral: freeCollateral2, indexPrice, weight } = inputs;
593
+ const usdcBalance = new import_orderly_utils2.Decimal(USDCBalance);
594
+ const denominator = usdcBalance.isNegative() ? new import_orderly_utils2.Decimal(indexPrice).mul(weight).mul(new import_orderly_utils2.Decimal(1).add(2e-3)) : new import_orderly_utils2.Decimal(indexPrice).mul(weight);
595
+ if (denominator.isZero()) {
596
+ return import_orderly_utils2.zero;
597
+ }
598
+ const qty = new import_orderly_utils2.Decimal(collateralQty);
599
+ const maxQtyByValue = new import_orderly_utils2.Decimal(freeCollateral2).div(denominator);
600
+ return maxQtyByValue.lt(qty) ? maxQtyByValue : qty;
601
+ };
602
+ var calcMinimumReceived = (inputs) => {
603
+ const { amount, slippage } = inputs;
604
+ const slippageRatio = new import_orderly_utils2.Decimal(slippage).div(100);
605
+ return new import_orderly_utils2.Decimal(amount).mul(new import_orderly_utils2.Decimal(1).minus(slippageRatio)).toNumber();
606
+ };
607
+ var maxLeverage = (inputs) => {
608
+ const { symbolLeverage, accountLeverage } = inputs;
609
+ return symbolLeverage != null ? symbolLeverage : 1;
610
+ };
611
+
612
+ // src/order.ts
613
+ var order_exports = {};
614
+ __export(order_exports, {
615
+ estLeverage: () => estLeverage,
616
+ estLiqPrice: () => estLiqPrice,
617
+ maxPrice: () => maxPrice,
618
+ minPrice: () => minPrice,
619
+ orderFee: () => orderFee,
620
+ scopePrice: () => scopePrice
621
+ });
622
+ var import_orderly_utils3 = require("@kodiak-finance/orderly-utils");
623
+ function maxPrice(markprice, range) {
624
+ return markprice * (1 + range);
625
+ }
626
+ function minPrice(markprice, range) {
627
+ return markprice * (1 - range);
628
+ }
629
+ function scopePrice(price, scope, side) {
630
+ if (side === "BUY") {
631
+ return price * (1 - scope);
632
+ }
633
+ return price * (1 + scope);
634
+ }
635
+ function orderFee(inputs) {
636
+ return new import_orderly_utils3.Decimal(inputs.qty).mul(inputs.price).mul(inputs.futuresTakeFeeRate).toNumber();
637
+ }
638
+ function estLiqPrice(inputs) {
639
+ var _a;
640
+ const {
641
+ positions,
642
+ newOrder,
643
+ totalCollateral: totalCollateral2,
644
+ markPrice,
645
+ baseIMR,
646
+ baseMMR,
647
+ orderFee: orderFee2,
648
+ IMR_Factor
649
+ } = inputs;
650
+ let currentPosition = void 0;
651
+ let newTotalMM = import_orderly_utils3.zero;
652
+ const hasPosition = positions.filter((item) => item.position_qty > 0).length > 0;
653
+ const basePrice = hasPosition ? markPrice : newOrder.price;
654
+ const newOrderNotional = new import_orderly_utils3.Decimal(newOrder.qty).mul(newOrder.price);
655
+ for (let index = 0; index < positions.length; index++) {
656
+ const position = positions[index];
657
+ let notional2 = new import_orderly_utils3.Decimal(position.position_qty).mul(position.mark_price);
658
+ if (newOrder.symbol === position.symbol) {
659
+ currentPosition = position;
660
+ notional2 = notional2.add(newOrderNotional);
661
+ }
662
+ newTotalMM = newTotalMM.add(notional2.abs().mul(position.mmr));
663
+ }
664
+ if (!currentPosition) {
665
+ newTotalMM = newTotalMM.add(newOrderNotional.mul(baseMMR));
666
+ }
667
+ const newMMR = Math.max(
668
+ baseMMR,
669
+ new import_orderly_utils3.Decimal(baseMMR).div(baseIMR).mul(IMR_Factor).mul(
670
+ newOrderNotional.add(
671
+ !!currentPosition ? new import_orderly_utils3.Decimal(currentPosition.position_qty).mul(
672
+ currentPosition.mark_price
673
+ ) : import_orderly_utils3.zero
674
+ ).abs()
675
+ ).toPower(4 / 5).toNumber()
676
+ );
677
+ const newQty = new import_orderly_utils3.Decimal(newOrder.qty).add(
678
+ (_a = currentPosition == null ? void 0 : currentPosition.position_qty) != null ? _a : 0
679
+ );
680
+ if (newQty.eq(0)) {
681
+ return 0;
682
+ }
683
+ const denominator = newQty.abs().mul(newMMR).sub(newQty);
684
+ if (denominator.eq(import_orderly_utils3.zero)) {
685
+ return 0;
686
+ }
687
+ const price = new import_orderly_utils3.Decimal(basePrice).add(
688
+ new import_orderly_utils3.Decimal(totalCollateral2).sub(newTotalMM).sub(orderFee2).div(denominator)
689
+ ).toNumber();
690
+ return Math.max(0, price);
691
+ }
692
+ function estLeverage(inputs) {
693
+ const { totalCollateral: totalCollateral2, positions, newOrder } = inputs;
694
+ if (totalCollateral2 <= 0) {
695
+ return null;
696
+ }
697
+ let hasPosition = false;
698
+ let sumPositionNotional = positions.reduce((acc, cur) => {
699
+ let count = new import_orderly_utils3.Decimal(cur.position_qty).mul(cur.mark_price);
700
+ if (cur.symbol === newOrder.symbol) {
701
+ hasPosition = true;
702
+ count = count.add(new import_orderly_utils3.Decimal(newOrder.qty).mul(newOrder.price));
703
+ }
704
+ return acc.add(count.abs());
705
+ }, import_orderly_utils3.zero);
706
+ if (!hasPosition) {
707
+ sumPositionNotional = sumPositionNotional.add(
708
+ new import_orderly_utils3.Decimal(newOrder.qty).mul(newOrder.price).abs()
709
+ );
710
+ }
711
+ if (sumPositionNotional.eq(import_orderly_utils3.zero)) {
712
+ return null;
713
+ }
714
+ const totalMarginRatio2 = new import_orderly_utils3.Decimal(totalCollateral2).div(
715
+ sumPositionNotional
716
+ );
717
+ return new import_orderly_utils3.Decimal(1).div(totalMarginRatio2).toDecimalPlaces(2, import_orderly_utils3.Decimal.ROUND_HALF_EVEN).toNumber();
718
+ }
719
+ // Annotate the CommonJS export names for ESM import in node:
720
+ 0 && (module.exports = {
721
+ account,
722
+ order,
723
+ orderUtils,
724
+ positions,
725
+ version
726
+ });
727
+ //# sourceMappingURL=index.js.map