@lifi/perps-sdk 23.1.0 → 25.0.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/README.md +102 -56
- package/dist/cjs/client/PerpsClient.d.ts +3 -2
- package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
- package/dist/cjs/client/PerpsClient.js +16 -9
- package/dist/cjs/client/PerpsClient.js.map +1 -1
- package/dist/cjs/decimal/arithmetic.d.ts +15 -0
- package/dist/cjs/decimal/arithmetic.d.ts.map +1 -0
- package/dist/cjs/decimal/arithmetic.js +53 -0
- package/dist/cjs/decimal/arithmetic.js.map +1 -0
- package/dist/cjs/decimal/big.d.ts +0 -1
- package/dist/cjs/decimal/big.d.ts.map +1 -1
- package/dist/cjs/decimal/big.js +0 -4
- package/dist/cjs/decimal/big.js.map +1 -1
- package/dist/cjs/decimal/compare.d.ts +6 -2
- package/dist/cjs/decimal/compare.d.ts.map +1 -1
- package/dist/cjs/decimal/compare.js +15 -2
- package/dist/cjs/decimal/compare.js.map +1 -1
- package/dist/cjs/decimal/convert.d.ts +10 -6
- package/dist/cjs/decimal/convert.d.ts.map +1 -1
- package/dist/cjs/decimal/convert.js +34 -21
- package/dist/cjs/decimal/convert.js.map +1 -1
- package/dist/cjs/decimal/decimalStringToBig.d.ts +5 -0
- package/dist/cjs/decimal/decimalStringToBig.d.ts.map +1 -0
- package/dist/cjs/decimal/decimalStringToBig.js +25 -0
- package/dist/cjs/decimal/decimalStringToBig.js.map +1 -0
- package/dist/cjs/decimal/format.d.ts.map +1 -1
- package/dist/cjs/decimal/format.js +70 -52
- package/dist/cjs/decimal/format.js.map +1 -1
- package/dist/cjs/decimal/parse.d.ts +5 -4
- package/dist/cjs/decimal/parse.d.ts.map +1 -1
- package/dist/cjs/decimal/parse.js +43 -25
- package/dist/cjs/decimal/parse.js.map +1 -1
- package/dist/cjs/errors/invalidInput.d.ts +3 -0
- package/dist/cjs/errors/invalidInput.d.ts.map +1 -0
- package/dist/cjs/errors/invalidInput.js +9 -0
- package/dist/cjs/errors/invalidInput.js.map +1 -0
- package/dist/cjs/index.d.ts +15 -12
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +69 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/math/fills.d.ts +1 -1
- package/dist/cjs/math/fills.d.ts.map +1 -1
- package/dist/cjs/math/fills.js +28 -13
- package/dist/cjs/math/fills.js.map +1 -1
- package/dist/cjs/math/order.d.ts +27 -16
- package/dist/cjs/math/order.d.ts.map +1 -1
- package/dist/cjs/math/order.js +131 -134
- package/dist/cjs/math/order.js.map +1 -1
- package/dist/cjs/math/position.d.ts +85 -35
- package/dist/cjs/math/position.d.ts.map +1 -1
- package/dist/cjs/math/position.js +93 -94
- package/dist/cjs/math/position.js.map +1 -1
- package/dist/cjs/services/getGasRecommendation.js +1 -1
- package/dist/cjs/services/getGasRecommendation.js.map +1 -1
- package/dist/cjs/services/getQuote.d.ts +1 -1
- package/dist/cjs/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/cjs/services/resolveSubscribeQuote.js +3 -2
- package/dist/cjs/services/resolveSubscribeQuote.js.map +1 -1
- package/dist/cjs/transport/request.d.ts +1 -0
- package/dist/cjs/transport/request.d.ts.map +1 -1
- package/dist/cjs/transport/request.js +2 -2
- package/dist/cjs/transport/request.js.map +1 -1
- package/dist/cjs/types/api.d.ts +4 -0
- package/dist/cjs/types/api.d.ts.map +1 -1
- package/dist/cjs/types/provider.d.ts +9 -5
- package/dist/cjs/types/provider.d.ts.map +1 -1
- package/dist/cjs/types/withdrawal.d.ts +12 -4
- package/dist/cjs/types/withdrawal.d.ts.map +1 -1
- package/dist/cjs/utils/createSafeFunction.d.ts +2 -0
- package/dist/cjs/utils/createSafeFunction.d.ts.map +1 -0
- package/dist/cjs/utils/createSafeFunction.js +15 -0
- package/dist/cjs/utils/createSafeFunction.js.map +1 -0
- package/dist/cjs/utils/timestampToIsoString.d.ts +3 -0
- package/dist/cjs/utils/timestampToIsoString.d.ts.map +1 -0
- package/dist/cjs/utils/timestampToIsoString.js +16 -0
- package/dist/cjs/utils/timestampToIsoString.js.map +1 -0
- package/dist/cjs/utils/warnOnce.d.ts +6 -0
- package/dist/cjs/utils/warnOnce.d.ts.map +1 -1
- package/dist/cjs/utils/warnOnce.js +19 -1
- package/dist/cjs/utils/warnOnce.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/websocket/PerpsWsClient.d.ts +2 -0
- package/dist/cjs/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/cjs/websocket/PerpsWsClient.js +14 -1
- package/dist/cjs/websocket/PerpsWsClient.js.map +1 -1
- package/dist/cjs/websocket/wsLog.d.ts +2 -0
- package/dist/cjs/websocket/wsLog.d.ts.map +1 -1
- package/dist/cjs/websocket/wsLog.js +9 -0
- package/dist/cjs/websocket/wsLog.js.map +1 -1
- package/dist/cjs/wire/orderAmounts.d.ts +3 -2
- package/dist/cjs/wire/orderAmounts.d.ts.map +1 -1
- package/dist/cjs/wire/orderAmounts.js +22 -21
- package/dist/cjs/wire/orderAmounts.js.map +1 -1
- package/dist/cjs/wire/refuel.d.ts +4 -1
- package/dist/cjs/wire/refuel.d.ts.map +1 -1
- package/dist/cjs/wire/refuel.js +23 -6
- package/dist/cjs/wire/refuel.js.map +1 -1
- package/dist/cjs/wire/transferable.js +3 -3
- package/dist/cjs/wire/transferable.js.map +1 -1
- package/dist/cjs/wire/withdraw.d.ts.map +1 -1
- package/dist/cjs/wire/withdraw.js +3 -3
- package/dist/cjs/wire/withdraw.js.map +1 -1
- package/dist/esm/client/PerpsClient.d.ts +17 -4
- package/dist/esm/client/PerpsClient.d.ts.map +1 -1
- package/dist/esm/client/PerpsClient.js +30 -8
- package/dist/esm/client/PerpsClient.js.map +1 -1
- package/dist/esm/decimal/arithmetic.d.ts +98 -0
- package/dist/esm/decimal/arithmetic.d.ts.map +1 -0
- package/dist/esm/decimal/arithmetic.js +126 -0
- package/dist/esm/decimal/arithmetic.js.map +1 -0
- package/dist/esm/decimal/big.d.ts +0 -2
- package/dist/esm/decimal/big.d.ts.map +1 -1
- package/dist/esm/decimal/big.js +0 -4
- package/dist/esm/decimal/big.js.map +1 -1
- package/dist/esm/decimal/compare.d.ts +40 -6
- package/dist/esm/decimal/compare.d.ts.map +1 -1
- package/dist/esm/decimal/compare.js +46 -6
- package/dist/esm/decimal/compare.js.map +1 -1
- package/dist/esm/decimal/convert.d.ts +50 -36
- package/dist/esm/decimal/convert.d.ts.map +1 -1
- package/dist/esm/decimal/convert.js +64 -42
- package/dist/esm/decimal/convert.js.map +1 -1
- package/dist/esm/decimal/decimalStringToBig.d.ts +25 -0
- package/dist/esm/decimal/decimalStringToBig.d.ts.map +1 -0
- package/dist/esm/decimal/decimalStringToBig.js +37 -0
- package/dist/esm/decimal/decimalStringToBig.js.map +1 -0
- package/dist/esm/decimal/format.d.ts +4 -1
- package/dist/esm/decimal/format.d.ts.map +1 -1
- package/dist/esm/decimal/format.js +71 -70
- package/dist/esm/decimal/format.js.map +1 -1
- package/dist/esm/decimal/parse.d.ts +29 -13
- package/dist/esm/decimal/parse.d.ts.map +1 -1
- package/dist/esm/decimal/parse.js +61 -44
- package/dist/esm/decimal/parse.js.map +1 -1
- package/dist/esm/errors/invalidInput.d.ts +4 -0
- package/dist/esm/errors/invalidInput.d.ts.map +1 -0
- package/dist/esm/errors/invalidInput.js +7 -0
- package/dist/esm/errors/invalidInput.js.map +1 -0
- package/dist/esm/index.d.ts +15 -12
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +11 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/math/fills.d.ts +6 -3
- package/dist/esm/math/fills.d.ts.map +1 -1
- package/dist/esm/math/fills.js +31 -16
- package/dist/esm/math/fills.js.map +1 -1
- package/dist/esm/math/order.d.ts +84 -66
- package/dist/esm/math/order.d.ts.map +1 -1
- package/dist/esm/math/order.js +178 -175
- package/dist/esm/math/order.js.map +1 -1
- package/dist/esm/math/position.d.ts +155 -98
- package/dist/esm/math/position.d.ts.map +1 -1
- package/dist/esm/math/position.js +160 -156
- package/dist/esm/math/position.js.map +1 -1
- package/dist/esm/services/getGasRecommendation.js +1 -1
- package/dist/esm/services/getGasRecommendation.js.map +1 -1
- package/dist/esm/services/getQuote.d.ts +2 -2
- package/dist/esm/services/getQuote.js +1 -1
- package/dist/esm/services/resolveSubscribeQuote.d.ts +1 -1
- package/dist/esm/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/esm/services/resolveSubscribeQuote.js +4 -3
- package/dist/esm/services/resolveSubscribeQuote.js.map +1 -1
- package/dist/esm/transport/request.d.ts +5 -0
- package/dist/esm/transport/request.d.ts.map +1 -1
- package/dist/esm/transport/request.js +2 -2
- package/dist/esm/transport/request.js.map +1 -1
- package/dist/esm/types/api.d.ts +9 -0
- package/dist/esm/types/api.d.ts.map +1 -1
- package/dist/esm/types/provider.d.ts +30 -16
- package/dist/esm/types/provider.d.ts.map +1 -1
- package/dist/esm/types/withdrawal.d.ts +32 -7
- package/dist/esm/types/withdrawal.d.ts.map +1 -1
- package/dist/esm/utils/createSafeFunction.d.ts +9 -0
- package/dist/esm/utils/createSafeFunction.d.ts.map +1 -0
- package/dist/esm/utils/createSafeFunction.js +19 -0
- package/dist/esm/utils/createSafeFunction.js.map +1 -0
- package/dist/esm/utils/timestampToIsoString.d.ts +15 -0
- package/dist/esm/utils/timestampToIsoString.d.ts.map +1 -0
- package/dist/esm/utils/timestampToIsoString.js +24 -0
- package/dist/esm/utils/timestampToIsoString.js.map +1 -0
- package/dist/esm/utils/warnOnce.d.ts +27 -0
- package/dist/esm/utils/warnOnce.d.ts.map +1 -1
- package/dist/esm/utils/warnOnce.js +36 -0
- package/dist/esm/utils/warnOnce.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/websocket/PerpsWsClient.d.ts +7 -0
- package/dist/esm/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/esm/websocket/PerpsWsClient.js +20 -2
- package/dist/esm/websocket/PerpsWsClient.js.map +1 -1
- package/dist/esm/websocket/wsLog.d.ts +12 -0
- package/dist/esm/websocket/wsLog.d.ts.map +1 -1
- package/dist/esm/websocket/wsLog.js +19 -0
- package/dist/esm/websocket/wsLog.js.map +1 -1
- package/dist/esm/wire/orderAmounts.d.ts +9 -7
- package/dist/esm/wire/orderAmounts.d.ts.map +1 -1
- package/dist/esm/wire/orderAmounts.js +24 -20
- package/dist/esm/wire/orderAmounts.js.map +1 -1
- package/dist/esm/wire/refuel.d.ts +24 -14
- package/dist/esm/wire/refuel.d.ts.map +1 -1
- package/dist/esm/wire/refuel.js +38 -17
- package/dist/esm/wire/refuel.js.map +1 -1
- package/dist/esm/wire/transferable.d.ts +2 -2
- package/dist/esm/wire/transferable.js +5 -5
- package/dist/esm/wire/transferable.js.map +1 -1
- package/dist/esm/wire/withdraw.d.ts.map +1 -1
- package/dist/esm/wire/withdraw.js +3 -3
- package/dist/esm/wire/withdraw.js.map +1 -1
- package/dist/types/client/PerpsClient.d.ts +17 -4
- package/dist/types/client/PerpsClient.d.ts.map +1 -1
- package/dist/types/decimal/arithmetic.d.ts +98 -0
- package/dist/types/decimal/arithmetic.d.ts.map +1 -0
- package/dist/types/decimal/big.d.ts +0 -2
- package/dist/types/decimal/big.d.ts.map +1 -1
- package/dist/types/decimal/compare.d.ts +40 -6
- package/dist/types/decimal/compare.d.ts.map +1 -1
- package/dist/types/decimal/convert.d.ts +50 -36
- package/dist/types/decimal/convert.d.ts.map +1 -1
- package/dist/types/decimal/decimalStringToBig.d.ts +25 -0
- package/dist/types/decimal/decimalStringToBig.d.ts.map +1 -0
- package/dist/types/decimal/format.d.ts +4 -1
- package/dist/types/decimal/format.d.ts.map +1 -1
- package/dist/types/decimal/parse.d.ts +29 -13
- package/dist/types/decimal/parse.d.ts.map +1 -1
- package/dist/types/errors/invalidInput.d.ts +4 -0
- package/dist/types/errors/invalidInput.d.ts.map +1 -0
- package/dist/types/index.d.ts +15 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/math/fills.d.ts +6 -3
- package/dist/types/math/fills.d.ts.map +1 -1
- package/dist/types/math/order.d.ts +84 -66
- package/dist/types/math/order.d.ts.map +1 -1
- package/dist/types/math/position.d.ts +155 -98
- package/dist/types/math/position.d.ts.map +1 -1
- package/dist/types/services/getQuote.d.ts +2 -2
- package/dist/types/services/resolveSubscribeQuote.d.ts +1 -1
- package/dist/types/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/types/transport/request.d.ts +5 -0
- package/dist/types/transport/request.d.ts.map +1 -1
- package/dist/types/types/api.d.ts +9 -0
- package/dist/types/types/api.d.ts.map +1 -1
- package/dist/types/types/provider.d.ts +30 -16
- package/dist/types/types/provider.d.ts.map +1 -1
- package/dist/types/types/withdrawal.d.ts +32 -7
- package/dist/types/types/withdrawal.d.ts.map +1 -1
- package/dist/types/utils/createSafeFunction.d.ts +9 -0
- package/dist/types/utils/createSafeFunction.d.ts.map +1 -0
- package/dist/types/utils/timestampToIsoString.d.ts +15 -0
- package/dist/types/utils/timestampToIsoString.d.ts.map +1 -0
- package/dist/types/utils/warnOnce.d.ts +27 -0
- package/dist/types/utils/warnOnce.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/websocket/PerpsWsClient.d.ts +7 -0
- package/dist/types/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/types/websocket/wsLog.d.ts +12 -0
- package/dist/types/websocket/wsLog.d.ts.map +1 -1
- package/dist/types/wire/orderAmounts.d.ts +9 -7
- package/dist/types/wire/orderAmounts.d.ts.map +1 -1
- package/dist/types/wire/refuel.d.ts +24 -14
- package/dist/types/wire/refuel.d.ts.map +1 -1
- package/dist/types/wire/transferable.d.ts +2 -2
- package/dist/types/wire/withdraw.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client/PerpsClient.ts +48 -10
- package/src/decimal/arithmetic.ts +170 -0
- package/src/decimal/big.ts +0 -5
- package/src/decimal/compare.ts +61 -11
- package/src/decimal/convert.ts +105 -63
- package/src/decimal/decimalStringToBig.ts +42 -0
- package/src/decimal/format.ts +81 -72
- package/src/decimal/parse.ts +78 -57
- package/src/errors/invalidInput.ts +10 -0
- package/src/index.ts +80 -12
- package/src/math/fills.ts +32 -17
- package/src/math/order.ts +279 -226
- package/src/math/position.ts +280 -196
- package/src/services/getGasRecommendation.ts +1 -1
- package/src/services/getQuote.ts +2 -2
- package/src/services/resolveSubscribeQuote.ts +4 -3
- package/src/transport/request.ts +7 -2
- package/src/types/api.ts +10 -0
- package/src/types/provider.ts +39 -16
- package/src/types/withdrawal.ts +35 -8
- package/src/utils/createSafeFunction.ts +20 -0
- package/src/utils/timestampToIsoString.ts +31 -0
- package/src/utils/warnOnce.ts +60 -0
- package/src/version.ts +1 -1
- package/src/websocket/PerpsWsClient.ts +25 -2
- package/src/websocket/wsLog.ts +44 -0
- package/src/wire/orderAmounts.ts +45 -26
- package/src/wire/refuel.ts +56 -20
- package/src/wire/transferable.ts +5 -5
- package/src/wire/withdraw.ts +3 -5
- package/dist/cjs/decimal/requireDecimal.d.ts +0 -4
- package/dist/cjs/decimal/requireDecimal.d.ts.map +0 -1
- package/dist/cjs/decimal/requireDecimal.js +0 -12
- package/dist/cjs/decimal/requireDecimal.js.map +0 -1
- package/dist/esm/decimal/requireDecimal.d.ts +0 -5
- package/dist/esm/decimal/requireDecimal.d.ts.map +0 -1
- package/dist/esm/decimal/requireDecimal.js +0 -7
- package/dist/esm/decimal/requireDecimal.js.map +0 -1
- package/dist/types/decimal/requireDecimal.d.ts +0 -5
- package/dist/types/decimal/requireDecimal.d.ts.map +0 -1
- package/src/decimal/requireDecimal.ts +0 -8
package/src/math/position.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Display-tier position formulas and margin-adjustment predicates. Every
|
|
3
|
-
* formula takes and gives
|
|
4
|
-
*
|
|
3
|
+
* formula takes and gives decimal strings; arithmetic is exact Big.js, with
|
|
4
|
+
* division to 40 decimal places. Each formula throws `ValidationError` on an
|
|
5
|
+
* input that does not match the decimal pattern and has a `safe*` pair that gives
|
|
6
|
+
* `undefined` in place of the throw.
|
|
5
7
|
*
|
|
6
8
|
* Sign convention: long = +1, short = -1. Sizes passed to the `estimate*`
|
|
7
9
|
* helpers are always non-negative magnitudes; direction is carried by
|
|
@@ -10,318 +12,400 @@
|
|
|
10
12
|
|
|
11
13
|
import {
|
|
12
14
|
MarginMode,
|
|
15
|
+
type PerpsMarket,
|
|
13
16
|
type Position,
|
|
14
17
|
PositionMarginAdjustment,
|
|
15
18
|
} from '@lifi/perps-types'
|
|
16
|
-
import {
|
|
19
|
+
import { DivBig } from '../decimal/big.js'
|
|
20
|
+
import {
|
|
21
|
+
bigToDecimalString,
|
|
22
|
+
decimalStringToBig,
|
|
23
|
+
decimalStringToDivBig,
|
|
24
|
+
} from '../decimal/decimalStringToBig.js'
|
|
25
|
+
import { invalidInput } from '../errors/invalidInput.js'
|
|
26
|
+
import type { LiquidationEstimateParams } from '../types/provider.js'
|
|
27
|
+
import { createSafeFunction } from '../utils/createSafeFunction.js'
|
|
17
28
|
|
|
18
29
|
/**
|
|
19
|
-
*
|
|
30
|
+
* Notional value of a position: `|size| × price`.
|
|
20
31
|
*
|
|
21
|
-
* @
|
|
22
|
-
* @param price - Current asset price
|
|
23
|
-
* @returns Notional value in USD
|
|
32
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
24
33
|
* @public
|
|
25
34
|
*/
|
|
26
|
-
export function calculateNotionalValue(size:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return new DivBig(size).abs().times(price).toNumber()
|
|
35
|
+
export function calculateNotionalValue(size: string, price: string): string {
|
|
36
|
+
return bigToDecimalString(
|
|
37
|
+
decimalStringToBig(size).abs().times(decimalStringToBig(price))
|
|
38
|
+
)
|
|
31
39
|
}
|
|
32
40
|
|
|
41
|
+
/** @public */
|
|
42
|
+
export const safeCalculateNotionalValue = createSafeFunction(
|
|
43
|
+
'calculateNotionalValue',
|
|
44
|
+
calculateNotionalValue
|
|
45
|
+
)
|
|
46
|
+
|
|
33
47
|
/**
|
|
34
|
-
*
|
|
48
|
+
* Unrealized PnL: `(currentPrice - entryPrice) × size`, where `size` is
|
|
49
|
+
* positive for a long and negative for a short.
|
|
35
50
|
*
|
|
36
|
-
* @
|
|
37
|
-
* @param currentPrice - Current market price
|
|
38
|
-
* @param size - Position size (positive for long, negative for short)
|
|
39
|
-
* @returns Unrealized PnL in USD
|
|
51
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
40
52
|
* @public
|
|
41
53
|
*/
|
|
42
54
|
export function calculateUnrealizedPnl(
|
|
43
|
-
entryPrice:
|
|
44
|
-
currentPrice:
|
|
45
|
-
size:
|
|
46
|
-
):
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
entryPrice: string,
|
|
56
|
+
currentPrice: string,
|
|
57
|
+
size: string
|
|
58
|
+
): string {
|
|
59
|
+
return bigToDecimalString(
|
|
60
|
+
decimalStringToBig(currentPrice)
|
|
61
|
+
.minus(decimalStringToBig(entryPrice))
|
|
62
|
+
.times(decimalStringToBig(size))
|
|
63
|
+
)
|
|
51
64
|
}
|
|
52
65
|
|
|
66
|
+
/** @public */
|
|
67
|
+
export const safeCalculateUnrealizedPnl = createSafeFunction(
|
|
68
|
+
'calculateUnrealizedPnl',
|
|
69
|
+
calculateUnrealizedPnl
|
|
70
|
+
)
|
|
71
|
+
|
|
53
72
|
/**
|
|
54
|
-
*
|
|
73
|
+
* Return on equity as a percentage (`'10'` for 10%): `pnl ÷ margin × 100`.
|
|
55
74
|
*
|
|
56
|
-
* @
|
|
57
|
-
*
|
|
58
|
-
* @returns ROE as percentage (e.g., 10 for 10%)
|
|
75
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
76
|
+
* decimal pattern or `margin` is zero.
|
|
59
77
|
* @public
|
|
60
78
|
*/
|
|
61
|
-
export function calculateRoe(pnl:
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
export function calculateRoe(pnl: string, margin: string): string {
|
|
80
|
+
const marginBig = decimalStringToBig(margin)
|
|
81
|
+
const pnlBig = decimalStringToDivBig(pnl)
|
|
82
|
+
if (marginBig.eq(0)) {
|
|
83
|
+
throw invalidInput('margin', 'must not be zero')
|
|
64
84
|
}
|
|
65
|
-
|
|
66
|
-
return Number.NaN
|
|
67
|
-
}
|
|
68
|
-
return new DivBig(pnl).div(margin).times(100).toNumber()
|
|
85
|
+
return bigToDecimalString(pnlBig.div(marginBig).times(100))
|
|
69
86
|
}
|
|
70
87
|
|
|
88
|
+
/** @public */
|
|
89
|
+
export const safeCalculateRoe = createSafeFunction('calculateRoe', calculateRoe)
|
|
90
|
+
|
|
71
91
|
/**
|
|
72
|
-
*
|
|
92
|
+
* Required margin: `notionalValue ÷ leverage`.
|
|
73
93
|
*
|
|
74
|
-
* @
|
|
75
|
-
*
|
|
76
|
-
* @returns Required margin in USD
|
|
94
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern
|
|
95
|
+
* or `leverage` is zero.
|
|
77
96
|
* @public
|
|
78
97
|
*/
|
|
79
98
|
export function calculateRequiredMargin(
|
|
80
|
-
notionalValue:
|
|
81
|
-
leverage:
|
|
82
|
-
):
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return Number.NaN
|
|
99
|
+
notionalValue: string,
|
|
100
|
+
leverage: string
|
|
101
|
+
): string {
|
|
102
|
+
const notionalBig = decimalStringToDivBig(notionalValue)
|
|
103
|
+
const leverageBig = decimalStringToBig(leverage)
|
|
104
|
+
if (leverageBig.eq(0)) {
|
|
105
|
+
throw invalidInput('leverage', 'must not be zero')
|
|
88
106
|
}
|
|
89
|
-
return
|
|
107
|
+
return bigToDecimalString(notionalBig.div(leverageBig))
|
|
90
108
|
}
|
|
91
109
|
|
|
110
|
+
/** @public */
|
|
111
|
+
export const safeCalculateRequiredMargin = createSafeFunction(
|
|
112
|
+
'calculateRequiredMargin',
|
|
113
|
+
calculateRequiredMargin
|
|
114
|
+
)
|
|
115
|
+
|
|
92
116
|
/**
|
|
93
|
-
* Distance from the current price to the liquidation price, as
|
|
94
|
-
* the current price.
|
|
117
|
+
* Distance from the current price to the liquidation price, as an absolute
|
|
118
|
+
* percentage of the current price.
|
|
95
119
|
*
|
|
96
|
-
* @
|
|
97
|
-
*
|
|
98
|
-
* @returns Absolute distance as a percentage, or 0 when current price is zero
|
|
120
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
121
|
+
* decimal pattern or `currentPrice` is zero.
|
|
99
122
|
* @public
|
|
100
123
|
*/
|
|
101
124
|
export function calculateLiquidationDistance(params: {
|
|
102
|
-
liquidationPrice:
|
|
103
|
-
currentPrice:
|
|
104
|
-
}):
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
125
|
+
liquidationPrice: string
|
|
126
|
+
currentPrice: string
|
|
127
|
+
}): string {
|
|
128
|
+
const liquidationPrice = decimalStringToDivBig(params.liquidationPrice)
|
|
129
|
+
const currentPrice = decimalStringToBig(params.currentPrice)
|
|
130
|
+
if (currentPrice.eq(0)) {
|
|
131
|
+
throw invalidInput('currentPrice', 'must not be zero')
|
|
108
132
|
}
|
|
109
|
-
return
|
|
133
|
+
return bigToDecimalString(
|
|
134
|
+
liquidationPrice.minus(currentPrice).div(currentPrice).abs().times(100)
|
|
135
|
+
)
|
|
110
136
|
}
|
|
111
137
|
|
|
138
|
+
/** @public */
|
|
139
|
+
export const safeCalculateLiquidationDistance = createSafeFunction(
|
|
140
|
+
'calculateLiquidationDistance',
|
|
141
|
+
calculateLiquidationDistance
|
|
142
|
+
)
|
|
143
|
+
|
|
112
144
|
/**
|
|
113
|
-
* Effective leverage of an open position
|
|
145
|
+
* Effective leverage of an open position: `positionValueUsd ÷ marginUsd`.
|
|
114
146
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* @param positionValueUsd - Position notional value in USD
|
|
118
|
-
* @param marginUsd - Margin backing the position in USD
|
|
119
|
-
* @returns Effective leverage, or 0 when margin is zero
|
|
147
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
148
|
+
* decimal pattern or `marginUsd` is zero.
|
|
120
149
|
* @public
|
|
121
150
|
*/
|
|
122
151
|
export function calculateEffectiveLeverage(params: {
|
|
123
|
-
positionValueUsd:
|
|
124
|
-
marginUsd:
|
|
125
|
-
}):
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (!areFinite(positionValueUsd, marginUsd)) {
|
|
131
|
-
return Number.NaN
|
|
152
|
+
positionValueUsd: string
|
|
153
|
+
marginUsd: string
|
|
154
|
+
}): string {
|
|
155
|
+
const positionValue = decimalStringToDivBig(params.positionValueUsd)
|
|
156
|
+
const margin = decimalStringToBig(params.marginUsd)
|
|
157
|
+
if (margin.eq(0)) {
|
|
158
|
+
throw invalidInput('marginUsd', 'must not be zero')
|
|
132
159
|
}
|
|
133
|
-
return
|
|
160
|
+
return bigToDecimalString(positionValue.div(margin))
|
|
134
161
|
}
|
|
135
162
|
|
|
163
|
+
/** @public */
|
|
164
|
+
export const safeCalculateEffectiveLeverage = createSafeFunction(
|
|
165
|
+
'calculateEffectiveLeverage',
|
|
166
|
+
calculateEffectiveLeverage
|
|
167
|
+
)
|
|
168
|
+
|
|
136
169
|
/**
|
|
137
170
|
* Estimated liquidation price for an isolated-margin position, parameterised
|
|
138
171
|
* by the venue's maintenance margin rate.
|
|
139
172
|
*
|
|
140
173
|
* Standard isolated-margin model (new position, no existing exposure):
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* margin_available = margin_per_unit - maintenance_per_unit
|
|
144
|
-
* liq_price = entryPrice - side * margin_available / (1 - mmr * side)
|
|
174
|
+
* margin_available = entryPrice × (1 / leverage - mmr)
|
|
175
|
+
* liq_price = entryPrice - side × margin_available / (1 - mmr × side)
|
|
145
176
|
*
|
|
146
177
|
* For existing positions, prefer `Position.liquidationPrice` from the venue.
|
|
147
178
|
*
|
|
148
179
|
* @param maintenanceMarginRate - Venue maintenance margin rate as a fraction
|
|
149
|
-
* (
|
|
150
|
-
* @
|
|
151
|
-
*
|
|
180
|
+
* (`'0.01'` = 1%).
|
|
181
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
182
|
+
* decimal pattern, `leverage` is zero, or `maintenanceMarginRate` gives a
|
|
183
|
+
* zero denominator (`1` for a long, `-1` for a short).
|
|
152
184
|
* @public
|
|
153
185
|
*/
|
|
154
186
|
export function estimateLiquidationPrice(params: {
|
|
155
|
-
entryPrice:
|
|
156
|
-
leverage:
|
|
187
|
+
entryPrice: string
|
|
188
|
+
leverage: string
|
|
157
189
|
isLong: boolean
|
|
158
|
-
maintenanceMarginRate:
|
|
159
|
-
}):
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
190
|
+
maintenanceMarginRate: string
|
|
191
|
+
}): string {
|
|
192
|
+
const entryPrice = decimalStringToBig(params.entryPrice)
|
|
193
|
+
const leverage = decimalStringToBig(params.leverage)
|
|
194
|
+
const mmr = decimalStringToBig(params.maintenanceMarginRate)
|
|
195
|
+
const side = params.isLong ? 1 : -1
|
|
196
|
+
const denominator = mmr.times(-side).plus(1)
|
|
197
|
+
if (leverage.eq(0)) {
|
|
198
|
+
throw invalidInput('leverage', 'must not be zero')
|
|
163
199
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (!areFinite(entryPrice, leverage, maintenanceMarginRate)) {
|
|
170
|
-
return Number.NaN
|
|
200
|
+
if (denominator.eq(0)) {
|
|
201
|
+
throw invalidInput(
|
|
202
|
+
'maintenanceMarginRate',
|
|
203
|
+
`must not be ${params.isLong ? '1' : '-1'} for this side`
|
|
204
|
+
)
|
|
171
205
|
}
|
|
172
|
-
const mmr = new DivBig(maintenanceMarginRate)
|
|
173
206
|
const marginAvailable = new DivBig(1)
|
|
174
207
|
.div(leverage)
|
|
175
208
|
.minus(mmr)
|
|
176
209
|
.times(entryPrice)
|
|
177
|
-
return
|
|
178
|
-
.minus(marginAvailable.times(side).div(
|
|
179
|
-
|
|
210
|
+
return bigToDecimalString(
|
|
211
|
+
entryPrice.minus(marginAvailable.times(side).div(denominator))
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** @public */
|
|
216
|
+
export const safeEstimateLiquidationPrice = createSafeFunction(
|
|
217
|
+
'estimateLiquidationPrice',
|
|
218
|
+
estimateLiquidationPrice
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Estimate the liquidation price of a new isolated position from the flat
|
|
223
|
+
* `market.maintenanceMarginRate`.
|
|
224
|
+
*
|
|
225
|
+
* @returns The estimate, or `undefined` when the market carries no
|
|
226
|
+
* `maintenanceMarginRate`.
|
|
227
|
+
* @throws {PerpsError} `ValidationError` on an input that
|
|
228
|
+
* {@link estimateLiquidationPrice} rejects.
|
|
229
|
+
* @public
|
|
230
|
+
*/
|
|
231
|
+
export function estimateLiquidationPriceAtMarketRate(
|
|
232
|
+
market: PerpsMarket,
|
|
233
|
+
params: LiquidationEstimateParams
|
|
234
|
+
): string | undefined {
|
|
235
|
+
if (market.maintenanceMarginRate === undefined) {
|
|
236
|
+
return undefined
|
|
237
|
+
}
|
|
238
|
+
return estimateLiquidationPrice({
|
|
239
|
+
entryPrice: params.entryPrice,
|
|
240
|
+
leverage: params.leverage,
|
|
241
|
+
isLong: params.isLong,
|
|
242
|
+
maintenanceMarginRate: market.maintenanceMarginRate,
|
|
243
|
+
})
|
|
180
244
|
}
|
|
181
245
|
|
|
246
|
+
/** @public */
|
|
247
|
+
export const safeEstimateLiquidationPriceAtMarketRate = createSafeFunction(
|
|
248
|
+
'estimateLiquidationPriceAtMarketRate',
|
|
249
|
+
estimateLiquidationPriceAtMarketRate
|
|
250
|
+
)
|
|
251
|
+
|
|
182
252
|
/**
|
|
183
253
|
* Whether an isolated position with this liquidation price is already past
|
|
184
254
|
* liquidation at `currentPrice`: a long liquidates when the price falls to its
|
|
185
255
|
* liquidation level, a short when it rises to it. A non-positive price on
|
|
186
256
|
* either side counts as unknown, so the result is `false`.
|
|
187
257
|
*
|
|
258
|
+
* @throws {PerpsError} `ValidationError` when a price does not match the decimal pattern.
|
|
188
259
|
* @public
|
|
189
260
|
*/
|
|
190
261
|
export function wouldImmediatelyLiquidate(params: {
|
|
191
|
-
liquidationPrice:
|
|
192
|
-
currentPrice:
|
|
262
|
+
liquidationPrice: string
|
|
263
|
+
currentPrice: string
|
|
193
264
|
isLong: boolean
|
|
194
265
|
}): boolean {
|
|
195
|
-
const
|
|
196
|
-
|
|
266
|
+
const liquidationPrice = decimalStringToBig(params.liquidationPrice)
|
|
267
|
+
const currentPrice = decimalStringToBig(params.currentPrice)
|
|
268
|
+
if (currentPrice.lte(0) || liquidationPrice.lte(0)) {
|
|
197
269
|
return false
|
|
198
270
|
}
|
|
199
|
-
return isLong
|
|
200
|
-
? liquidationPrice
|
|
201
|
-
: liquidationPrice
|
|
271
|
+
return params.isLong
|
|
272
|
+
? liquidationPrice.gte(currentPrice)
|
|
273
|
+
: liquidationPrice.lte(currentPrice)
|
|
202
274
|
}
|
|
203
275
|
|
|
276
|
+
/** @public */
|
|
277
|
+
export const safeWouldImmediatelyLiquidate = createSafeFunction(
|
|
278
|
+
'wouldImmediatelyLiquidate',
|
|
279
|
+
wouldImmediatelyLiquidate
|
|
280
|
+
)
|
|
281
|
+
|
|
204
282
|
/**
|
|
205
|
-
* Estimated average entry price after adding to an existing position
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* the size of each leg in coin units. Both legs assumed in the same direction
|
|
209
|
-
* (this helper is for adding to, not flipping, a position).
|
|
283
|
+
* Estimated average entry price after adding to an existing position: the
|
|
284
|
+
* size-weighted average of the current entry and the fill price. Both legs
|
|
285
|
+
* are in the same direction (an add, not a flip).
|
|
210
286
|
*
|
|
211
|
-
* @param
|
|
212
|
-
*
|
|
213
|
-
* @
|
|
214
|
-
*
|
|
215
|
-
* market, limitPrice for limit orders).
|
|
216
|
-
* @returns The new weighted-average entry price, or undefined if the inputs
|
|
217
|
-
* cannot produce a valid average (zero combined size, non-finite values).
|
|
287
|
+
* @param fillPrice - Expected fill price (mid for market, limit price for
|
|
288
|
+
* limit orders).
|
|
289
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
290
|
+
* decimal pattern or `currentSize + addSize` is not positive.
|
|
218
291
|
* @public
|
|
219
292
|
*/
|
|
220
293
|
export function estimateAverageEntryPrice(params: {
|
|
221
|
-
currentSize:
|
|
222
|
-
currentEntry:
|
|
223
|
-
addSize:
|
|
224
|
-
fillPrice:
|
|
225
|
-
}):
|
|
226
|
-
const
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
294
|
+
currentSize: string
|
|
295
|
+
currentEntry: string
|
|
296
|
+
addSize: string
|
|
297
|
+
fillPrice: string
|
|
298
|
+
}): string {
|
|
299
|
+
const currentSize = decimalStringToDivBig(params.currentSize)
|
|
300
|
+
const addSize = decimalStringToBig(params.addSize)
|
|
301
|
+
const currentEntry = decimalStringToBig(params.currentEntry)
|
|
302
|
+
const fillPrice = decimalStringToBig(params.fillPrice)
|
|
303
|
+
const totalSize = currentSize.plus(addSize)
|
|
304
|
+
if (totalSize.lte(0)) {
|
|
305
|
+
throw invalidInput('currentSize + addSize', 'must be positive')
|
|
230
306
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return new DivBig(currentSize)
|
|
238
|
-
.times(currentEntry)
|
|
239
|
-
.plus(new DivBig(addSize).times(fillPrice))
|
|
240
|
-
.div(new DivBig(currentSize).plus(addSize))
|
|
241
|
-
.toNumber()
|
|
307
|
+
return bigToDecimalString(
|
|
308
|
+
currentSize
|
|
309
|
+
.times(currentEntry)
|
|
310
|
+
.plus(addSize.times(fillPrice))
|
|
311
|
+
.div(totalSize)
|
|
312
|
+
)
|
|
242
313
|
}
|
|
243
314
|
|
|
315
|
+
/** @public */
|
|
316
|
+
export const safeEstimateAverageEntryPrice = createSafeFunction(
|
|
317
|
+
'estimateAverageEntryPrice',
|
|
318
|
+
estimateAverageEntryPrice
|
|
319
|
+
)
|
|
320
|
+
|
|
244
321
|
/**
|
|
245
|
-
* Estimated effective leverage after adding margin and notional
|
|
246
|
-
*
|
|
247
|
-
* leverage = totalNotional / totalMargin. The caller computes notional from
|
|
248
|
-
* size and price (`calculateNotionalValue`) and supplies the additional
|
|
249
|
-
* margin the user is about to put up.
|
|
322
|
+
* Estimated effective leverage after adding margin and notional:
|
|
323
|
+
* `(currentNotional + addNotional) ÷ (currentMargin + addMargin)`.
|
|
250
324
|
*
|
|
251
|
-
* @
|
|
252
|
-
*
|
|
325
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
326
|
+
* decimal pattern or `currentMargin + addMargin` is not positive.
|
|
253
327
|
* @public
|
|
254
328
|
*/
|
|
255
329
|
export function estimateNewLeverage(params: {
|
|
256
|
-
currentNotional:
|
|
257
|
-
currentMargin:
|
|
258
|
-
addNotional:
|
|
259
|
-
addMargin:
|
|
260
|
-
}):
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
330
|
+
currentNotional: string
|
|
331
|
+
currentMargin: string
|
|
332
|
+
addNotional: string
|
|
333
|
+
addMargin: string
|
|
334
|
+
}): string {
|
|
335
|
+
const totalNotional = decimalStringToDivBig(params.currentNotional).plus(
|
|
336
|
+
decimalStringToBig(params.addNotional)
|
|
337
|
+
)
|
|
338
|
+
const totalMargin = decimalStringToBig(params.currentMargin).plus(
|
|
339
|
+
decimalStringToBig(params.addMargin)
|
|
340
|
+
)
|
|
341
|
+
if (totalMargin.lte(0)) {
|
|
342
|
+
throw invalidInput('currentMargin + addMargin', 'must be positive')
|
|
268
343
|
}
|
|
269
|
-
return
|
|
270
|
-
.plus(addNotional)
|
|
271
|
-
.div(new DivBig(currentMargin).plus(addMargin))
|
|
272
|
-
.toNumber()
|
|
344
|
+
return bigToDecimalString(totalNotional.div(totalMargin))
|
|
273
345
|
}
|
|
274
346
|
|
|
347
|
+
/** @public */
|
|
348
|
+
export const safeEstimateNewLeverage = createSafeFunction(
|
|
349
|
+
'estimateNewLeverage',
|
|
350
|
+
estimateNewLeverage
|
|
351
|
+
)
|
|
352
|
+
|
|
275
353
|
/**
|
|
276
|
-
* Estimated unrealised PnL at the
|
|
277
|
-
*
|
|
278
|
-
* `pnl = (markPrice - entryPrice) * size * (isLong ? 1 : -1)`
|
|
354
|
+
* Estimated unrealised PnL at the mark price:
|
|
355
|
+
* `(markPrice - entryPrice) × size × (isLong ? 1 : -1)`.
|
|
279
356
|
*
|
|
280
357
|
* @param size - Position size as a non-negative magnitude.
|
|
358
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
281
359
|
* @public
|
|
282
360
|
*/
|
|
283
361
|
export function estimateUnrealizedPnl(params: {
|
|
284
|
-
entryPrice:
|
|
285
|
-
markPrice:
|
|
286
|
-
size:
|
|
362
|
+
entryPrice: string
|
|
363
|
+
markPrice: string
|
|
364
|
+
size: string
|
|
287
365
|
isLong: boolean
|
|
288
|
-
}):
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
.times(size)
|
|
296
|
-
.times(isLong ? 1 : -1)
|
|
297
|
-
.toNumber()
|
|
366
|
+
}): string {
|
|
367
|
+
return bigToDecimalString(
|
|
368
|
+
decimalStringToBig(params.markPrice)
|
|
369
|
+
.minus(decimalStringToBig(params.entryPrice))
|
|
370
|
+
.times(decimalStringToBig(params.size))
|
|
371
|
+
.times(params.isLong ? 1 : -1)
|
|
372
|
+
)
|
|
298
373
|
}
|
|
299
374
|
|
|
375
|
+
/** @public */
|
|
376
|
+
export const safeEstimateUnrealizedPnl = createSafeFunction(
|
|
377
|
+
'estimateUnrealizedPnl',
|
|
378
|
+
estimateUnrealizedPnl
|
|
379
|
+
)
|
|
380
|
+
|
|
300
381
|
/**
|
|
301
|
-
* Realised PnL on the portion of a position being closed
|
|
302
|
-
*
|
|
303
|
-
* `rPnl = (closePrice - entryPrice) * closeSize * (isLong ? 1 : -1)`
|
|
382
|
+
* Realised PnL on the portion of a position being closed:
|
|
383
|
+
* `(closePrice - entryPrice) × closeSize × (isLong ? 1 : -1)`.
|
|
304
384
|
*
|
|
305
385
|
* @param closeSize - Size being closed as a non-negative magnitude.
|
|
386
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
306
387
|
* @public
|
|
307
388
|
*/
|
|
308
389
|
export function calculateRealizedPnl(params: {
|
|
309
|
-
entryPrice:
|
|
310
|
-
closePrice:
|
|
311
|
-
closeSize:
|
|
390
|
+
entryPrice: string
|
|
391
|
+
closePrice: string
|
|
392
|
+
closeSize: string
|
|
312
393
|
isLong: boolean
|
|
313
|
-
}):
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
.times(closeSize)
|
|
321
|
-
.times(isLong ? 1 : -1)
|
|
322
|
-
.toNumber()
|
|
394
|
+
}): string {
|
|
395
|
+
return bigToDecimalString(
|
|
396
|
+
decimalStringToBig(params.closePrice)
|
|
397
|
+
.minus(decimalStringToBig(params.entryPrice))
|
|
398
|
+
.times(decimalStringToBig(params.closeSize))
|
|
399
|
+
.times(params.isLong ? 1 : -1)
|
|
400
|
+
)
|
|
323
401
|
}
|
|
324
402
|
|
|
403
|
+
/** @public */
|
|
404
|
+
export const safeCalculateRealizedPnl = createSafeFunction(
|
|
405
|
+
'calculateRealizedPnl',
|
|
406
|
+
calculateRealizedPnl
|
|
407
|
+
)
|
|
408
|
+
|
|
325
409
|
/**
|
|
326
410
|
* Whether this position can take a margin adjustment at all: it holds margin of
|
|
327
411
|
* its own and its market exposes individual position margin.
|
package/src/services/getQuote.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface GetQuoteParams {
|
|
|
15
15
|
/** Buy consumes asks; sell consumes bids. */
|
|
16
16
|
side: QuoteSide
|
|
17
17
|
/** USD notional to fill. */
|
|
18
|
-
size:
|
|
18
|
+
size: string
|
|
19
19
|
/** Product family used to distinguish spot and perpetual markets. */
|
|
20
20
|
type: TradeType
|
|
21
21
|
}
|
|
@@ -36,7 +36,7 @@ export interface GetQuoteParams {
|
|
|
36
36
|
* provider: 'hyperliquid',
|
|
37
37
|
* symbol: 'BTC',
|
|
38
38
|
* side: 'buy',
|
|
39
|
-
* size:
|
|
39
|
+
* size: '10000',
|
|
40
40
|
* type: 'perps',
|
|
41
41
|
* })
|
|
42
42
|
* console.log(quote.expectedFillPrice, quote.priceImpactBps)
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type OrderbookResponse,
|
|
5
5
|
PerpsErrorCode,
|
|
6
6
|
} from '@lifi/perps-types'
|
|
7
|
+
import { isDecimalString } from '../decimal/parse.js'
|
|
7
8
|
import { PerpsError } from '../errors/PerpsError.js'
|
|
8
9
|
import { buildQuote } from '../math/order.js'
|
|
9
10
|
import type {
|
|
@@ -44,7 +45,7 @@ export const QUOTE_THROTTLE_MS = 100
|
|
|
44
45
|
* price, a throwing `onQuote`) is logged via `wsLog.listenerFailure` and the
|
|
45
46
|
* emission is skipped, on both the immediate and the trailing-timer path.
|
|
46
47
|
*
|
|
47
|
-
* @throws {PerpsError} `ValidationError` when `params.size`
|
|
48
|
+
* @throws {PerpsError} `ValidationError` when `params.size` does not match the decimal pattern.
|
|
48
49
|
* @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
|
|
49
50
|
* @internal
|
|
50
51
|
*/
|
|
@@ -56,10 +57,10 @@ export async function resolveSubscribeQuote(
|
|
|
56
57
|
feeTier: FeeTier,
|
|
57
58
|
onQuote: QuoteListener
|
|
58
59
|
): Promise<() => void> {
|
|
59
|
-
if (!
|
|
60
|
+
if (!isDecimalString(params.size)) {
|
|
60
61
|
throw new PerpsError(
|
|
61
62
|
PerpsErrorCode.ValidationError,
|
|
62
|
-
`Quote size must be a
|
|
63
|
+
`Quote size must be a decimal string, got '${params.size}'`
|
|
63
64
|
)
|
|
64
65
|
}
|
|
65
66
|
const market = await resolveQuoteMarket(client, provider, params)
|