@lifi/perps-sdk 19.0.0 → 20.1.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.
Files changed (209) hide show
  1. package/README.md +35 -5
  2. package/dist/cjs/client/PerpsClient.d.ts +1 -1
  3. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  4. package/dist/cjs/client/PerpsClient.js +4 -1
  5. package/dist/cjs/client/PerpsClient.js.map +1 -1
  6. package/dist/cjs/client/createPerpsClient.d.ts +1 -6
  7. package/dist/cjs/client/createPerpsClient.d.ts.map +1 -1
  8. package/dist/cjs/client/createPerpsClient.js +1 -14
  9. package/dist/cjs/client/createPerpsClient.js.map +1 -1
  10. package/dist/cjs/index.d.ts +6 -3
  11. package/dist/cjs/index.d.ts.map +1 -1
  12. package/dist/cjs/index.js +15 -3
  13. package/dist/cjs/index.js.map +1 -1
  14. package/dist/cjs/registry/assetRegistry.d.ts +2 -1
  15. package/dist/cjs/registry/assetRegistry.d.ts.map +1 -1
  16. package/dist/cjs/registry/assetRegistry.js +4 -2
  17. package/dist/cjs/registry/assetRegistry.js.map +1 -1
  18. package/dist/cjs/registry/marketRegistry.d.ts +2 -1
  19. package/dist/cjs/registry/marketRegistry.d.ts.map +1 -1
  20. package/dist/cjs/registry/marketRegistry.js +4 -2
  21. package/dist/cjs/registry/marketRegistry.js.map +1 -1
  22. package/dist/cjs/registry/referenceDataRegistry.d.ts +5 -1
  23. package/dist/cjs/registry/referenceDataRegistry.d.ts.map +1 -1
  24. package/dist/cjs/registry/referenceDataRegistry.js +65 -5
  25. package/dist/cjs/registry/referenceDataRegistry.js.map +1 -1
  26. package/dist/cjs/services/getOhlcv.d.ts.map +1 -1
  27. package/dist/cjs/services/getOhlcv.js.map +1 -1
  28. package/dist/cjs/transport/request.d.ts +1 -0
  29. package/dist/cjs/transport/request.d.ts.map +1 -1
  30. package/dist/cjs/transport/request.js +6 -2
  31. package/dist/cjs/transport/request.js.map +1 -1
  32. package/dist/cjs/types/api.d.ts +3 -4
  33. package/dist/cjs/types/api.d.ts.map +1 -1
  34. package/dist/cjs/types/config.d.ts +0 -9
  35. package/dist/cjs/types/config.d.ts.map +1 -1
  36. package/dist/cjs/types/provider.d.ts +1 -1
  37. package/dist/cjs/types/provider.d.ts.map +1 -1
  38. package/dist/cjs/types/withdrawal.d.ts +4 -2
  39. package/dist/cjs/types/withdrawal.d.ts.map +1 -1
  40. package/dist/cjs/utils/calculations.d.ts.map +1 -1
  41. package/dist/cjs/utils/calculations.js +107 -38
  42. package/dist/cjs/utils/calculations.js.map +1 -1
  43. package/dist/cjs/utils/decimal.d.ts +5 -0
  44. package/dist/cjs/utils/decimal.d.ts.map +1 -0
  45. package/dist/cjs/utils/decimal.js +17 -0
  46. package/dist/cjs/utils/decimal.js.map +1 -0
  47. package/dist/cjs/utils/math.d.ts +4 -0
  48. package/dist/cjs/utils/math.d.ts.map +1 -0
  49. package/dist/cjs/utils/math.js +8 -0
  50. package/dist/cjs/utils/math.js.map +1 -0
  51. package/dist/cjs/utils/orderEntry.d.ts +6 -0
  52. package/dist/cjs/utils/orderEntry.d.ts.map +1 -0
  53. package/dist/cjs/utils/orderEntry.js +20 -0
  54. package/dist/cjs/utils/orderEntry.js.map +1 -0
  55. package/dist/cjs/utils/parse.d.ts +1 -0
  56. package/dist/cjs/utils/parse.d.ts.map +1 -1
  57. package/dist/cjs/utils/parse.js +15 -0
  58. package/dist/cjs/utils/parse.js.map +1 -1
  59. package/dist/cjs/utils/positionMath.d.ts +5 -0
  60. package/dist/cjs/utils/positionMath.d.ts.map +1 -1
  61. package/dist/cjs/utils/positionMath.js +53 -6
  62. package/dist/cjs/utils/positionMath.js.map +1 -1
  63. package/dist/cjs/version.d.ts +1 -1
  64. package/dist/cjs/version.js +1 -1
  65. package/dist/cjs/websocket/PerpsWsClient.d.ts +0 -1
  66. package/dist/cjs/websocket/PerpsWsClient.d.ts.map +1 -1
  67. package/dist/cjs/websocket/PerpsWsClient.js +0 -7
  68. package/dist/cjs/websocket/PerpsWsClient.js.map +1 -1
  69. package/dist/cjs/websocket/WsProviderBase.d.ts.map +1 -1
  70. package/dist/cjs/websocket/WsProviderBase.js +11 -3
  71. package/dist/cjs/websocket/WsProviderBase.js.map +1 -1
  72. package/dist/esm/client/PerpsClient.d.ts +8 -7
  73. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  74. package/dist/esm/client/PerpsClient.js +11 -7
  75. package/dist/esm/client/PerpsClient.js.map +1 -1
  76. package/dist/esm/client/createPerpsClient.d.ts +1 -12
  77. package/dist/esm/client/createPerpsClient.d.ts.map +1 -1
  78. package/dist/esm/client/createPerpsClient.js +1 -19
  79. package/dist/esm/client/createPerpsClient.js.map +1 -1
  80. package/dist/esm/client/requireProvider.d.ts +1 -1
  81. package/dist/esm/client/requireProvider.js +1 -1
  82. package/dist/esm/index.d.ts +6 -3
  83. package/dist/esm/index.d.ts.map +1 -1
  84. package/dist/esm/index.js +5 -2
  85. package/dist/esm/index.js.map +1 -1
  86. package/dist/esm/registry/assetRegistry.d.ts +2 -1
  87. package/dist/esm/registry/assetRegistry.d.ts.map +1 -1
  88. package/dist/esm/registry/assetRegistry.js +4 -2
  89. package/dist/esm/registry/assetRegistry.js.map +1 -1
  90. package/dist/esm/registry/marketRegistry.d.ts +2 -1
  91. package/dist/esm/registry/marketRegistry.d.ts.map +1 -1
  92. package/dist/esm/registry/marketRegistry.js +4 -2
  93. package/dist/esm/registry/marketRegistry.js.map +1 -1
  94. package/dist/esm/registry/referenceDataRegistry.d.ts +6 -6
  95. package/dist/esm/registry/referenceDataRegistry.d.ts.map +1 -1
  96. package/dist/esm/registry/referenceDataRegistry.js +68 -10
  97. package/dist/esm/registry/referenceDataRegistry.js.map +1 -1
  98. package/dist/esm/services/getOhlcv.d.ts +1 -0
  99. package/dist/esm/services/getOhlcv.d.ts.map +1 -1
  100. package/dist/esm/services/getOhlcv.js.map +1 -1
  101. package/dist/esm/transport/request.d.ts +2 -0
  102. package/dist/esm/transport/request.d.ts.map +1 -1
  103. package/dist/esm/transport/request.js +6 -2
  104. package/dist/esm/transport/request.js.map +1 -1
  105. package/dist/esm/types/api.d.ts +8 -22
  106. package/dist/esm/types/api.d.ts.map +1 -1
  107. package/dist/esm/types/config.d.ts +0 -27
  108. package/dist/esm/types/config.d.ts.map +1 -1
  109. package/dist/esm/types/provider.d.ts +7 -6
  110. package/dist/esm/types/provider.d.ts.map +1 -1
  111. package/dist/esm/types/withdrawal.d.ts +24 -15
  112. package/dist/esm/types/withdrawal.d.ts.map +1 -1
  113. package/dist/esm/utils/calculations.d.ts +3 -2
  114. package/dist/esm/utils/calculations.d.ts.map +1 -1
  115. package/dist/esm/utils/calculations.js +109 -39
  116. package/dist/esm/utils/calculations.js.map +1 -1
  117. package/dist/esm/utils/decimal.d.ts +14 -0
  118. package/dist/esm/utils/decimal.d.ts.map +1 -0
  119. package/dist/esm/utils/decimal.js +19 -0
  120. package/dist/esm/utils/decimal.js.map +1 -0
  121. package/dist/esm/utils/math.d.ts +6 -0
  122. package/dist/esm/utils/math.d.ts.map +1 -0
  123. package/dist/esm/utils/math.js +5 -0
  124. package/dist/esm/utils/math.js.map +1 -0
  125. package/dist/esm/utils/orderEntry.d.ts +26 -0
  126. package/dist/esm/utils/orderEntry.d.ts.map +1 -0
  127. package/dist/esm/utils/orderEntry.js +34 -0
  128. package/dist/esm/utils/orderEntry.js.map +1 -0
  129. package/dist/esm/utils/parse.d.ts +7 -0
  130. package/dist/esm/utils/parse.d.ts.map +1 -1
  131. package/dist/esm/utils/parse.js +20 -0
  132. package/dist/esm/utils/parse.js.map +1 -1
  133. package/dist/esm/utils/positionMath.d.ts +13 -0
  134. package/dist/esm/utils/positionMath.d.ts.map +1 -1
  135. package/dist/esm/utils/positionMath.js +60 -6
  136. package/dist/esm/utils/positionMath.js.map +1 -1
  137. package/dist/esm/version.d.ts +1 -1
  138. package/dist/esm/version.js +1 -1
  139. package/dist/esm/websocket/PerpsWsClient.d.ts +0 -7
  140. package/dist/esm/websocket/PerpsWsClient.d.ts.map +1 -1
  141. package/dist/esm/websocket/PerpsWsClient.js +0 -7
  142. package/dist/esm/websocket/PerpsWsClient.js.map +1 -1
  143. package/dist/esm/websocket/WsProviderBase.d.ts.map +1 -1
  144. package/dist/esm/websocket/WsProviderBase.js +11 -3
  145. package/dist/esm/websocket/WsProviderBase.js.map +1 -1
  146. package/dist/types/client/PerpsClient.d.ts +8 -7
  147. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  148. package/dist/types/client/createPerpsClient.d.ts +1 -12
  149. package/dist/types/client/createPerpsClient.d.ts.map +1 -1
  150. package/dist/types/client/requireProvider.d.ts +1 -1
  151. package/dist/types/index.d.ts +6 -3
  152. package/dist/types/index.d.ts.map +1 -1
  153. package/dist/types/registry/assetRegistry.d.ts +2 -1
  154. package/dist/types/registry/assetRegistry.d.ts.map +1 -1
  155. package/dist/types/registry/marketRegistry.d.ts +2 -1
  156. package/dist/types/registry/marketRegistry.d.ts.map +1 -1
  157. package/dist/types/registry/referenceDataRegistry.d.ts +6 -6
  158. package/dist/types/registry/referenceDataRegistry.d.ts.map +1 -1
  159. package/dist/types/services/getOhlcv.d.ts +1 -0
  160. package/dist/types/services/getOhlcv.d.ts.map +1 -1
  161. package/dist/types/transport/request.d.ts +2 -0
  162. package/dist/types/transport/request.d.ts.map +1 -1
  163. package/dist/types/types/api.d.ts +8 -22
  164. package/dist/types/types/api.d.ts.map +1 -1
  165. package/dist/types/types/config.d.ts +0 -27
  166. package/dist/types/types/config.d.ts.map +1 -1
  167. package/dist/types/types/provider.d.ts +7 -6
  168. package/dist/types/types/provider.d.ts.map +1 -1
  169. package/dist/types/types/withdrawal.d.ts +24 -15
  170. package/dist/types/types/withdrawal.d.ts.map +1 -1
  171. package/dist/types/utils/calculations.d.ts +3 -2
  172. package/dist/types/utils/calculations.d.ts.map +1 -1
  173. package/dist/types/utils/decimal.d.ts +14 -0
  174. package/dist/types/utils/decimal.d.ts.map +1 -0
  175. package/dist/types/utils/math.d.ts +6 -0
  176. package/dist/types/utils/math.d.ts.map +1 -0
  177. package/dist/types/utils/orderEntry.d.ts +26 -0
  178. package/dist/types/utils/orderEntry.d.ts.map +1 -0
  179. package/dist/types/utils/parse.d.ts +7 -0
  180. package/dist/types/utils/parse.d.ts.map +1 -1
  181. package/dist/types/utils/positionMath.d.ts +13 -0
  182. package/dist/types/utils/positionMath.d.ts.map +1 -1
  183. package/dist/types/version.d.ts +1 -1
  184. package/dist/types/websocket/PerpsWsClient.d.ts +0 -7
  185. package/dist/types/websocket/PerpsWsClient.d.ts.map +1 -1
  186. package/dist/types/websocket/WsProviderBase.d.ts.map +1 -1
  187. package/package.json +2 -2
  188. package/src/client/PerpsClient.ts +12 -8
  189. package/src/client/createPerpsClient.ts +4 -32
  190. package/src/client/requireProvider.ts +1 -1
  191. package/src/index.ts +10 -4
  192. package/src/registry/assetRegistry.ts +7 -5
  193. package/src/registry/marketRegistry.ts +7 -5
  194. package/src/registry/referenceDataRegistry.ts +89 -11
  195. package/src/services/getOhlcv.ts +1 -0
  196. package/src/transport/request.ts +12 -2
  197. package/src/types/api.ts +8 -26
  198. package/src/types/config.ts +0 -30
  199. package/src/types/provider.ts +8 -7
  200. package/src/types/withdrawal.ts +24 -15
  201. package/src/utils/calculations.ts +114 -43
  202. package/src/utils/decimal.ts +21 -0
  203. package/src/utils/math.ts +7 -0
  204. package/src/utils/orderEntry.ts +38 -0
  205. package/src/utils/parse.ts +25 -0
  206. package/src/utils/positionMath.ts +66 -6
  207. package/src/version.ts +1 -1
  208. package/src/websocket/PerpsWsClient.ts +0 -19
  209. package/src/websocket/WsProviderBase.ts +11 -3
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { PerpsErrorCode, } from '@lifi/perps-types';
9
9
  import { PerpsError } from '../errors/PerpsError.js';
