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