@orderly.network/perp 4.8.9-alpha.0 → 4.8.10-alpha.0
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 +12 -12
- package/dist/index.d.ts +12 -12
- package/dist/index.js +246 -105
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +232 -91
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -7,9 +7,9 @@ var __export = (target, all) => {
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
if (typeof window !== "undefined") {
|
|
9
9
|
window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
|
|
10
|
-
window.__ORDERLY_VERSION__["@orderly.network/perp"] = "4.8.
|
|
10
|
+
window.__ORDERLY_VERSION__["@orderly.network/perp"] = "4.8.10-alpha.0";
|
|
11
11
|
}
|
|
12
|
-
var version_default = "4.8.
|
|
12
|
+
var version_default = "4.8.10-alpha.0";
|
|
13
13
|
|
|
14
14
|
// src/positions.ts
|
|
15
15
|
var positions_exports = {};
|
|
@@ -32,14 +32,34 @@ __export(positions_exports, {
|
|
|
32
32
|
unrealizedPnLROI: () => unrealizedPnLROI,
|
|
33
33
|
unsettlementPnL: () => unsettlementPnL
|
|
34
34
|
});
|
|
35
|
-
import { Decimal, zero } from "@orderly.network/utils";
|
|
35
|
+
import { Decimal as Decimal2, zero } from "@orderly.network/utils";
|
|
36
36
|
|
|
37
37
|
// src/constants.ts
|
|
38
38
|
var IMRFactorPower = 4 / 5;
|
|
39
39
|
|
|
40
|
+
// src/utils.ts
|
|
41
|
+
import { Decimal } from "@orderly.network/utils";
|
|
42
|
+
var DMax = (...values) => {
|
|
43
|
+
if (values.length === 0) {
|
|
44
|
+
throw new Error("DMax requires at least one argument");
|
|
45
|
+
}
|
|
46
|
+
const decimals = values.map(
|
|
47
|
+
(val) => val instanceof Decimal ? val : new Decimal(val)
|
|
48
|
+
);
|
|
49
|
+
let max = decimals[0];
|
|
50
|
+
for (let i = 1; i < decimals.length; i++) {
|
|
51
|
+
if (decimals[i].gte(max)) {
|
|
52
|
+
max = decimals[i];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return max;
|
|
56
|
+
};
|
|
57
|
+
|
|
40
58
|
// src/positions.ts
|
|
59
|
+
var MaxIterates = 30;
|
|
60
|
+
var CONVERGENCE_THRESHOLD = 1e-4;
|
|
41
61
|
function notional(qty, mark_price) {
|
|
42
|
-
return new
|
|
62
|
+
return new Decimal2(qty).mul(mark_price).abs().toNumber();
|
|
43
63
|
}
|
|
44
64
|
function totalNotional(positions) {
|
|
45
65
|
return positions.reduce((acc, cur) => {
|
|
@@ -47,13 +67,13 @@ function totalNotional(positions) {
|
|
|
47
67
|
}, 0);
|
|
48
68
|
}
|
|
49
69
|
function unrealizedPnL(inputs) {
|
|
50
|
-
return new
|
|
70
|
+
return new Decimal2(inputs.qty).mul(inputs.markPrice - inputs.openPrice).toNumber();
|
|
51
71
|
}
|
|
52
72
|
function unrealizedPnLROI(inputs) {
|
|
53
73
|
const { openPrice, IMR: IMR2 } = inputs;
|
|
54
74
|
if (inputs.unrealizedPnL === 0 || inputs.positionQty === 0 || openPrice === 0 || IMR2 === 0)
|
|
55
75
|
return 0;
|
|
56
|
-
return new
|
|
76
|
+
return new Decimal2(inputs.unrealizedPnL).div(new Decimal2(Math.abs(inputs.positionQty)).mul(openPrice).mul(IMR2)).toNumber();
|
|
57
77
|
}
|
|
58
78
|
function totalUnrealizedPnL(positions) {
|
|
59
79
|
return positions.reduce((acc, cur) => {
|
|
@@ -64,26 +84,147 @@ function totalUnrealizedPnL(positions) {
|
|
|
64
84
|
});
|
|
65
85
|
}, 0);
|
|
66
86
|
}
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
var mmForOtherSymbols = (positions) => {
|
|
88
|
+
return positions.reduce((acc, cur) => {
|
|
89
|
+
return acc.add(
|
|
90
|
+
new Decimal2(cur.position_qty).abs().mul(cur.mark_price).mul(cur.mmr)
|
|
91
|
+
);
|
|
92
|
+
}, zero);
|
|
93
|
+
};
|
|
94
|
+
var calculateLiqPrice = (markPrice, positionQty, MMR3, totalCollateral2, positions) => {
|
|
95
|
+
const decimalMarkPrice = new Decimal2(markPrice);
|
|
96
|
+
const absQty = new Decimal2(positionQty).abs();
|
|
97
|
+
const denominator = absQty.mul(MMR3).sub(positionQty);
|
|
98
|
+
const liqPrice2 = new Decimal2(totalCollateral2).sub(absQty.mul(decimalMarkPrice).mul(MMR3)).sub(mmForOtherSymbols(positions)).div(denominator).add(decimalMarkPrice);
|
|
99
|
+
return DMax(liqPrice2, zero);
|
|
100
|
+
};
|
|
101
|
+
var compareCollateralWithMM = (inputs) => {
|
|
102
|
+
return (price) => {
|
|
103
|
+
const {
|
|
104
|
+
totalCollateral: totalCollateral2,
|
|
105
|
+
positionQty,
|
|
106
|
+
markPrice,
|
|
107
|
+
baseMMR,
|
|
108
|
+
baseIMR,
|
|
109
|
+
IMRFactor,
|
|
110
|
+
positions
|
|
111
|
+
} = inputs;
|
|
112
|
+
const decimalPositionQty = new Decimal2(positionQty);
|
|
113
|
+
const collateral = new Decimal2(totalCollateral2).sub(decimalPositionQty.mul(markPrice)).add(decimalPositionQty.mul(price));
|
|
114
|
+
const mm = decimalPositionQty.abs().mul(price).mul(
|
|
115
|
+
Math.max(
|
|
116
|
+
baseMMR,
|
|
117
|
+
new Decimal2(baseMMR).div(baseIMR).mul(IMRFactor).mul(decimalPositionQty.mul(price).abs().toPower(IMRFactorPower)).toNumber()
|
|
118
|
+
)
|
|
119
|
+
).add(mmForOtherSymbols(positions));
|
|
120
|
+
return collateral.gte(mm);
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
var liqPrice = (inputs) => {
|
|
124
|
+
const {
|
|
125
|
+
positionQty,
|
|
126
|
+
markPrice,
|
|
127
|
+
totalCollateral: totalCollateral2,
|
|
128
|
+
positions,
|
|
129
|
+
MMR: MMR3,
|
|
130
|
+
baseMMR,
|
|
131
|
+
baseIMR,
|
|
132
|
+
IMRFactor,
|
|
133
|
+
symbol
|
|
134
|
+
} = inputs;
|
|
69
135
|
if (positionQty === 0 || totalCollateral2 === 0) {
|
|
70
136
|
return null;
|
|
71
137
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
138
|
+
const isLONG = positionQty > 0;
|
|
139
|
+
const otherPositions = positions.filter((item) => item.symbol !== symbol);
|
|
140
|
+
if (isLONG) {
|
|
141
|
+
let liqPriceLeft = calculateLiqPrice(
|
|
142
|
+
markPrice,
|
|
143
|
+
positionQty,
|
|
144
|
+
baseMMR,
|
|
145
|
+
totalCollateral2,
|
|
146
|
+
otherPositions
|
|
75
147
|
);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
148
|
+
let liqPriceRight = calculateLiqPrice(
|
|
149
|
+
markPrice,
|
|
150
|
+
positionQty,
|
|
151
|
+
MMR3,
|
|
152
|
+
totalCollateral2,
|
|
153
|
+
otherPositions
|
|
154
|
+
);
|
|
155
|
+
const compareCollateralWithMMFunc = compareCollateralWithMM({
|
|
156
|
+
totalCollateral: totalCollateral2,
|
|
157
|
+
positionQty,
|
|
158
|
+
markPrice,
|
|
159
|
+
baseIMR,
|
|
160
|
+
baseMMR,
|
|
161
|
+
IMRFactor,
|
|
162
|
+
positions: otherPositions
|
|
163
|
+
});
|
|
164
|
+
for (let i = 0; i < MaxIterates; i++) {
|
|
165
|
+
if (liqPriceLeft.gte(liqPriceRight)) {
|
|
166
|
+
return liqPriceRight.toNumber();
|
|
167
|
+
}
|
|
168
|
+
const mid = new Decimal2(liqPriceLeft).add(liqPriceRight).div(2);
|
|
169
|
+
if (compareCollateralWithMMFunc(mid)) {
|
|
170
|
+
liqPriceRight = mid;
|
|
171
|
+
} else {
|
|
172
|
+
liqPriceLeft = mid;
|
|
173
|
+
}
|
|
174
|
+
if (liqPriceRight.sub(liqPriceLeft).div(liqPriceLeft.add(liqPriceRight)).mul(2).lte(CONVERGENCE_THRESHOLD)) {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return liqPriceRight.toNumber();
|
|
179
|
+
} else {
|
|
180
|
+
let liqPriceRight = calculateLiqPrice(
|
|
181
|
+
markPrice,
|
|
182
|
+
positionQty,
|
|
183
|
+
MMR3,
|
|
184
|
+
totalCollateral2,
|
|
185
|
+
otherPositions
|
|
186
|
+
);
|
|
187
|
+
let liqPriceLeft = calculateLiqPrice(
|
|
188
|
+
markPrice,
|
|
189
|
+
positionQty,
|
|
190
|
+
Math.max(
|
|
191
|
+
baseIMR,
|
|
192
|
+
new Decimal2(baseMMR).div(baseIMR).mul(IMRFactor).mul(
|
|
193
|
+
new Decimal2(positionQty).mul(liqPriceRight).abs().toPower(IMRFactorPower)
|
|
194
|
+
).toNumber()
|
|
195
|
+
),
|
|
196
|
+
totalCollateral2,
|
|
197
|
+
otherPositions
|
|
198
|
+
);
|
|
199
|
+
const compareCollateralWithMMFunc = compareCollateralWithMM({
|
|
200
|
+
totalCollateral: totalCollateral2,
|
|
201
|
+
positionQty,
|
|
202
|
+
markPrice,
|
|
203
|
+
baseMMR,
|
|
204
|
+
baseIMR,
|
|
205
|
+
IMRFactor,
|
|
206
|
+
positions: otherPositions
|
|
207
|
+
});
|
|
208
|
+
for (let i = 0; i < MaxIterates; i++) {
|
|
209
|
+
if (liqPriceLeft.gte(liqPriceRight)) {
|
|
210
|
+
return liqPriceLeft.toNumber();
|
|
211
|
+
}
|
|
212
|
+
const mid = liqPriceLeft.add(liqPriceRight).div(2);
|
|
213
|
+
if (compareCollateralWithMMFunc(mid)) {
|
|
214
|
+
liqPriceLeft = mid;
|
|
215
|
+
} else {
|
|
216
|
+
liqPriceRight = mid;
|
|
217
|
+
}
|
|
218
|
+
if (liqPriceRight.sub(liqPriceLeft).div(liqPriceLeft.add(liqPriceRight)).mul(2).lte(CONVERGENCE_THRESHOLD)) {
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return liqPriceLeft.toNumber();
|
|
223
|
+
}
|
|
224
|
+
};
|
|
84
225
|
function maintenanceMargin(inputs) {
|
|
85
226
|
const { positionQty, markPrice, MMR: MMR3 } = inputs;
|
|
86
|
-
return new
|
|
227
|
+
return new Decimal2(positionQty).mul(markPrice).mul(MMR3).abs().toNumber();
|
|
87
228
|
}
|
|
88
229
|
function unsettlementPnL(inputs) {
|
|
89
230
|
const {
|
|
@@ -93,8 +234,8 @@ function unsettlementPnL(inputs) {
|
|
|
93
234
|
sumUnitaryFunding,
|
|
94
235
|
lastSumUnitaryFunding
|
|
95
236
|
} = inputs;
|
|
96
|
-
const qty = new
|
|
97
|
-
return qty.mul(markPrice).sub(costPosition).sub(qty.mul(new
|
|
237
|
+
const qty = new Decimal2(positionQty);
|
|
238
|
+
return qty.mul(markPrice).sub(costPosition).sub(qty.mul(new Decimal2(sumUnitaryFunding).sub(lastSumUnitaryFunding))).toNumber();
|
|
98
239
|
}
|
|
99
240
|
function totalUnsettlementPnL(positions) {
|
|
100
241
|
if (!Array.isArray(positions) || positions.length === 0) {
|
|
@@ -120,31 +261,31 @@ function MMR(inputs) {
|
|
|
120
261
|
} = inputs;
|
|
121
262
|
return Math.max(
|
|
122
263
|
baseMMR,
|
|
123
|
-
new
|
|
264
|
+
new Decimal2(baseMMR).div(baseIMR).mul(IMRFactor).mul(Math.pow(Math.abs(positionNotional), IMR_factor_power)).toNumber()
|
|
124
265
|
);
|
|
125
266
|
}
|
|
126
267
|
function estPnLForTP(inputs) {
|
|
127
|
-
return new
|
|
268
|
+
return new Decimal2(inputs.positionQty).mul(new Decimal2(inputs.price).sub(inputs.entryPrice)).toNumber();
|
|
128
269
|
}
|
|
129
270
|
function estPriceForTP(inputs) {
|
|
130
|
-
return new
|
|
271
|
+
return new Decimal2(inputs.pnl).div(inputs.positionQty).add(inputs.entryPrice).toNumber();
|
|
131
272
|
}
|
|
132
273
|
function estOffsetForTP(inputs) {
|
|
133
|
-
return new
|
|
274
|
+
return new Decimal2(inputs.price).div(inputs.entryPrice).toNumber();
|
|
134
275
|
}
|
|
135
276
|
function estPriceFromOffsetForTP(inputs) {
|
|
136
|
-
return new
|
|
277
|
+
return new Decimal2(inputs.offset).add(inputs.entryPrice).toNumber();
|
|
137
278
|
}
|
|
138
279
|
function estPnLForSL(inputs) {
|
|
139
280
|
return 0;
|
|
140
281
|
}
|
|
141
282
|
function maxPositionNotional(inputs) {
|
|
142
283
|
const { leverage, IMRFactor } = inputs;
|
|
143
|
-
return new
|
|
284
|
+
return new Decimal2(1).div(new Decimal2(leverage).mul(IMRFactor)).pow(1 / 0.8).toNumber();
|
|
144
285
|
}
|
|
145
286
|
function maxPositionLeverage(inputs) {
|
|
146
287
|
const { IMRFactor, notional: notional2 } = inputs;
|
|
147
|
-
return new
|
|
288
|
+
return new Decimal2(1).div(new Decimal2(IMRFactor).mul(new Decimal2(notional2).pow(0.8))).toNumber();
|
|
148
289
|
}
|
|
149
290
|
|
|
150
291
|
// src/account.ts
|
|
@@ -184,11 +325,11 @@ __export(account_exports, {
|
|
|
184
325
|
totalValue: () => totalValue
|
|
185
326
|
});
|
|
186
327
|
import { OrderSide } from "@orderly.network/types";
|
|
187
|
-
import { Decimal as
|
|
328
|
+
import { Decimal as Decimal3, zero as zero2 } from "@orderly.network/utils";
|
|
188
329
|
function totalValue(inputs) {
|
|
189
330
|
const { totalUnsettlementPnL: totalUnsettlementPnL2, USDCHolding, nonUSDCHolding } = inputs;
|
|
190
331
|
const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {
|
|
191
|
-
return new
|
|
332
|
+
return new Decimal3(cur.holding).mul(cur.indexPrice).add(acc);
|
|
192
333
|
}, zero2);
|
|
193
334
|
return nonUSDCHoldingValue.add(USDCHolding).add(totalUnsettlementPnL2);
|
|
194
335
|
}
|
|
@@ -200,19 +341,19 @@ function totalCollateral(inputs) {
|
|
|
200
341
|
const { USDCHolding, nonUSDCHolding, unsettlementPnL: unsettlementPnL2 } = inputs;
|
|
201
342
|
const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {
|
|
202
343
|
const finalHolding = Math.min(cur.holding, cur.collateralCap);
|
|
203
|
-
const value = new
|
|
344
|
+
const value = new Decimal3(finalHolding).mul(cur.collateralRatio).mul(cur.indexPrice);
|
|
204
345
|
return acc.add(value);
|
|
205
346
|
}, zero2);
|
|
206
|
-
return new
|
|
347
|
+
return new Decimal3(USDCHolding).add(nonUSDCHoldingValue).add(unsettlementPnL2);
|
|
207
348
|
}
|
|
208
349
|
function initialMarginWithOrder() {
|
|
209
350
|
}
|
|
210
351
|
function positionNotionalWithOrder_by_symbol(inputs) {
|
|
211
|
-
return new
|
|
352
|
+
return new Decimal3(inputs.markPrice).mul(inputs.positionQtyWithOrders);
|
|
212
353
|
}
|
|
213
354
|
function positionQtyWithOrders_by_symbol(inputs) {
|
|
214
355
|
const { positionQty, buyOrdersQty, sellOrdersQty } = inputs;
|
|
215
|
-
const positionQtyDecimal = new
|
|
356
|
+
const positionQtyDecimal = new Decimal3(positionQty);
|
|
216
357
|
const qty = Math.max(
|
|
217
358
|
positionQtyDecimal.add(buyOrdersQty).abs().toNumber(),
|
|
218
359
|
positionQtyDecimal.sub(sellOrdersQty).abs().toNumber()
|
|
@@ -231,8 +372,8 @@ function IMR(inputs) {
|
|
|
231
372
|
return Math.max(
|
|
232
373
|
1 / maxLeverage2,
|
|
233
374
|
baseIMR,
|
|
234
|
-
new
|
|
235
|
-
new
|
|
375
|
+
new Decimal3(IMR_Factor).mul(
|
|
376
|
+
new Decimal3(positionNotional).add(orderNotional).abs().toPower(IMR_factor_power)
|
|
236
377
|
).toNumber()
|
|
237
378
|
);
|
|
238
379
|
}
|
|
@@ -264,8 +405,8 @@ function getPositonsAndOrdersNotionalBySymbol(inputs) {
|
|
|
264
405
|
const positionQty = getQtyFromPositions(positions, symbol);
|
|
265
406
|
const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);
|
|
266
407
|
const sellOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.SELL);
|
|
267
|
-
const markPriceDecimal = new
|
|
268
|
-
return markPriceDecimal.mul(positionQty).add(markPriceDecimal.mul(new
|
|
408
|
+
const markPriceDecimal = new Decimal3(markPrice);
|
|
409
|
+
return markPriceDecimal.mul(positionQty).add(markPriceDecimal.mul(new Decimal3(buyOrdersQty).add(sellOrdersQty))).abs().toNumber();
|
|
269
410
|
}
|
|
270
411
|
function totalInitialMarginWithOrders(inputs) {
|
|
271
412
|
const {
|
|
@@ -296,10 +437,10 @@ function totalInitialMarginWithOrders(inputs) {
|
|
|
296
437
|
markPrice,
|
|
297
438
|
positionQtyWithOrders
|
|
298
439
|
});
|
|
299
|
-
const markPriceDecimal = new
|
|
440
|
+
const markPriceDecimal = new Decimal3(markPrice);
|
|
300
441
|
const imr = IMR({
|
|
301
442
|
positionNotional: markPriceDecimal.mul(positionQty).toNumber(),
|
|
302
|
-
ordersNotional: markPriceDecimal.mul(new
|
|
443
|
+
ordersNotional: markPriceDecimal.mul(new Decimal3(buyOrdersQty).add(sellOrdersQty)).toNumber(),
|
|
303
444
|
maxLeverage: maxLeverage2,
|
|
304
445
|
IMR_Factor: IMR_Factors[symbol],
|
|
305
446
|
baseIMR: symbolInfo[symbol]("base_imr", 0)
|
|
@@ -328,10 +469,10 @@ function totalInitialMarginWithQty(inputs) {
|
|
|
328
469
|
markPrice,
|
|
329
470
|
positionQtyWithOrders
|
|
330
471
|
});
|
|
331
|
-
const markPriceDecimal = new
|
|
472
|
+
const markPriceDecimal = new Decimal3(markPrice);
|
|
332
473
|
const imr = IMR({
|
|
333
474
|
positionNotional: markPriceDecimal.mul(positionQty).toNumber(),
|
|
334
|
-
ordersNotional: markPriceDecimal.mul(new
|
|
475
|
+
ordersNotional: markPriceDecimal.mul(new Decimal3(buyOrdersQty).add(sellOrdersQty)).toNumber(),
|
|
335
476
|
maxLeverage: maxLeverage({
|
|
336
477
|
symbolLeverage: (_a = position == null ? void 0 : position.leverage) != null ? _a : inputs.maxLeverage,
|
|
337
478
|
accountLeverage: inputs.maxLeverage
|
|
@@ -378,13 +519,13 @@ function otherIMs(inputs) {
|
|
|
378
519
|
console.warn("markPrices[%s] is undefined", symbol);
|
|
379
520
|
return acc;
|
|
380
521
|
}
|
|
381
|
-
const markPriceDecimal = new
|
|
522
|
+
const markPriceDecimal = new Decimal3(markPrices[symbol] || 0);
|
|
382
523
|
const position = positions.find((item) => item.symbol === symbol);
|
|
383
524
|
const positionQty = getQtyFromPositions(positions, symbol);
|
|
384
525
|
const positionNotional = markPriceDecimal.mul(positionQty).toNumber();
|
|
385
526
|
const buyOrdersQty = position.pending_long_qty;
|
|
386
527
|
const sellOrdersQty = position.pending_short_qty;
|
|
387
|
-
const ordersNotional = markPriceDecimal.mul(new
|
|
528
|
+
const ordersNotional = markPriceDecimal.mul(new Decimal3(buyOrdersQty).add(sellOrdersQty)).toNumber();
|
|
388
529
|
const IMR_Factor = IMR_Factors[symbol];
|
|
389
530
|
if (typeof IMR_Factor === "undefined") {
|
|
390
531
|
console.warn("IMR_Factor is not found:", symbol);
|
|
@@ -435,10 +576,10 @@ function maxQtyByLong(inputs, options) {
|
|
|
435
576
|
if (totalCollateral2 === 0) {
|
|
436
577
|
return 0;
|
|
437
578
|
}
|
|
438
|
-
const totalCollateralDecimal = new
|
|
579
|
+
const totalCollateralDecimal = new Decimal3(totalCollateral2);
|
|
439
580
|
const factor_1 = totalCollateralDecimal.sub(otherIMs2).div(
|
|
440
|
-
new
|
|
441
|
-
).div(markPrice).mul(0.995).sub(new
|
|
581
|
+
new Decimal3(takerFeeRate).mul(2).mul(1e-4).add(Math.max(1 / maxLeverage2, baseIMR))
|
|
582
|
+
).div(markPrice).mul(0.995).sub(new Decimal3(positionQty).add(buyOrdersQty)).toNumber();
|
|
442
583
|
if (positionQty === 0 && buyOrdersQty === 0) {
|
|
443
584
|
return Math.min(baseMaxQty, factor_1);
|
|
444
585
|
}
|
|
@@ -446,10 +587,10 @@ function maxQtyByLong(inputs, options) {
|
|
|
446
587
|
return Math.min(baseMaxQty, factor_1);
|
|
447
588
|
}
|
|
448
589
|
const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).sub(
|
|
449
|
-
new
|
|
590
|
+
new Decimal3(positionQty).add(buyOrdersQty)
|
|
450
591
|
// .abs()
|
|
451
592
|
// .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))
|
|
452
|
-
).div(new
|
|
593
|
+
).div(new Decimal3(takerFeeRate).mul(2).mul(1e-4).add(1)).mul(0.995).toNumber();
|
|
453
594
|
return Math.min(baseMaxQty, factor_1, factor_2);
|
|
454
595
|
} catch (error) {
|
|
455
596
|
return 0;
|
|
@@ -470,9 +611,9 @@ function maxQtyByShort(inputs, options) {
|
|
|
470
611
|
sellOrdersQty,
|
|
471
612
|
takerFeeRate
|
|
472
613
|
} = inputs;
|
|
473
|
-
const totalCollateralDecimal = new
|
|
614
|
+
const totalCollateralDecimal = new Decimal3(totalCollateral2);
|
|
474
615
|
const factor_1 = totalCollateralDecimal.sub(otherIMs2).div(
|
|
475
|
-
new
|
|
616
|
+
new Decimal3(takerFeeRate).mul(2).mul(1e-4).add(Math.max(1 / maxLeverage2, baseIMR))
|
|
476
617
|
).div(markPrice).mul(0.995).add(positionQty).sub(Math.abs(sellOrdersQty)).toNumber();
|
|
477
618
|
if (positionQty === 0 && sellOrdersQty === 0) {
|
|
478
619
|
return Math.min(baseMaxQty, factor_1);
|
|
@@ -480,7 +621,7 @@ function maxQtyByShort(inputs, options) {
|
|
|
480
621
|
if (IMR_Factor === 0) {
|
|
481
622
|
return Math.min(baseMaxQty, factor_1);
|
|
482
623
|
}
|
|
483
|
-
const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).add(positionQty).sub(sellOrdersQty).div(new
|
|
624
|
+
const factor_2 = totalCollateralDecimal.sub(otherIMs2).div(IMR_Factor).toPower(1 / 1.8).div(markPrice).add(positionQty).sub(sellOrdersQty).div(new Decimal3(takerFeeRate).mul(2).mul(1e-4).add(1)).mul(0.995).toNumber();
|
|
484
625
|
return Math.min(baseMaxQty, factor_1, factor_2);
|
|
485
626
|
} catch (error) {
|
|
486
627
|
return 0;
|
|
@@ -491,10 +632,10 @@ function totalMarginRatio(inputs, dp) {
|
|
|
491
632
|
if (totalCollateral2 === 0) {
|
|
492
633
|
return 0;
|
|
493
634
|
}
|
|
494
|
-
const totalCollateralDecimal = new
|
|
635
|
+
const totalCollateralDecimal = new Decimal3(totalCollateral2);
|
|
495
636
|
const totalPositionNotional = positions.reduce((acc, cur) => {
|
|
496
637
|
const markPrice = markPrices[cur.symbol] || 0;
|
|
497
|
-
return acc.add(new
|
|
638
|
+
return acc.add(new Decimal3(cur.position_qty).mul(markPrice).abs());
|
|
498
639
|
}, zero2);
|
|
499
640
|
if (totalPositionNotional.eq(zero2)) {
|
|
500
641
|
return 0;
|
|
@@ -503,7 +644,7 @@ function totalMarginRatio(inputs, dp) {
|
|
|
503
644
|
}
|
|
504
645
|
function totalUnrealizedROI(inputs) {
|
|
505
646
|
const { totalUnrealizedPnL: totalUnrealizedPnL2, totalValue: totalValue2 } = inputs;
|
|
506
|
-
return new
|
|
647
|
+
return new Decimal3(totalUnrealizedPnL2).div(totalValue2 - totalUnrealizedPnL2).toNumber();
|
|
507
648
|
}
|
|
508
649
|
function currentLeverage(totalMarginRatio2) {
|
|
509
650
|
if (totalMarginRatio2 === 0) {
|
|
@@ -513,7 +654,7 @@ function currentLeverage(totalMarginRatio2) {
|
|
|
513
654
|
}
|
|
514
655
|
function availableBalance(inputs) {
|
|
515
656
|
const { USDCHolding, unsettlementPnL: unsettlementPnL2 } = inputs;
|
|
516
|
-
return new
|
|
657
|
+
return new Decimal3(USDCHolding).add(unsettlementPnL2).toNumber();
|
|
517
658
|
}
|
|
518
659
|
function MMR2(inputs) {
|
|
519
660
|
if (inputs.positionsNotional === 0) {
|
|
@@ -522,7 +663,7 @@ function MMR2(inputs) {
|
|
|
522
663
|
if (inputs.positionsMMR === 0) {
|
|
523
664
|
return null;
|
|
524
665
|
}
|
|
525
|
-
return new
|
|
666
|
+
return new Decimal3(inputs.positionsMMR).div(inputs.positionsNotional).toNumber();
|
|
526
667
|
}
|
|
527
668
|
var collateralRatio = (params) => {
|
|
528
669
|
const {
|
|
@@ -533,30 +674,30 @@ var collateralRatio = (params) => {
|
|
|
533
674
|
indexPrice
|
|
534
675
|
} = params;
|
|
535
676
|
const cap = collateralCap === -1 ? collateralQty : collateralCap;
|
|
536
|
-
const K = new
|
|
537
|
-
const DCF = new
|
|
538
|
-
const qty = new
|
|
677
|
+
const K = new Decimal3(1.2);
|
|
678
|
+
const DCF = new Decimal3(discountFactor || 0);
|
|
679
|
+
const qty = new Decimal3(Math.min(collateralQty, cap));
|
|
539
680
|
const notionalAbs = qty.mul(indexPrice).abs();
|
|
540
681
|
const dynamicWeight = DCF.mul(notionalAbs.toPower(IMRFactorPower));
|
|
541
|
-
const result = K.div(new
|
|
542
|
-
return result.lt(baseWeight) ? result : new
|
|
682
|
+
const result = K.div(new Decimal3(1).add(dynamicWeight));
|
|
683
|
+
return result.lt(baseWeight) ? result : new Decimal3(baseWeight);
|
|
543
684
|
};
|
|
544
685
|
var collateralContribution = (params) => {
|
|
545
686
|
const { collateralQty, collateralCap, collateralRatio: collateralRatio2, indexPrice } = params;
|
|
546
687
|
const cap = collateralCap === -1 ? collateralQty : collateralCap;
|
|
547
|
-
return new
|
|
688
|
+
return new Decimal3(Math.min(collateralQty, cap)).mul(collateralRatio2).mul(indexPrice).toNumber();
|
|
548
689
|
};
|
|
549
690
|
var LTV = (params) => {
|
|
550
691
|
const { usdcBalance, upnl, assets } = params;
|
|
551
|
-
const usdcLoss = new
|
|
552
|
-
const upnlLoss = new
|
|
692
|
+
const usdcLoss = new Decimal3(Math.min(usdcBalance, 0)).abs();
|
|
693
|
+
const upnlLoss = new Decimal3(Math.min(upnl, 0)).abs();
|
|
553
694
|
const numerator = usdcLoss.add(upnlLoss);
|
|
554
695
|
const collateralSum = assets.reduce((acc, asset) => {
|
|
555
696
|
return acc.add(
|
|
556
|
-
new
|
|
697
|
+
new Decimal3(Math.max(asset.qty, 0)).mul(new Decimal3(asset.indexPrice)).mul(new Decimal3(asset.weight))
|
|
557
698
|
);
|
|
558
699
|
}, zero2);
|
|
559
|
-
const denominator = collateralSum.add(new
|
|
700
|
+
const denominator = collateralSum.add(new Decimal3(Math.max(upnl, 0)));
|
|
560
701
|
if (numerator.isZero() || denominator.isZero()) {
|
|
561
702
|
return 0;
|
|
562
703
|
}
|
|
@@ -565,26 +706,26 @@ var LTV = (params) => {
|
|
|
565
706
|
var maxWithdrawalUSDC = (inputs) => {
|
|
566
707
|
const { USDCBalance, freeCollateral: freeCollateral2, upnl } = inputs;
|
|
567
708
|
const value = Math.min(
|
|
568
|
-
new
|
|
569
|
-
new
|
|
709
|
+
new Decimal3(USDCBalance).toNumber(),
|
|
710
|
+
new Decimal3(freeCollateral2).sub(Math.max(upnl, 0)).toNumber()
|
|
570
711
|
);
|
|
571
712
|
return Math.max(0, value);
|
|
572
713
|
};
|
|
573
714
|
var maxWithdrawalOtherCollateral = (inputs) => {
|
|
574
715
|
const { USDCBalance, collateralQty, freeCollateral: freeCollateral2, indexPrice, weight } = inputs;
|
|
575
|
-
const usdcBalance = new
|
|
576
|
-
const denominator = usdcBalance.isNegative() ? new
|
|
716
|
+
const usdcBalance = new Decimal3(USDCBalance);
|
|
717
|
+
const denominator = usdcBalance.isNegative() ? new Decimal3(indexPrice).mul(weight).mul(new Decimal3(1).add(2e-3)) : new Decimal3(indexPrice).mul(weight);
|
|
577
718
|
if (denominator.isZero()) {
|
|
578
719
|
return zero2;
|
|
579
720
|
}
|
|
580
|
-
const qty = new
|
|
581
|
-
const maxQtyByValue = new
|
|
721
|
+
const qty = new Decimal3(collateralQty);
|
|
722
|
+
const maxQtyByValue = new Decimal3(freeCollateral2).div(denominator);
|
|
582
723
|
return maxQtyByValue.lt(qty) ? maxQtyByValue : qty;
|
|
583
724
|
};
|
|
584
725
|
var calcMinimumReceived = (inputs) => {
|
|
585
726
|
const { amount, slippage } = inputs;
|
|
586
|
-
const slippageRatio = new
|
|
587
|
-
return new
|
|
727
|
+
const slippageRatio = new Decimal3(slippage).div(100);
|
|
728
|
+
return new Decimal3(amount).mul(new Decimal3(1).minus(slippageRatio)).toNumber();
|
|
588
729
|
};
|
|
589
730
|
var maxLeverage = (inputs) => {
|
|
590
731
|
const { symbolLeverage, accountLeverage } = inputs;
|
|
@@ -602,7 +743,7 @@ __export(order_exports, {
|
|
|
602
743
|
scopePrice: () => scopePrice,
|
|
603
744
|
tpslROI: () => tpslROI
|
|
604
745
|
});
|
|
605
|
-
import { Decimal as
|
|
746
|
+
import { Decimal as Decimal4, getTPSLDirection, zero as zero3 } from "@orderly.network/utils";
|
|
606
747
|
function maxPrice(markprice, range) {
|
|
607
748
|
return markprice * (1 + range);
|
|
608
749
|
}
|
|
@@ -616,7 +757,7 @@ function scopePrice(price, scope, side) {
|
|
|
616
757
|
return price * (1 + scope);
|
|
617
758
|
}
|
|
618
759
|
function orderFee(inputs) {
|
|
619
|
-
return new
|
|
760
|
+
return new Decimal4(inputs.qty).mul(inputs.price).mul(inputs.futuresTakeFeeRate).toNumber();
|
|
620
761
|
}
|
|
621
762
|
function estLiqPrice(inputs) {
|
|
622
763
|
var _a;
|
|
@@ -634,10 +775,10 @@ function estLiqPrice(inputs) {
|
|
|
634
775
|
let newTotalMM = zero3;
|
|
635
776
|
const hasPosition = positions.filter((item) => item.position_qty > 0).length > 0;
|
|
636
777
|
const basePrice = hasPosition ? markPrice : newOrder.price;
|
|
637
|
-
const newOrderNotional = new
|
|
778
|
+
const newOrderNotional = new Decimal4(newOrder.qty).mul(newOrder.price);
|
|
638
779
|
for (let index = 0; index < positions.length; index++) {
|
|
639
780
|
const position = positions[index];
|
|
640
|
-
let notional2 = new
|
|
781
|
+
let notional2 = new Decimal4(position.position_qty).mul(position.mark_price);
|
|
641
782
|
if (newOrder.symbol === position.symbol) {
|
|
642
783
|
currentPosition = position;
|
|
643
784
|
notional2 = notional2.add(newOrderNotional);
|
|
@@ -649,15 +790,15 @@ function estLiqPrice(inputs) {
|
|
|
649
790
|
}
|
|
650
791
|
const newMMR = Math.max(
|
|
651
792
|
baseMMR,
|
|
652
|
-
new
|
|
793
|
+
new Decimal4(baseMMR).div(baseIMR).mul(IMR_Factor).mul(
|
|
653
794
|
newOrderNotional.add(
|
|
654
|
-
!!currentPosition ? new
|
|
795
|
+
!!currentPosition ? new Decimal4(currentPosition.position_qty).mul(
|
|
655
796
|
currentPosition.mark_price
|
|
656
797
|
) : zero3
|
|
657
798
|
).abs()
|
|
658
799
|
).toPower(4 / 5).toNumber()
|
|
659
800
|
);
|
|
660
|
-
const newQty = new
|
|
801
|
+
const newQty = new Decimal4(newOrder.qty).add(
|
|
661
802
|
(_a = currentPosition == null ? void 0 : currentPosition.position_qty) != null ? _a : 0
|
|
662
803
|
);
|
|
663
804
|
if (newQty.eq(0)) {
|
|
@@ -667,8 +808,8 @@ function estLiqPrice(inputs) {
|
|
|
667
808
|
if (denominator.eq(zero3)) {
|
|
668
809
|
return 0;
|
|
669
810
|
}
|
|
670
|
-
const price = new
|
|
671
|
-
new
|
|
811
|
+
const price = new Decimal4(basePrice).add(
|
|
812
|
+
new Decimal4(totalCollateral2).sub(newTotalMM).sub(orderFee2).div(denominator)
|
|
672
813
|
).toNumber();
|
|
673
814
|
return Math.max(0, price);
|
|
674
815
|
}
|
|
@@ -679,25 +820,25 @@ function estLeverage(inputs) {
|
|
|
679
820
|
}
|
|
680
821
|
let hasPosition = false;
|
|
681
822
|
let sumPositionNotional = positions.reduce((acc, cur) => {
|
|
682
|
-
let count = new
|
|
823
|
+
let count = new Decimal4(cur.position_qty).mul(cur.mark_price);
|
|
683
824
|
if (cur.symbol === newOrder.symbol) {
|
|
684
825
|
hasPosition = true;
|
|
685
|
-
count = count.add(new
|
|
826
|
+
count = count.add(new Decimal4(newOrder.qty).mul(newOrder.price));
|
|
686
827
|
}
|
|
687
828
|
return acc.add(count.abs());
|
|
688
829
|
}, zero3);
|
|
689
830
|
if (!hasPosition) {
|
|
690
831
|
sumPositionNotional = sumPositionNotional.add(
|
|
691
|
-
new
|
|
832
|
+
new Decimal4(newOrder.qty).mul(newOrder.price).abs()
|
|
692
833
|
);
|
|
693
834
|
}
|
|
694
835
|
if (sumPositionNotional.eq(zero3)) {
|
|
695
836
|
return null;
|
|
696
837
|
}
|
|
697
|
-
const totalMarginRatio2 = new
|
|
838
|
+
const totalMarginRatio2 = new Decimal4(totalCollateral2).div(
|
|
698
839
|
sumPositionNotional
|
|
699
840
|
);
|
|
700
|
-
return new
|
|
841
|
+
return new Decimal4(1).div(totalMarginRatio2).toDecimalPlaces(2, Decimal4.ROUND_HALF_EVEN).toNumber();
|
|
701
842
|
}
|
|
702
843
|
function tpslROI(inputs) {
|
|
703
844
|
const direction = getTPSLDirection({
|
|
@@ -707,7 +848,7 @@ function tpslROI(inputs) {
|
|
|
707
848
|
orderPrice: inputs.orderPrice
|
|
708
849
|
});
|
|
709
850
|
const { closePrice, orderPrice, leverage } = inputs;
|
|
710
|
-
return new
|
|
851
|
+
return new Decimal4(closePrice).minus(orderPrice).div(orderPrice).mul(leverage).abs().mul(direction).toNumber();
|
|
711
852
|
}
|
|
712
853
|
export {
|
|
713
854
|
account_exports as account,
|