10
+ import { areFinite, DivBig } from './decimal.js';
10
11
  /**
11
12
  * Calculate position size in asset units from margin.
12
13
  *
@@ -21,7 +22,13 @@ import { PerpsError } from '../errors/PerpsError.js';
21
22
  * @public
22
23
  */
23
24
  export function calculatePositionSize(marginUsd, leverage, price) {
24
- return (marginUsd * leverage) / price;
25
+ if (price === 0) {
26
+ return (marginUsd * leverage) / price;
27
+ }
28
+ if (!areFinite(marginUsd, leverage, price)) {
29
+ return Number.NaN;
30
+ }
31
+ return new DivBig(marginUsd).times(leverage).div(price).toNumber();
25
32
  }
26
33
  /**
27
34
  * Calculate notional value of a position.
@@ -32,7 +39,10 @@ export function calculatePositionSize(marginUsd, leverage, price) {
32
39
  * @public
33
40
  */
34
41
  export function calculateNotionalValue(size, price) {
35
- return Math.abs(size) * price;
42
+ if (!areFinite(size, price)) {
43
+ return Number.NaN;
44
+ }
45
+ return new DivBig(size).abs().times(price).toNumber();
36
46
  }
37
47
  /**
38
48
  * Calculate unrealized PnL.
@@ -44,7 +54,10 @@ export function calculateNotionalValue(size, price) {
44
54
  * @public
45
55
  */
46
56
  export function calculateUnrealizedPnl(entryPrice, currentPrice, size) {
47
- return (currentPrice - entryPrice) * size;
57
+ if (!areFinite(entryPrice, currentPrice, size)) {
58
+ return Number.NaN;
59
+ }
60
+ return new DivBig(currentPrice).minus(entryPrice).times(size).toNumber();
48
61
  }
49
62
  /**
50
63
  * Calculate return on equity (ROE) percentage.
@@ -58,7 +71,10 @@ export function calculateRoe(pnl, margin) {
58
71
  if (margin === 0) {
59
72
  return 0;
60
73
  }
61
- return (pnl / margin) * 100;
74
+ if (!areFinite(pnl, margin)) {
75
+ return Number.NaN;
76
+ }
77
+ return new DivBig(pnl).div(margin).times(100).toNumber();
62
78
  }
63
79
  /**
64
80
  * Calculate required margin for a position.
@@ -69,7 +85,13 @@ export function calculateRoe(pnl, margin) {
69
85
  * @public
70
86
  */
71
87
  export function calculateRequiredMargin(notionalValue, leverage) {
72
- return notionalValue / leverage;
88
+ if (leverage === 0) {
89
+ return notionalValue / leverage;
90
+ }
91
+ if (!areFinite(notionalValue, leverage)) {
92
+ return Number.NaN;
93
+ }
94
+ return new DivBig(notionalValue).div(leverage).toNumber();
73
95
  }
74
96
  /**
75
97
  * Estimate trading fees.
@@ -80,7 +102,10 @@ export function calculateRequiredMargin(notionalValue, leverage) {
80
102
  * @public
81
103
  */
82
104
  export function estimateFees(sizeUsd, feeRate) {
83
- return sizeUsd * feeRate;
105
+ if (!areFinite(sizeUsd, feeRate)) {
106
+ return Number.NaN;
107
+ }
108
+ return new DivBig(sizeUsd).times(feeRate).toNumber();
84
109
  }
85
110
  /**
86
111
  * Apply slippage to a price for order execution.
@@ -92,8 +117,17 @@ export function estimateFees(sizeUsd, feeRate) {
92
117
  * @public
93
118
  */
94
119
  export function applySlippage(price, slippagePercent, isBuy) {
95
- const multiplier = 1 + slippagePercent / 100;
96
- return isBuy ? price * multiplier : price / multiplier;
120
+ if (!areFinite(price, slippagePercent)) {
121
+ return Number.NaN;
122
+ }
123
+ const multiplier = new DivBig(slippagePercent).div(100).plus(1);
124
+ if (isBuy) {
125
+ return new DivBig(price).times(multiplier).toNumber();
126
+ }
127
+ if (multiplier.eq(0)) {
128
+ return price / multiplier.toNumber();
129
+ }
130
+ return new DivBig(price).div(multiplier).toNumber();
97
131
  }
98
132
  /**
99
133
  * Distance from the current price to the liquidation price, as a percentage of
@@ -126,7 +160,10 @@ export function effectiveLeverage(params) {
126
160
  if (marginUsd === 0) {
127
161
  return 0;
128
162
  }
129
- return positionValueUsd / marginUsd;
163
+ if (!areFinite(positionValueUsd, marginUsd)) {
164
+ return Number.NaN;
165
+ }
166
+ return new DivBig(positionValueUsd).div(marginUsd).toNumber();
130
167
  }
131
168
  /**
132
169
  * Calculate expected gain/loss for a TP or SL trigger price.
@@ -143,12 +180,15 @@ export function calculateExpectedPnl(triggerPrice, entryPrice, leverage, isLong,
143
180
  if (!triggerPrice || entryPrice === 0 || margin === 0) {
144
181
  return null;
145
182
  }
183
+ if (!areFinite(triggerPrice, entryPrice, leverage, margin)) {
184
+ return { amount: Number.NaN, percent: Number.NaN };
185
+ }
146
186
  const priceDiff = isLong
147
- ? triggerPrice - entryPrice
148
- : entryPrice - triggerPrice;
149
- const percent = (priceDiff / entryPrice) * leverage * 100;
150
- const amount = margin * (percent / 100);
151
- return { amount, percent };
187
+ ? new DivBig(triggerPrice).minus(entryPrice)
188
+ : new DivBig(entryPrice).minus(triggerPrice);
189
+ const percent = priceDiff.div(entryPrice).times(leverage).times(100);
190
+ const amount = percent.times(margin).div(100);
191
+ return { amount: amount.toNumber(), percent: percent.toNumber() };
152
192
  }
153
193
  /**
154
194
  * Convert a percentage gain/loss to a target price.
@@ -163,8 +203,14 @@ export function priceFromPercent(percent, entryPrice, leverage, isLong) {
163
203
  if (entryPrice === 0 || leverage === 0) {
164
204
  return 0;
165
205
  }
166
- const priceDelta = (percent / 100 / leverage) * entryPrice;
167
- return isLong ? entryPrice + priceDelta : entryPrice - priceDelta;
206
+ if (!areFinite(percent, entryPrice, leverage)) {
207
+ return Number.NaN;
208
+ }
209
+ const priceDelta = new DivBig(percent)
210
+ .times(entryPrice)
211
+ .div(new DivBig(leverage).times(100));
212
+ const entry = new DivBig(entryPrice);
213
+ return (isLong ? entry.plus(priceDelta) : entry.minus(priceDelta)).toNumber();
168
214
  }
169
215
  /**
170
216
  * Convert a target price to a percentage gain/loss.
@@ -179,8 +225,13 @@ export function percentFromPrice(price, entryPrice, leverage, isLong) {
179
225
  if (entryPrice === 0 || leverage === 0) {
180
226
  return 0;
181
227
  }
182
- const priceDiff = isLong ? price - entryPrice : entryPrice - price;
183
- return (priceDiff / entryPrice) * leverage * 100;
228
+ if (!areFinite(price, entryPrice, leverage)) {
229
+ return Number.NaN;
230
+ }
231
+ const priceDiff = isLong
232
+ ? new DivBig(price).minus(entryPrice)
233
+ : new DivBig(entryPrice).minus(price);
234
+ return priceDiff.div(entryPrice).times(leverage).times(100).toNumber();
184
235
  }
185
236
  /**
186
237
  * Calculate realized PnL as a percentage of position value at close.
@@ -192,11 +243,14 @@ export function percentFromPrice(price, entryPrice, leverage, isLong) {
192
243
  * @public
193
244
  */
194
245
  export function calculateRealizedPnlPercent(realizedPnl, size, price) {
195
- const positionValue = Math.abs(size) * price;
196
- if (positionValue === 0) {
246
+ if (!areFinite(realizedPnl, size, price)) {
247
+ return Number.NaN;
248
+ }
249
+ const positionValue = new DivBig(size).abs().times(price);
250
+ if (positionValue.eq(0)) {
197
251
  return 0;
198
252
  }
199
- return (realizedPnl / positionValue) * 100;
253
+ return new DivBig(realizedPnl).div(positionValue).times(100).toNumber();
200
254
  }
201
255
  /**
202
256
  * Walk one side of an orderbook to fill `sizeUsd` notional, accumulating base
@@ -204,38 +258,54 @@ export function calculateRealizedPnlPercent(realizedPnl, size, price) {
204
258
  * in array order — the caller passes asks for a buy and bids for a sell, each
205
259
  * already ordered best-price-first. When the book cannot absorb the full
206
260
  * notional, the walk stops at the last level and flags `insufficientLiquidity`,
207
- * returning the best obtainable fill.
261
+ * returning the best obtainable fill. A non-finite `sizeUsd` gives NaN fill
262
+ * fields with `insufficientLiquidity` set.
208
263
  *
209
264
  * @throws {PerpsError} `ValidationError` when a level's `price` or `size`
210
265
  * does not parse to a finite number.
211
266
  * @public
212
267
  */
213
268
  export function walkOrderbook(levels, sizeUsd) {
214
- let remaining = sizeUsd;
215
- let baseSize = 0;
216
- let filledNotional = 0;
269
+ if (!Number.isFinite(sizeUsd)) {
270
+ return {
271
+ baseSize: Number.NaN,
272
+ filledNotional: Number.NaN,
273
+ vwap: Number.NaN,
274
+ insufficientLiquidity: true,
275
+ };
276
+ }
277
+ let remaining = new DivBig(sizeUsd);
278
+ let baseSize = new DivBig(0);
279
+ let filledNotional = new DivBig(0);
217
280
  for (const level of levels) {
218
- if (remaining <= 0) {
281
+ if (remaining.lte(0)) {
219
282
  break;
220
283
  }
221
- const price = Number.parseFloat(level.price);
222
- const size = Number.parseFloat(level.size);
223
- if (!Number.isFinite(price) || !Number.isFinite(size)) {
224
- throw new PerpsError(PerpsErrorCode.ValidationError, `Malformed orderbook level: price='${level.price}', size='${level.size}'`);
284
+ const { price, size } = parseLevel(level);
285
+ const levelNotional = size.times(price);
286
+ const take = remaining.lt(levelNotional) ? remaining : levelNotional;
287
+ if (take.eq(0)) {
288
+ continue;
225
289
  }
226
- const levelNotional = size * price;
227
- const take = Math.min(remaining, levelNotional);
228
- filledNotional += take;
229
- baseSize += take / price;
230
- remaining -= take;
290
+ filledNotional = filledNotional.plus(take);
291
+ baseSize = baseSize.plus(take.div(price));
292
+ remaining = remaining.minus(take);
231
293
  }
232
294
  return {
233
- baseSize,
234
- filledNotional,
235
- vwap: baseSize === 0 ? 0 : filledNotional / baseSize,
236
- insufficientLiquidity: remaining > 0,
295
+ baseSize: baseSize.toNumber(),
296
+ filledNotional: filledNotional.toNumber(),
297
+ vwap: baseSize.eq(0) ? 0 : filledNotional.div(baseSize).toNumber(),
298
+ insufficientLiquidity: remaining.gt(0),
237
299
  };
238
300
  }
301
+ function parseLevel(level) {
302
+ try {
303
+ return { price: new DivBig(level.price), size: new DivBig(level.size) };
304
+ }
305
+ catch {
306
+ throw new PerpsError(PerpsErrorCode.ValidationError, `Malformed orderbook level: price='${level.price}', size='${level.size}'`);
307
+ }
308
+ }
239
309
  /**
240
310
  * Build a {@link Quote} from a resolved market, its live {@link MarketContext},
241
311
  * and its orderbook snapshot. Pure: walks the relevant side (buy → asks,
@@ -1 +1 @@
1
- {"version":3,"file":"calculations.js","sourceRoot":"","sources":["../../../src/utils/calculations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"calculations.js","sourceRoot":"","sources":["../../../src/utils/calculations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import Big from 'big.js';
2
+ /**
3
+ * Scoped big.js constructor with 40 decimal places for division, so the
4
+ * shared global `Big.DP` and `Big.RM` stay untouched.
5
+ */
6
+ export declare const DivBig: Big.BigConstructor;
7
+ /**
8
+ * As `DivBig`, but truncating, so a derived amount never rounds up past the
9
+ * exact quotient.
10
+ */
11
+ export declare const TruncBig: Big.BigConstructor;
12
+ /** True when every value is a finite number, so `new DivBig(value)` cannot throw. */
13
+ export declare function areFinite(...values: number[]): boolean;
14
+ //# sourceMappingURL=decimal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decimal.d.ts","sourceRoot":"","sources":["../../../src/utils/decimal.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,QAAQ,CAAA;AAExB;;;GAGG;AACH,eAAO,MAAM,MAAM,oBAAQ,CAAA;AAG3B;;;GAGG;AACH,eAAO,MAAM,QAAQ,oBAAQ,CAAA;AAI7B,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,19 @@
1
+ import Big from 'big.js';
2
+ /**
3
+ * Scoped big.js constructor with 40 decimal places for division, so the
4
+ * shared global `Big.DP` and `Big.RM` stay untouched.
5
+ */
6
+ export const DivBig = Big();
7
+ DivBig.DP = 40;
8
+ /**
9
+ * As `DivBig`, but truncating, so a derived amount never rounds up past the
10
+ * exact quotient.
11
+ */
12
+ export const TruncBig = Big();
13
+ TruncBig.DP = 40;
14
+ TruncBig.RM = Big.roundDown;
15
+ /** True when every value is a finite number, so `new DivBig(value)` cannot throw. */
16
+ export function areFinite(...values) {
17
+ return values.every(Number.isFinite);
18
+ }
19
+ //# sourceMappingURL=decimal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decimal.js","sourceRoot":"","sources":["../../../src/utils/decimal.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,QAAQ,CAAA;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAA;AAC3B,MAAM,CAAC,EAAE,GAAG,EAAE,CAAA;AAEd;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAA;AAC7B,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAA;AAChB,QAAQ,CAAC,EAAE,GAAG,GAAG,CAAC,SAAS,CAAA;AAE3B,qFAAqF;AACrF,MAAM,UAAU,SAAS,CAAC,GAAG,MAAgB;IAC3C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACtC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type Big from 'big.js';
2
+ /** The larger of two Big values, as `Math.max` for numbers. */
3
+ export declare const maxOf: (a: Big, b: Big) => Big;
4
+ /** The smaller of two Big values, as `Math.min` for numbers. */
5
+ export declare const minOf: (a: Big, b: Big) => Big;
6
+ //# sourceMappingURL=math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../../src/utils/math.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAA;AAE7B,+DAA+D;AAC/D,eAAO,MAAM,KAAK,GAAI,GAAG,GAAG,EAAE,GAAG,GAAG,KAAG,GAAwB,CAAA;AAE/D,gEAAgE;AAChE,eAAO,MAAM,KAAK,GAAI,GAAG,GAAG,EAAE,GAAG,GAAG,KAAG,GAAwB,CAAA"}
@@ -0,0 +1,5 @@
1
+ /** The larger of two Big values, as `Math.max` for numbers. */
2
+ export const maxOf = (a, b) => (a.gt(b) ? a : b);
3
+ /** The smaller of two Big values, as `Math.min` for numbers. */
4
+ export const minOf = (a, b) => (a.lt(b) ? a : b);
5
+ //# sourceMappingURL=math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.js","sourceRoot":"","sources":["../../../src/utils/math.ts"],"names":[],"mappings":"AAEA,+DAA+D;AAC/D,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAM,EAAE,CAAM,EAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/D,gEAAgE;AAChE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAM,EAAE,CAAM,EAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,26 @@
1
+ import type Big from 'big.js';
2
+ /**
3
+ * Base size the given margin buys at `leverage`: size = margin × leverage ÷ price.
4
+ * Truncates, so `size × price` never exceeds `margin × leverage`.
5
+ * @public
6
+ */
7
+ export declare function sizeFromMargin(margin: Big, leverage: number, price: Big): Big;
8
+ /**
9
+ * Margin that holds the given base size at `leverage`: margin = size × price ÷ leverage.
10
+ * Truncates, so `margin × leverage` never exceeds `size × price`.
11
+ * @public
12
+ */
13
+ export declare function marginFromSize(size: Big, leverage: number, price: Big): Big;
14
+ /**
15
+ * Base size for a notional: size = notional ÷ price.
16
+ * Truncates, so `size × price` never exceeds the notional.
17
+ * @public
18
+ */
19
+ export declare function sizeFromNotional(notionalUsd: Big, price: Big): Big;
20
+ /**
21
+ * Margin for a notional at `leverage`: margin = notional ÷ leverage.
22
+ * Truncates, so `margin × leverage` never exceeds the notional.
23
+ * @public
24
+ */
25
+ export declare function marginFromNotional(notionalUsd: Big, leverage: number): Big;
26
+ //# sourceMappingURL=orderEntry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orderEntry.d.ts","sourceRoot":"","sources":["../../../src/utils/orderEntry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAA;AAG7B;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAElE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE1E"}
@@ -0,0 +1,34 @@
1
+ import { TruncBig } from './decimal.js';
2
+ /**
3
+ * Base size the given margin buys at `leverage`: size = margin × leverage ÷ price.
4
+ * Truncates, so `size × price` never exceeds `margin × leverage`.
5
+ * @public
6
+ */
7
+ export function sizeFromMargin(margin, leverage, price) {
8
+ return new TruncBig(margin).times(leverage).div(price);
9
+ }
10
+ /**
11
+ * Margin that holds the given base size at `leverage`: margin = size × price ÷ leverage.
12
+ * Truncates, so `margin × leverage` never exceeds `size × price`.
13
+ * @public
14
+ */
15
+ export function marginFromSize(size, leverage, price) {
16
+ return new TruncBig(size).times(price).div(leverage);
17
+ }
18
+ /**
19
+ * Base size for a notional: size = notional ÷ price.
20
+ * Truncates, so `size × price` never exceeds the notional.
21
+ * @public
22
+ */
23
+ export function sizeFromNotional(notionalUsd, price) {
24
+ return new TruncBig(notionalUsd).div(price);
25
+ }
26
+ /**
27
+ * Margin for a notional at `leverage`: margin = notional ÷ leverage.
28
+ * Truncates, so `margin × leverage` never exceeds the notional.
29
+ * @public
30
+ */
31
+ export function marginFromNotional(notionalUsd, leverage) {
32
+ return new TruncBig(notionalUsd).div(leverage);
33
+ }
34
+ //# sourceMappingURL=orderEntry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orderEntry.js","sourceRoot":"","sources":["../../../src/utils/orderEntry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAW,EAAE,QAAgB,EAAE,KAAU;IACtE,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAS,EAAE,QAAgB,EAAE,KAAU;IACpE,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAgB,EAAE,KAAU;IAC3D,OAAO,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAgB,EAAE,QAAgB;IACnE,OAAO,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAChD,CAAC"}
@@ -18,4 +18,11 @@
18
18
  * @public
19
19
  */
20
20
  export declare function stringToFloat(value: string): number;
21
+ /**
22
+ * Parse an optional decimal field, with the same formatting tolerance as {@link stringToFloat}.
23
+ * Gives back `undefined` for a missing, malformed or non-finite value, and `0` for an empty string.
24
+ *
25
+ * @public
26
+ */
27
+ export declare function parseDecimal(value: string | null | undefined): number | undefined;
21
28
  //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/utils/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASnD"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/utils/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASnD;AAKD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,GAAG,SAAS,CAYpB"}
@@ -27,4 +27,24 @@ export function stringToFloat(value) {
27
27
  }
28
28
  return parseFloat(cleaned);
29
29
  }
30
+ const FORMATTED_NUMBER = /^(?:[+-]\s*)?(?:\$\s*)?(?:(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?(?:\s*(?:%|USD))?$/i;
31
+ /**
32
+ * Parse an optional decimal field, with the same formatting tolerance as {@link stringToFloat}.
33
+ * Gives back `undefined` for a missing, malformed or non-finite value, and `0` for an empty string.
34
+ *
35
+ * @public
36
+ */
37
+ export function parseDecimal(value) {
38
+ if (value == null) {
39
+ return undefined;
40
+ }
41
+ if (value.trim() === '') {
42
+ return stringToFloat(value);
43
+ }
44
+ if (!FORMATTED_NUMBER.test(value.trim())) {
45
+ return undefined;
46
+ }
47
+ const parsed = stringToFloat(value);
48
+ return Number.isFinite(parsed) ? parsed : undefined;
49
+ }
30
50
  //# sourceMappingURL=parse.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/utils/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,CAAA;IACV,CAAC;IACD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/utils/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,CAAA;IACV,CAAC;IACD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED,MAAM,gBAAgB,GACpB,2GAA2G,CAAA;AAE7G;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAgC;IAEhC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACzC,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AACrD,CAAC"}
@@ -37,6 +37,19 @@ export declare function estimateIsolatedLiquidationPrice(params: {
37
37
  isLong: boolean;
38
38
  maintenanceMarginRate: number;
39
39
  }): number | undefined;
40
+ /**
41
+ * Whether an isolated position with this liquidation price is already past
42
+ * liquidation at `currentPrice`: a long liquidates when the price falls to its
43
+ * liquidation level, a short when it rises to it. A non-positive price on
44
+ * either side counts as unknown, so the result is `false`.
45
+ *
46
+ * @public
47
+ */
48
+ export declare function wouldImmediatelyLiquidate(params: {
49
+ liquidationPrice: number;
50
+ currentPrice: number;
51
+ isLong: boolean;
52
+ }): boolean;
40
53
  /**
41
54
  * Predicted average entry price after adding to an existing position.
42
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"positionMath.d.ts","sourceRoot":"","sources":["../../../src/utils/positionMath.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAErD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACvD,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,qBAAqB,EAAE,MAAM,CAAA;CAC9B,GAAG,MAAM,GAAG,SAAS,CAYrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,MAAM,GAAG,SAAS,CAUrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,MAAM,GAAG,SAAS,CAOrB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,MAAM,CAGT;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,MAAM,CAGT"}
1
+ {"version":3,"file":"positionMath.d.ts","sourceRoot":"","sources":["../../../src/utils/positionMath.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAErD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACvD,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,qBAAqB,EAAE,MAAM,CAAA;CAC9B,GAAG,MAAM,GAAG,SAAS,CAqBrB;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,gBAAgB,EAAE,MAAM,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,OAAO,CAQV;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,MAAM,GAAG,SAAS,CAiBrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,MAAM,GAAG,SAAS,CAarB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,MAAM,CAUT;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,MAAM,CAUT"}
@@ -5,6 +5,7 @@
5
5
  * Sign convention: long = +1, short = -1. Sizes passed to these helpers are
6
6
  * always non-negative magnitudes; direction is carried by `isLong`.
7
7
  */
8
+ import { areFinite, DivBig } from './decimal.js';
8
9
  /**
9
10
  * Direction sign for a position.
10
11
  *
@@ -43,8 +44,34 @@ export function estimateIsolatedLiquidationPrice(params) {
43
44
  if (denominator === 0) {
44
45
  return undefined;
45
46
  }
46
- const marginAvailable = entryPrice * (1 / leverage - maintenanceMarginRate);
47
- return entryPrice - (side * marginAvailable) / denominator;
47
+ if (!areFinite(entryPrice, leverage, maintenanceMarginRate)) {
48
+ return Number.NaN;
49
+ }
50
+ const mmr = new DivBig(maintenanceMarginRate);
51
+ const marginAvailable = new DivBig(1)
52
+ .div(leverage)
53
+ .minus(mmr)
54
+ .times(entryPrice);
55
+ return new DivBig(entryPrice)
56
+ .minus(marginAvailable.times(side).div(mmr.times(-side).plus(1)))
57
+ .toNumber();
58
+ }
59
+ /**
60
+ * Whether an isolated position with this liquidation price is already past
61
+ * liquidation at `currentPrice`: a long liquidates when the price falls to its
62
+ * liquidation level, a short when it rises to it. A non-positive price on
63
+ * either side counts as unknown, so the result is `false`.
64
+ *
65
+ * @public
66
+ */
67
+ export function wouldImmediatelyLiquidate(params) {
68
+ const { liquidationPrice, currentPrice, isLong } = params;
69
+ if (currentPrice <= 0 || liquidationPrice <= 0) {
70
+ return false;
71
+ }
72
+ return isLong
73
+ ? liquidationPrice >= currentPrice
74
+ : liquidationPrice <= currentPrice;
48
75
  }
49
76
  /**
50
77
  * Predicted average entry price after adding to an existing position.
@@ -71,7 +98,14 @@ export function predictAverageEntryPrice(params) {
71
98
  if (!Number.isFinite(currentEntry) || !Number.isFinite(fillPrice)) {
72
99
  return undefined;
73
100
  }
74
- return (currentSize * currentEntry + addSize * fillPrice) / totalSize;
101
+ if (!areFinite(currentSize, addSize)) {
102
+ return Number.NaN;
103
+ }
104
+ return new DivBig(currentSize)
105
+ .times(currentEntry)
106
+ .plus(new DivBig(addSize).times(fillPrice))
107
+ .div(new DivBig(currentSize).plus(addSize))
108
+ .toNumber();
75
109
  }
76
110
  /**
77
111
  * Predicted effective leverage after adding margin and notional.
@@ -90,7 +124,13 @@ export function predictNewLeverage(params) {
90
124
  if (totalMargin <= 0) {
91
125
  return undefined;
92
126
  }
93
- return (currentNotional + addNotional) / totalMargin;
127
+ if (!areFinite(currentNotional, currentMargin, addNotional, addMargin)) {
128
+ return Number.NaN;
129
+ }
130
+ return new DivBig(currentNotional)
131
+ .plus(addNotional)
132
+ .div(new DivBig(currentMargin).plus(addMargin))
133
+ .toNumber();
94
134
  }
95
135
  /**
96
136
  * Predicted unrealised PnL at the current mark price.
@@ -102,7 +142,14 @@ export function predictNewLeverage(params) {
102
142
  */
103
143
  export function predictUnrealizedPnl(params) {
104
144
  const { entryPrice, markPrice, size, isLong } = params;
105
- return (markPrice - entryPrice) * size * directionSign(isLong);
145
+ if (!areFinite(entryPrice, markPrice, size)) {
146
+ return Number.NaN;
147
+ }
148
+ return new DivBig(markPrice)
149
+ .minus(entryPrice)
150
+ .times(size)
151
+ .times(directionSign(isLong))
152
+ .toNumber();
106
153
  }
107
154
  /**
108
155
  * Realised PnL on the portion of a position being closed.
@@ -114,6 +161,13 @@ export function predictUnrealizedPnl(params) {
114
161
  */
115
162
  export function realizedPnlOnClose(params) {
116
163
  const { entryPrice, closePrice, closeSize, isLong } = params;
117
- return (closePrice - entryPrice) * closeSize * directionSign(isLong);
164
+ if (!areFinite(entryPrice, closePrice, closeSize)) {
165
+ return Number.NaN;
166
+ }
167
+ return new DivBig(closePrice)
168
+ .minus(entryPrice)
169
+ .times(closeSize)
170
+ .times(directionSign(isLong))
171
+ .toNumber();
118
172
  }
119
173
  //# sourceMappingURL=positionMath.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"positionMath.js","sourceRoot":"","sources":["../../../src/utils/positionMath.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC3C,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACxB,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAKhD;IACC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAAA;IACtE,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IAClC,MAAM,WAAW,GAAG,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAA;IACpD,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,eAAe,GAAG,UAAU,GAAG,CAAC,CAAC,GAAG,QAAQ,GAAG,qBAAqB,CAAC,CAAA;IAC3E,OAAO,UAAU,GAAG,CAAC,IAAI,GAAG,eAAe,CAAC,GAAG,WAAW,CAAA;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAKxC;IACC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAChE,MAAM,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;IACvC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAClE,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,CAAC,WAAW,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;AACvE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAKlC;IACC,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IACzE,MAAM,WAAW,GAAG,aAAa,GAAG,SAAS,CAAA;IAC7C,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,WAAW,CAAA;AACtD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAKpC;IACC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACtD,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;AAChE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAKlC;IACC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAC5D,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;AACtE,CAAC"}
1
+ {"version":3,"file":"positionMath.js","sourceRoot":"","sources":["../../../src/utils/positionMath.ts"],"names":[],"mappings":"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"}