@lifi/perps-sdk 20.1.0 → 21.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.
Files changed (320) hide show
  1. package/README.md +81 -6
  2. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  3. package/dist/cjs/client/PerpsClient.js +4 -1
  4. package/dist/cjs/client/PerpsClient.js.map +1 -1
  5. package/dist/cjs/{utils/decimal.d.ts → decimal/big.d.ts} +1 -1
  6. package/dist/cjs/decimal/big.d.ts.map +1 -0
  7. package/dist/cjs/{utils/decimal.js → decimal/big.js} +1 -1
  8. package/dist/cjs/decimal/big.js.map +1 -0
  9. package/dist/cjs/decimal/convert.d.ts +11 -0
  10. package/dist/cjs/decimal/convert.d.ts.map +1 -0
  11. package/dist/cjs/decimal/convert.js +70 -0
  12. package/dist/cjs/decimal/convert.js.map +1 -0
  13. package/dist/cjs/decimal/format.d.ts.map +1 -0
  14. package/dist/cjs/decimal/format.js.map +1 -0
  15. package/dist/cjs/decimal/parse.d.ts +6 -0
  16. package/dist/cjs/decimal/parse.d.ts.map +1 -0
  17. package/dist/cjs/{utils → decimal}/parse.js +5 -4
  18. package/dist/cjs/decimal/parse.js.map +1 -0
  19. package/dist/cjs/index.d.ts +17 -15
  20. package/dist/cjs/index.d.ts.map +1 -1
  21. package/dist/cjs/index.js +75 -61
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/cjs/math/fills.d.ts +5 -0
  24. package/dist/cjs/math/fills.d.ts.map +1 -0
  25. package/dist/cjs/{utils/fillClassification.js → math/fills.js} +16 -1
  26. package/dist/cjs/math/fills.js.map +1 -0
  27. package/dist/cjs/math/order.d.ts +45 -0
  28. package/dist/cjs/math/order.d.ts.map +1 -0
  29. package/dist/cjs/math/order.js +256 -0
  30. package/dist/cjs/math/order.js.map +1 -0
  31. package/dist/cjs/math/position.d.ts +56 -0
  32. package/dist/cjs/math/position.d.ts.map +1 -0
  33. package/dist/cjs/math/position.js +160 -0
  34. package/dist/cjs/math/position.js.map +1 -0
  35. package/dist/cjs/services/resolveQuote.d.ts.map +1 -1
  36. package/dist/cjs/services/resolveQuote.js +2 -2
  37. package/dist/cjs/services/resolveQuote.js.map +1 -1
  38. package/dist/cjs/services/resolveSubscribeQuote.d.ts.map +1 -1
  39. package/dist/cjs/services/resolveSubscribeQuote.js +2 -2
  40. package/dist/cjs/services/resolveSubscribeQuote.js.map +1 -1
  41. package/dist/cjs/types/provider.d.ts +3 -3
  42. package/dist/cjs/types/provider.d.ts.map +1 -1
  43. package/dist/cjs/types/withdrawal.d.ts +7 -5
  44. package/dist/cjs/types/withdrawal.d.ts.map +1 -1
  45. package/dist/cjs/utils/orderClassification.d.ts +1 -3
  46. package/dist/cjs/utils/orderClassification.d.ts.map +1 -1
  47. package/dist/cjs/utils/orderClassification.js +1 -15
  48. package/dist/cjs/utils/orderClassification.js.map +1 -1
  49. package/dist/cjs/version.d.ts +1 -1
  50. package/dist/cjs/version.js +1 -1
  51. package/dist/cjs/wire/orderAmounts.d.ts +18 -0
  52. package/dist/cjs/wire/orderAmounts.d.ts.map +1 -0
  53. package/dist/cjs/wire/orderAmounts.js +79 -0
  54. package/dist/cjs/wire/orderAmounts.js.map +1 -0
  55. package/dist/cjs/wire/refuel.d.ts +8 -0
  56. package/dist/cjs/wire/refuel.d.ts.map +1 -0
  57. package/dist/cjs/wire/refuel.js +23 -0
  58. package/dist/cjs/wire/refuel.js.map +1 -0
  59. package/dist/cjs/wire/requireDecimal.d.ts +4 -0
  60. package/dist/cjs/wire/requireDecimal.d.ts.map +1 -0
  61. package/dist/cjs/wire/requireDecimal.js +16 -0
  62. package/dist/cjs/wire/requireDecimal.js.map +1 -0
  63. package/dist/cjs/wire/snap.d.ts +5 -0
  64. package/dist/cjs/wire/snap.d.ts.map +1 -0
  65. package/dist/cjs/wire/snap.js +12 -0
  66. package/dist/cjs/wire/snap.js.map +1 -0
  67. package/dist/cjs/wire/transferable.d.ts +3 -0
  68. package/dist/cjs/wire/transferable.d.ts.map +1 -0
  69. package/dist/cjs/wire/transferable.js +13 -0
  70. package/dist/cjs/wire/transferable.js.map +1 -0
  71. package/dist/cjs/wire/withdraw.d.ts +4 -0
  72. package/dist/cjs/wire/withdraw.d.ts.map +1 -0
  73. package/dist/cjs/wire/withdraw.js +13 -0
  74. package/dist/cjs/wire/withdraw.js.map +1 -0
  75. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  76. package/dist/esm/client/PerpsClient.js +4 -1
  77. package/dist/esm/client/PerpsClient.js.map +1 -1
  78. package/dist/esm/{utils/decimal.d.ts → decimal/big.d.ts} +1 -1
  79. package/dist/esm/decimal/big.d.ts.map +1 -0
  80. package/dist/esm/{utils/decimal.js → decimal/big.js} +1 -1
  81. package/dist/esm/decimal/big.js.map +1 -0
  82. package/dist/esm/decimal/convert.d.ts +80 -0
  83. package/dist/esm/decimal/convert.d.ts.map +1 -0
  84. package/dist/esm/decimal/convert.js +118 -0
  85. package/dist/esm/decimal/convert.js.map +1 -0
  86. package/dist/esm/decimal/format.d.ts.map +1 -0
  87. package/dist/esm/decimal/format.js.map +1 -0
  88. package/dist/esm/decimal/parse.d.ts +29 -0
  89. package/dist/esm/decimal/parse.d.ts.map +1 -0
  90. package/dist/esm/{utils → decimal}/parse.js +9 -10
  91. package/dist/esm/decimal/parse.js.map +1 -0
  92. package/dist/esm/index.d.ts +17 -15
  93. package/dist/esm/index.d.ts.map +1 -1
  94. package/dist/esm/index.js +12 -12
  95. package/dist/esm/index.js.map +1 -1
  96. package/dist/esm/math/fills.d.ts +26 -0
  97. package/dist/esm/math/fills.d.ts.map +1 -0
  98. package/dist/esm/{utils/fillClassification.js → math/fills.js} +26 -2
  99. package/dist/esm/math/fills.js.map +1 -0
  100. package/dist/esm/{utils/calculations.d.ts → math/order.d.ts} +70 -75
  101. package/dist/esm/math/order.d.ts.map +1 -0
  102. package/dist/esm/{utils/calculations.js → math/order.js} +155 -111
  103. package/dist/esm/math/order.js.map +1 -0
  104. package/dist/esm/math/position.d.ts +211 -0
  105. package/dist/esm/math/position.d.ts.map +1 -0
  106. package/dist/esm/math/position.js +299 -0
  107. package/dist/esm/math/position.js.map +1 -0
  108. package/dist/esm/services/resolveQuote.d.ts.map +1 -1
  109. package/dist/esm/services/resolveQuote.js +1 -1
  110. package/dist/esm/services/resolveQuote.js.map +1 -1
  111. package/dist/esm/services/resolveSubscribeQuote.d.ts.map +1 -1
  112. package/dist/esm/services/resolveSubscribeQuote.js +1 -1
  113. package/dist/esm/services/resolveSubscribeQuote.js.map +1 -1
  114. package/dist/esm/types/provider.d.ts +23 -11
  115. package/dist/esm/types/provider.d.ts.map +1 -1
  116. package/dist/esm/types/withdrawal.d.ts +17 -5
  117. package/dist/esm/types/withdrawal.d.ts.map +1 -1
  118. package/dist/esm/utils/orderClassification.d.ts +1 -14
  119. package/dist/esm/utils/orderClassification.d.ts.map +1 -1
  120. package/dist/esm/utils/orderClassification.js +1 -25
  121. package/dist/esm/utils/orderClassification.js.map +1 -1
  122. package/dist/esm/version.d.ts +1 -1
  123. package/dist/esm/version.js +1 -1
  124. package/dist/esm/wire/orderAmounts.d.ts +55 -0
  125. package/dist/esm/wire/orderAmounts.d.ts.map +1 -0
  126. package/dist/esm/wire/orderAmounts.js +114 -0
  127. package/dist/esm/wire/orderAmounts.js.map +1 -0
  128. package/dist/esm/wire/refuel.d.ts +28 -0
  129. package/dist/esm/wire/refuel.d.ts.map +1 -0
  130. package/dist/esm/wire/refuel.js +36 -0
  131. package/dist/esm/wire/refuel.js.map +1 -0
  132. package/dist/esm/wire/requireDecimal.d.ts +11 -0
  133. package/dist/esm/wire/requireDecimal.d.ts.map +1 -0
  134. package/dist/esm/wire/requireDecimal.js +17 -0
  135. package/dist/esm/wire/requireDecimal.js.map +1 -0
  136. package/dist/esm/wire/snap.d.ts +24 -0
  137. package/dist/esm/wire/snap.d.ts.map +1 -0
  138. package/dist/esm/wire/snap.js +27 -0
  139. package/dist/esm/wire/snap.js.map +1 -0
  140. package/dist/esm/wire/transferable.d.ts +15 -0
  141. package/dist/esm/wire/transferable.d.ts.map +1 -0
  142. package/dist/esm/wire/transferable.js +22 -0
  143. package/dist/esm/wire/transferable.js.map +1 -0
  144. package/dist/esm/wire/withdraw.d.ts +14 -0
  145. package/dist/esm/wire/withdraw.d.ts.map +1 -0
  146. package/dist/esm/wire/withdraw.js +20 -0
  147. package/dist/esm/wire/withdraw.js.map +1 -0
  148. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  149. package/dist/types/{utils/decimal.d.ts → decimal/big.d.ts} +1 -1
  150. package/dist/types/decimal/big.d.ts.map +1 -0
  151. package/dist/types/decimal/convert.d.ts +80 -0
  152. package/dist/types/decimal/convert.d.ts.map +1 -0
  153. package/dist/types/decimal/format.d.ts.map +1 -0
  154. package/dist/types/decimal/parse.d.ts +29 -0
  155. package/dist/types/decimal/parse.d.ts.map +1 -0
  156. package/dist/types/index.d.ts +17 -15
  157. package/dist/types/index.d.ts.map +1 -1
  158. package/dist/types/math/fills.d.ts +26 -0
  159. package/dist/types/math/fills.d.ts.map +1 -0
  160. package/dist/types/{utils/calculations.d.ts → math/order.d.ts} +70 -75
  161. package/dist/types/math/order.d.ts.map +1 -0
  162. package/dist/types/math/position.d.ts +211 -0
  163. package/dist/types/math/position.d.ts.map +1 -0
  164. package/dist/types/services/resolveQuote.d.ts.map +1 -1
  165. package/dist/types/services/resolveSubscribeQuote.d.ts.map +1 -1
  166. package/dist/types/types/provider.d.ts +23 -11
  167. package/dist/types/types/provider.d.ts.map +1 -1
  168. package/dist/types/types/withdrawal.d.ts +17 -5
  169. package/dist/types/types/withdrawal.d.ts.map +1 -1
  170. package/dist/types/utils/orderClassification.d.ts +1 -14
  171. package/dist/types/utils/orderClassification.d.ts.map +1 -1
  172. package/dist/types/version.d.ts +1 -1
  173. package/dist/types/wire/orderAmounts.d.ts +55 -0
  174. package/dist/types/wire/orderAmounts.d.ts.map +1 -0
  175. package/dist/types/wire/refuel.d.ts +28 -0
  176. package/dist/types/wire/refuel.d.ts.map +1 -0
  177. package/dist/types/wire/requireDecimal.d.ts +11 -0
  178. package/dist/types/wire/requireDecimal.d.ts.map +1 -0
  179. package/dist/types/wire/snap.d.ts +24 -0
  180. package/dist/types/wire/snap.d.ts.map +1 -0
  181. package/dist/types/wire/transferable.d.ts +15 -0
  182. package/dist/types/wire/transferable.d.ts.map +1 -0
  183. package/dist/types/wire/withdraw.d.ts +14 -0
  184. package/dist/types/wire/withdraw.d.ts.map +1 -0
  185. package/package.json +2 -2
  186. package/src/client/PerpsClient.ts +4 -1
  187. package/src/decimal/convert.ts +164 -0
  188. package/src/{utils → decimal}/parse.ts +13 -11
  189. package/src/index.ts +80 -57
  190. package/src/{utils/fillClassification.ts → math/fills.ts} +30 -1
  191. package/src/{utils/calculations.ts → math/order.ts} +205 -127
  192. package/src/{utils/positionMath.ts → math/position.ts} +173 -21
  193. package/src/services/resolveQuote.ts +1 -1
  194. package/src/services/resolveSubscribeQuote.ts +1 -1
  195. package/src/types/provider.ts +23 -10
  196. package/src/types/withdrawal.ts +22 -5
  197. package/src/utils/orderClassification.ts +0 -30
  198. package/src/version.ts +1 -1
  199. package/src/wire/orderAmounts.ts +172 -0
  200. package/src/wire/refuel.ts +51 -0
  201. package/src/wire/requireDecimal.ts +24 -0
  202. package/src/wire/snap.ts +38 -0
  203. package/src/wire/transferable.ts +26 -0
  204. package/src/wire/withdraw.ts +29 -0
  205. package/dist/cjs/utils/calculations.d.ts +0 -47
  206. package/dist/cjs/utils/calculations.d.ts.map +0 -1
  207. package/dist/cjs/utils/calculations.js +0 -214
  208. package/dist/cjs/utils/calculations.js.map +0 -1
  209. package/dist/cjs/utils/decimal.d.ts.map +0 -1
  210. package/dist/cjs/utils/decimal.js.map +0 -1
  211. package/dist/cjs/utils/fillClassification.d.ts +0 -3
  212. package/dist/cjs/utils/fillClassification.d.ts.map +0 -1
  213. package/dist/cjs/utils/fillClassification.js.map +0 -1
  214. package/dist/cjs/utils/format.d.ts.map +0 -1
  215. package/dist/cjs/utils/format.js.map +0 -1
  216. package/dist/cjs/utils/math.d.ts +0 -4
  217. package/dist/cjs/utils/math.d.ts.map +0 -1
  218. package/dist/cjs/utils/math.js +0 -8
  219. package/dist/cjs/utils/math.js.map +0 -1
  220. package/dist/cjs/utils/orderEntry.d.ts +0 -6
  221. package/dist/cjs/utils/orderEntry.d.ts.map +0 -1
  222. package/dist/cjs/utils/orderEntry.js +0 -20
  223. package/dist/cjs/utils/orderEntry.js.map +0 -1
  224. package/dist/cjs/utils/orderMath.d.ts +0 -6
  225. package/dist/cjs/utils/orderMath.d.ts.map +0 -1
  226. package/dist/cjs/utils/orderMath.js +0 -85
  227. package/dist/cjs/utils/orderMath.js.map +0 -1
  228. package/dist/cjs/utils/parse.d.ts +0 -3
  229. package/dist/cjs/utils/parse.d.ts.map +0 -1
  230. package/dist/cjs/utils/parse.js.map +0 -1
  231. package/dist/cjs/utils/positionMath.d.ts +0 -37
  232. package/dist/cjs/utils/positionMath.d.ts.map +0 -1
  233. package/dist/cjs/utils/positionMath.js +0 -99
  234. package/dist/cjs/utils/positionMath.js.map +0 -1
  235. package/dist/cjs/utils/scaleToInteger.d.ts +0 -3
  236. package/dist/cjs/utils/scaleToInteger.d.ts.map +0 -1
  237. package/dist/cjs/utils/scaleToInteger.js +0 -30
  238. package/dist/cjs/utils/scaleToInteger.js.map +0 -1
  239. package/dist/cjs/utils/units.d.ts +0 -3
  240. package/dist/cjs/utils/units.d.ts.map +0 -1
  241. package/dist/cjs/utils/units.js +0 -18
  242. package/dist/cjs/utils/units.js.map +0 -1
  243. package/dist/cjs/utils/validation.d.ts +0 -2
  244. package/dist/cjs/utils/validation.d.ts.map +0 -1
  245. package/dist/cjs/utils/validation.js +0 -16
  246. package/dist/cjs/utils/validation.js.map +0 -1
  247. package/dist/esm/utils/calculations.d.ts.map +0 -1
  248. package/dist/esm/utils/calculations.js.map +0 -1
  249. package/dist/esm/utils/decimal.d.ts.map +0 -1
  250. package/dist/esm/utils/decimal.js.map +0 -1
  251. package/dist/esm/utils/fillClassification.d.ts +0 -13
  252. package/dist/esm/utils/fillClassification.d.ts.map +0 -1
  253. package/dist/esm/utils/fillClassification.js.map +0 -1
  254. package/dist/esm/utils/format.d.ts.map +0 -1
  255. package/dist/esm/utils/format.js.map +0 -1
  256. package/dist/esm/utils/math.d.ts +0 -6
  257. package/dist/esm/utils/math.d.ts.map +0 -1
  258. package/dist/esm/utils/math.js +0 -5
  259. package/dist/esm/utils/math.js.map +0 -1
  260. package/dist/esm/utils/orderEntry.d.ts +0 -26
  261. package/dist/esm/utils/orderEntry.d.ts.map +0 -1
  262. package/dist/esm/utils/orderEntry.js +0 -34
  263. package/dist/esm/utils/orderEntry.js.map +0 -1
  264. package/dist/esm/utils/orderMath.d.ts +0 -37
  265. package/dist/esm/utils/orderMath.d.ts.map +0 -1
  266. package/dist/esm/utils/orderMath.js +0 -113
  267. package/dist/esm/utils/orderMath.js.map +0 -1
  268. package/dist/esm/utils/parse.d.ts +0 -28
  269. package/dist/esm/utils/parse.d.ts.map +0 -1
  270. package/dist/esm/utils/parse.js.map +0 -1
  271. package/dist/esm/utils/positionMath.d.ts +0 -120
  272. package/dist/esm/utils/positionMath.d.ts.map +0 -1
  273. package/dist/esm/utils/positionMath.js +0 -173
  274. package/dist/esm/utils/positionMath.js.map +0 -1
  275. package/dist/esm/utils/scaleToInteger.d.ts +0 -22
  276. package/dist/esm/utils/scaleToInteger.d.ts.map +0 -1
  277. package/dist/esm/utils/scaleToInteger.js +0 -34
  278. package/dist/esm/utils/scaleToInteger.js.map +0 -1
  279. package/dist/esm/utils/units.d.ts +0 -27
  280. package/dist/esm/utils/units.d.ts.map +0 -1
  281. package/dist/esm/utils/units.js +0 -38
  282. package/dist/esm/utils/units.js.map +0 -1
  283. package/dist/esm/utils/validation.d.ts +0 -18
  284. package/dist/esm/utils/validation.d.ts.map +0 -1
  285. package/dist/esm/utils/validation.js +0 -29
  286. package/dist/esm/utils/validation.js.map +0 -1
  287. package/dist/types/utils/calculations.d.ts.map +0 -1
  288. package/dist/types/utils/decimal.d.ts.map +0 -1
  289. package/dist/types/utils/fillClassification.d.ts +0 -13
  290. package/dist/types/utils/fillClassification.d.ts.map +0 -1
  291. package/dist/types/utils/format.d.ts.map +0 -1
  292. package/dist/types/utils/math.d.ts +0 -6
  293. package/dist/types/utils/math.d.ts.map +0 -1
  294. package/dist/types/utils/orderEntry.d.ts +0 -26
  295. package/dist/types/utils/orderEntry.d.ts.map +0 -1
  296. package/dist/types/utils/orderMath.d.ts +0 -37
  297. package/dist/types/utils/orderMath.d.ts.map +0 -1
  298. package/dist/types/utils/parse.d.ts +0 -28
  299. package/dist/types/utils/parse.d.ts.map +0 -1
  300. package/dist/types/utils/positionMath.d.ts +0 -120
  301. package/dist/types/utils/positionMath.d.ts.map +0 -1
  302. package/dist/types/utils/scaleToInteger.d.ts +0 -22
  303. package/dist/types/utils/scaleToInteger.d.ts.map +0 -1
  304. package/dist/types/utils/units.d.ts +0 -27
  305. package/dist/types/utils/units.d.ts.map +0 -1
  306. package/dist/types/utils/validation.d.ts +0 -18
  307. package/dist/types/utils/validation.d.ts.map +0 -1
  308. package/src/utils/math.ts +0 -7
  309. package/src/utils/orderEntry.ts +0 -38
  310. package/src/utils/orderMath.ts +0 -152
  311. package/src/utils/scaleToInteger.ts +0 -56
  312. package/src/utils/units.ts +0 -39
  313. package/src/utils/validation.ts +0 -38
  314. /package/dist/cjs/{utils → decimal}/format.d.ts +0 -0
  315. /package/dist/cjs/{utils → decimal}/format.js +0 -0
  316. /package/dist/esm/{utils → decimal}/format.d.ts +0 -0
  317. /package/dist/esm/{utils → decimal}/format.js +0 -0
  318. /package/dist/types/{utils → decimal}/format.d.ts +0 -0
  319. /package/src/{utils/decimal.ts → decimal/big.ts} +0 -0
  320. /package/src/{utils → decimal}/format.ts +0 -0
@@ -1,24 +1,151 @@
1
1
  /**
2
- * Pure-function helpers for predicting how a perp position changes after a
3
- * fill.
2
+ * Display-tier position formulas. Every function takes and gives `number`;
3
+ * exact decimal arithmetic happens internally with `DivBig`.
4
4
  *
5
- * Sign convention: long = +1, short = -1. Sizes passed to these helpers are
6
- * always non-negative magnitudes; direction is carried by `isLong`.
5
+ * Sign convention: long = +1, short = -1. Sizes passed to the `estimate*`
6
+ * helpers are always non-negative magnitudes; direction is carried by
7
+ * `isLong`.
7
8
  */
8
9
 
9
- import { areFinite, DivBig } from './decimal.js'
10
+ import { areFinite, DivBig } from '../decimal/big.js'
10
11
 
11
12
  /**
12
13
  * Direction sign for a position.
13
14
  *
14
- * @param isLong - True for long positions, false for short.
15
- * @returns +1 for long, -1 for short.
16
- * @public
15
+ * @deprecated Inline `isLong ? 1 : -1`. Removed in the next major.
17
16
  */
18
17
  export function directionSign(isLong: boolean): 1 | -1 {
19
18
  return isLong ? 1 : -1
20
19
  }
21
20
 
21
+ /**
22
+ * Calculate notional value of a position.
23
+ *
24
+ * @param size - Position size in asset units
25
+ * @param price - Current asset price
26
+ * @returns Notional value in USD
27
+ * @public
28
+ */
29
+ export function calculateNotionalValue(size: number, price: number): number {
30
+ if (!areFinite(size, price)) {
31
+ return Number.NaN
32
+ }
33
+ return new DivBig(size).abs().times(price).toNumber()
34
+ }
35
+
36
+ /**
37
+ * Calculate unrealized PnL.
38
+ *
39
+ * @param entryPrice - Position entry price
40
+ * @param currentPrice - Current market price
41
+ * @param size - Position size (positive for long, negative for short)
42
+ * @returns Unrealized PnL in USD
43
+ * @public
44
+ */
45
+ export function calculateUnrealizedPnl(
46
+ entryPrice: number,
47
+ currentPrice: number,
48
+ size: number
49
+ ): number {
50
+ if (!areFinite(entryPrice, currentPrice, size)) {
51
+ return Number.NaN
52
+ }
53
+ return new DivBig(currentPrice).minus(entryPrice).times(size).toNumber()
54
+ }
55
+
56
+ /**
57
+ * Calculate return on equity (ROE) percentage.
58
+ *
59
+ * @param pnl - Profit/loss in USD
60
+ * @param margin - Initial margin in USD
61
+ * @returns ROE as percentage (e.g., 10 for 10%)
62
+ * @public
63
+ */
64
+ export function calculateRoe(pnl: number, margin: number): number {
65
+ if (margin === 0) {
66
+ return 0
67
+ }
68
+ if (!areFinite(pnl, margin)) {
69
+ return Number.NaN
70
+ }
71
+ return new DivBig(pnl).div(margin).times(100).toNumber()
72
+ }
73
+
74
+ /**
75
+ * Calculate required margin for a position.
76
+ *
77
+ * @param notionalValue - Position notional value in USD
78
+ * @param leverage - Position leverage
79
+ * @returns Required margin in USD
80
+ * @public
81
+ */
82
+ export function calculateRequiredMargin(
83
+ notionalValue: number,
84
+ leverage: number
85
+ ): number {
86
+ if (leverage === 0) {
87
+ return notionalValue / leverage
88
+ }
89
+ if (!areFinite(notionalValue, leverage)) {
90
+ return Number.NaN
91
+ }
92
+ return new DivBig(notionalValue).div(leverage).toNumber()
93
+ }
94
+
95
+ /**
96
+ * Distance from the current price to the liquidation price, as a percentage of
97
+ * the current price.
98
+ *
99
+ * @param liquidationPrice - The position's liquidation price
100
+ * @param currentPrice - Current market price
101
+ * @returns Absolute distance as a percentage, or 0 when current price is zero
102
+ * @public
103
+ */
104
+ export function calculateLiquidationDistance(params: {
105
+ liquidationPrice: number
106
+ currentPrice: number
107
+ }): number {
108
+ const { liquidationPrice, currentPrice } = params
109
+ if (currentPrice === 0) {
110
+ return 0
111
+ }
112
+ return Math.abs((liquidationPrice - currentPrice) / currentPrice) * 100
113
+ }
114
+
115
+ /**
116
+ * @deprecated Use `calculateLiquidationDistance`. Removed in the next major.
117
+ */
118
+ export const liquidationDistancePercent = calculateLiquidationDistance
119
+
120
+ /**
121
+ * Effective leverage of an open position.
122
+ *
123
+ * leverage = positionValueUsd / marginUsd
124
+ *
125
+ * @param positionValueUsd - Position notional value in USD
126
+ * @param marginUsd - Margin backing the position in USD
127
+ * @returns Effective leverage, or 0 when margin is zero
128
+ * @public
129
+ */
130
+ export function calculateEffectiveLeverage(params: {
131
+ positionValueUsd: number
132
+ marginUsd: number
133
+ }): number {
134
+ const { positionValueUsd, marginUsd } = params
135
+ if (marginUsd === 0) {
136
+ return 0
137
+ }
138
+ if (!areFinite(positionValueUsd, marginUsd)) {
139
+ return Number.NaN
140
+ }
141
+ return new DivBig(positionValueUsd).div(marginUsd).toNumber()
142
+ }
143
+
144
+ /**
145
+ * @deprecated Use `calculateEffectiveLeverage`. Removed in the next major.
146
+ */
147
+ export const effectiveLeverage = calculateEffectiveLeverage
148
+
22
149
  /**
23
150
  * Estimated liquidation price for an isolated-margin position, parameterised
24
151
  * by the venue's maintenance margin rate.
@@ -37,7 +164,7 @@ export function directionSign(isLong: boolean): 1 | -1 {
37
164
  * produce one (zero leverage, degenerate denominator).
38
165
  * @public
39
166
  */
40
- export function estimateIsolatedLiquidationPrice(params: {
167
+ export function estimateLiquidationPrice(params: {
41
168
  entryPrice: number
42
169
  leverage: number
43
170
  isLong: boolean
@@ -47,7 +174,7 @@ export function estimateIsolatedLiquidationPrice(params: {
47
174
  if (leverage === 0) {
48
175
  return undefined
49
176
  }
50
- const side = directionSign(isLong)
177
+ const side = isLong ? 1 : -1
51
178
  const denominator = 1 - maintenanceMarginRate * side
52
179
  if (denominator === 0) {
53
180
  return undefined
@@ -65,6 +192,11 @@ export function estimateIsolatedLiquidationPrice(params: {
65
192
  .toNumber()
66
193
  }
67
194
 
195
+ /**
196
+ * @deprecated Use `estimateLiquidationPrice`. Removed in the next major.
197
+ */
198
+ export const estimateIsolatedLiquidationPrice = estimateLiquidationPrice
199
+
68
200
  /**
69
201
  * Whether an isolated position with this liquidation price is already past
70
202
  * liquidation at `currentPrice`: a long liquidates when the price falls to its
@@ -88,7 +220,7 @@ export function wouldImmediatelyLiquidate(params: {
88
220
  }
89
221
 
90
222
  /**
91
- * Predicted average entry price after adding to an existing position.
223
+ * Estimated average entry price after adding to an existing position.
92
224
  *
93
225
  * Weighted average of the current entry and the new fill price, weighted by
94
226
  * the size of each leg in coin units. Both legs assumed in the same direction
@@ -103,7 +235,7 @@ export function wouldImmediatelyLiquidate(params: {
103
235
  * cannot produce a valid average (zero combined size, non-finite values).
104
236
  * @public
105
237
  */
106
- export function predictAverageEntryPrice(params: {
238
+ export function estimateAverageEntryPrice(params: {
107
239
  currentSize: number
108
240
  currentEntry: number
109
241
  addSize: number
@@ -128,7 +260,12 @@ export function predictAverageEntryPrice(params: {
128
260
  }
129
261
 
130
262
  /**
131
- * Predicted effective leverage after adding margin and notional.
263
+ * @deprecated Use `estimateAverageEntryPrice`. Removed in the next major.
264
+ */
265
+ export const predictAverageEntryPrice = estimateAverageEntryPrice
266
+
267
+ /**
268
+ * Estimated effective leverage after adding margin and notional.
132
269
  *
133
270
  * leverage = totalNotional / totalMargin. The caller computes notional from
134
271
  * size and price (`calculateNotionalValue`) and supplies the additional
@@ -138,7 +275,7 @@ export function predictAverageEntryPrice(params: {
138
275
  * non-positive.
139
276
  * @public
140
277
  */
141
- export function predictNewLeverage(params: {
278
+ export function estimateNewLeverage(params: {
142
279
  currentNotional: number
143
280
  currentMargin: number
144
281
  addNotional: number
@@ -159,14 +296,19 @@ export function predictNewLeverage(params: {
159
296
  }
160
297
 
161
298
  /**
162
- * Predicted unrealised PnL at the current mark price.
299
+ * @deprecated Use `estimateNewLeverage`. Removed in the next major.
300
+ */
301
+ export const predictNewLeverage = estimateNewLeverage
302
+
303
+ /**
304
+ * Estimated unrealised PnL at the current mark price.
163
305
  *
164
- * `pnl = (markPrice - entryPrice) * size * directionSign(isLong)`
306
+ * `pnl = (markPrice - entryPrice) * size * (isLong ? 1 : -1)`
165
307
  *
166
308
  * @param size - Position size as a non-negative magnitude.
167
309
  * @public
168
310
  */
169
- export function predictUnrealizedPnl(params: {
311
+ export function estimateUnrealizedPnl(params: {
170
312
  entryPrice: number
171
313
  markPrice: number
172
314
  size: number
@@ -179,19 +321,24 @@ export function predictUnrealizedPnl(params: {
179
321
  return new DivBig(markPrice)
180
322
  .minus(entryPrice)
181
323
  .times(size)
182
- .times(directionSign(isLong))
324
+ .times(isLong ? 1 : -1)
183
325
  .toNumber()
184
326
  }
185
327
 
328
+ /**
329
+ * @deprecated Use `estimateUnrealizedPnl`. Removed in the next major.
330
+ */
331
+ export const predictUnrealizedPnl = estimateUnrealizedPnl
332
+
186
333
  /**
187
334
  * Realised PnL on the portion of a position being closed.
188
335
  *
189
- * `rPnl = (closePrice - entryPrice) * closeSize * directionSign(isLong)`
336
+ * `rPnl = (closePrice - entryPrice) * closeSize * (isLong ? 1 : -1)`
190
337
  *
191
338
  * @param closeSize - Size being closed as a non-negative magnitude.
192
339
  * @public
193
340
  */
194
- export function realizedPnlOnClose(params: {
341
+ export function calculateRealizedPnl(params: {
195
342
  entryPrice: number
196
343
  closePrice: number
197
344
  closeSize: number
@@ -204,6 +351,11 @@ export function realizedPnlOnClose(params: {
204
351
  return new DivBig(closePrice)
205
352
  .minus(entryPrice)
206
353
  .times(closeSize)
207
- .times(directionSign(isLong))
354
+ .times(isLong ? 1 : -1)
208
355
  .toNumber()
209
356
  }
357
+
358
+ /**
359
+ * @deprecated Use `calculateRealizedPnl`. Removed in the next major.
360
+ */
361
+ export const realizedPnlOnClose = calculateRealizedPnl
@@ -6,12 +6,12 @@ import {
6
6
  type Quote,
7
7
  } from '@lifi/perps-types'
8
8
  import { PerpsError } from '../errors/PerpsError.js'
9
+ import { buildQuote } from '../math/order.js'
9
10
  import type { SDKRequestOptions } from '../types/config.js'
10
11
  import type {
11
12
  PerpsSDKClient,
12
13
  ProviderGetQuoteParams,
13
14
  } from '../types/provider.js'
14
- import { buildQuote } from '../utils/calculations.js'
15
15
  import { getMarkets } from './getMarkets.js'
16
16
  import { getMarketsContext } from './getMarketsContext.js'
17
17
  import { getOrderbook } from './getOrderbook.js'
@@ -3,12 +3,12 @@ import type {
3
3
  MarketContext,
4
4
  OrderbookResponse,
5
5
  } from '@lifi/perps-types'
6
+ import { buildQuote } from '../math/order.js'
6
7
  import type {
7
8
  PerpsSDKClient,
8
9
  ProviderGetQuoteParams,
9
10
  QuoteListener,
10
11
  } from '../types/provider.js'
11
- import { buildQuote } from '../utils/calculations.js'
12
12
  import type { WsProvider } from '../websocket/types.js'
13
13
  import { resolveQuoteMarket, resolveQuotePrice } from './resolveQuote.js'
14
14
 
@@ -9,6 +9,7 @@ import type {
9
9
  ActivitiesResponse,
10
10
  ActivityType,
11
11
  AvailableToTrade,
12
+ DecimalString,
12
13
  FillsResponse,
13
14
  Market,
14
15
  MarketRef,
@@ -534,29 +535,37 @@ export interface PerpsProviderPlugin {
534
535
  ): AccountSummary
535
536
 
536
537
  /**
537
- * Format an order price onto the venue's tick grid for `market`. This is
538
- * the canonical, provider-correct formatting surface — venue tick rules
539
- * differ per provider, so provider-agnostic consumers must route every
540
- * order price through the market's own provider instead of applying one
541
- * venue's rules to another's markets. Pure — does no I/O.
538
+ * Snap an order price onto the venue's tick grid for `market`, rounding
539
+ * half-up. This is the canonical, provider-correct price surface — venue
540
+ * tick rules differ per provider, so provider-agnostic consumers must route
541
+ * every order price through the market's own provider instead of applying
542
+ * one venue's rules to another's markets. Pure — does no I/O.
543
+ *
544
+ * Takes and gives a {@link DecimalString}. Never pass a `number`: above 15
545
+ * significant digits the value has already lost digits by the time it
546
+ * arrives.
542
547
  *
543
548
  * @returns The price as a wire-ready decimal string, trailing zeros
544
549
  * stripped.
545
550
  * @throws {PerpsError} `ValidationError` when `market` lacks the tick
546
551
  * metadata the venue's rules need (e.g. `Market.priceDecimals` absent).
547
552
  */
548
- formatOrderPrice(market: Market, price: number): string
553
+ snapOrderPrice(market: Market, price: DecimalString): DecimalString
549
554
 
550
555
  /**
551
- * Format an order size onto the venue's lot grid for `market`. Truncates
552
- * (never rounds up) so the formatted size cannot exceed the user's intended
553
- * size or available balance. Pure — does no I/O.
556
+ * Snap an order size onto the venue's lot grid for `market`, truncating
557
+ * toward zero (never rounding up) so the snapped size cannot exceed the
558
+ * user's intended size or available balance. Pure — does no I/O.
559
+ *
560
+ * Takes and gives a {@link DecimalString}. Never pass a `number`: above 15
561
+ * significant digits the value has already lost digits by the time it
562
+ * arrives.
554
563
  *
555
564
  * @param size - Size in base-asset units as a non-negative magnitude.
556
565
  * @returns The size as a wire-ready decimal string, trailing zeros
557
566
  * stripped.
558
567
  */
559
- formatOrderSize(market: Market, size: number): string
568
+ snapOrderSize(market: Market, size: DecimalString): DecimalString
560
569
 
561
570
  /**
562
571
  * Estimate the liquidation price of a new isolated position on `market`
@@ -564,6 +573,10 @@ export interface PerpsProviderPlugin {
564
573
  * positions, prefer `Position.liquidationPrice` from the venue. Pure —
565
574
  * does no I/O.
566
575
  *
576
+ * Numbers, in and out, on purpose: this is a display-tier estimate that
577
+ * feeds a screen, not a wire amount. It is not a `snap*` method and must
578
+ * not be converted to {@link DecimalString}.
579
+ *
567
580
  * @returns The estimated liquidation price, or `undefined` when the venue's
568
581
  * model cannot be evaluated client-side (degenerate inputs, or `market`
569
582
  * lacks the margin metadata the model needs).
@@ -1,4 +1,9 @@
1
- import type { ActionType, Asset, WithdrawalRoute } from '@lifi/perps-types'
1
+ import type {
2
+ ActionType,
3
+ Asset,
4
+ DecimalString,
5
+ WithdrawalRoute,
6
+ } from '@lifi/perps-types'
2
7
  import type { Address } from 'viem'
3
8
 
4
9
  export type { WithdrawalRoute }
@@ -14,13 +19,19 @@ export interface ProviderWithdrawableBalance {
14
19
  assetId: string
15
20
  route: WithdrawalRoute
16
21
  /** Withdrawable amount in the asset's own units. Always greater than zero. */
17
- available: string
22
+ available: DecimalString
23
+ /**
24
+ * Largest `amount` the row can fund: `available` when the fee is deducted
25
+ * from the amount or absent; `available − withdrawalFee` floored at zero
26
+ * when the venue charges the fee on top (`isFeeDeducted === false`).
27
+ */
28
+ max: DecimalString
18
29
  /**
19
30
  * Flat venue fee on a withdrawal from this row, in the asset's own units.
20
31
  * Absent when the venue publishes no fee for the asset. The client rejects
21
32
  * a value that is not a non-negative decimal.
22
33
  */
23
- withdrawalFee?: string
34
+ withdrawalFee?: DecimalString
24
35
  /**
25
36
  * `true` when the venue takes `withdrawalFee` out of the requested amount,
26
37
  * `false` when it charges the fee in addition. Set together with
@@ -40,7 +51,13 @@ export interface WithdrawableBalance {
40
51
  asset: Asset
41
52
  route: WithdrawalRoute
42
53
  /** Withdrawable amount in the asset's own units. */
43
- available: string
54
+ available: DecimalString
55
+ /**
56
+ * Largest `amount` the row can fund: `available` when the fee is deducted
57
+ * from the amount or absent; `available − withdrawalFee` floored at zero
58
+ * when the venue charges the fee on top (`isFeeDeducted === false`).
59
+ */
60
+ max: DecimalString
44
61
  /**
45
62
  * Flat venue fee on a withdrawal from this row, in the asset's own units.
46
63
  * Absent when the venue publishes no fee for the asset. With
@@ -51,7 +68,7 @@ export interface WithdrawableBalance {
51
68
  * is zero or negative when the fee is at or above `available`, and the row
52
69
  * then funds no withdrawal.
53
70
  */
54
- withdrawalFee?: string
71
+ withdrawalFee?: DecimalString
55
72
  /**
56
73
  * Present only together with `withdrawalFee`. Absent on a row from a
57
74
  * provider plugin that does not report it; absence means unknown, not
@@ -5,20 +5,11 @@ import type {
5
5
  TwapOrder,
6
6
  } from '@lifi/perps-types'
7
7
  import {
8
- FillClassification,
9
8
  OrderSide,
10
9
  OrderStatus,
11
10
  OrderType,
12
11
  TriggerCondition,
13
12
  } from '@lifi/perps-types'
14
- import { stringToFloat } from './parse.js'
15
-
16
- /**
17
- * Re-exported fill taxonomy used by {@link classifyFillFromPosition}.
18
- *
19
- * @public
20
- */
21
- export { FillClassification }
22
13
 
23
14
  const TP_TYPES = new Set<OrderType>([
24
15
  OrderType.TAKE_PROFIT_MARKET,
@@ -97,24 +88,3 @@ export const ACTIVE_ORDER_STATUSES: ReadonlySet<OrderStatus> = new Set([
97
88
  export function isActiveOrderStatus(status: OrderStatus): boolean {
98
89
  return ACTIVE_ORDER_STATUSES.has(status)
99
90
  }
100
-
101
- /**
102
- * Classify a fill as open or close based on realizedPnl.
103
- * @deprecated Use `Fill.classification` instead — it uses startPosition
104
- * for accurate open/increase/reduce/close/reverse classification.
105
- * @public
106
- */
107
- export function classifyFill(
108
- side: OrderSide,
109
- realizedPnl: string | null | undefined
110
- ): FillClassification {
111
- const isClose = realizedPnl != null && stringToFloat(realizedPnl) !== 0
112
- if (side === OrderSide.BUY) {
113
- return isClose
114
- ? FillClassification.CLOSED_SHORT
115
- : FillClassification.OPENED_LONG
116
- }
117
- return isClose
118
- ? FillClassification.CLOSED_LONG
119
- : FillClassification.OPENED_SHORT
120
- }
package/src/version.ts CHANGED
@@ -10,4 +10,4 @@ export const name = '@lifi/perps-sdk'
10
10
  *
11
11
  * @public
12
12
  */
13
- export const version = '20.1.0'
13
+ export const version = '21.0.0'
@@ -0,0 +1,172 @@
1
+ import {
2
+ type DecimalString,
3
+ isDecimalString,
4
+ type Market,
5
+ PerpsErrorCode,
6
+ } from '@lifi/perps-types'
7
+ import Big from 'big.js'
8
+ import { TruncBig } from '../decimal/big.js'
9
+ import { PerpsError } from '../errors/PerpsError.js'
10
+ import type { PerpsSDKClient } from '../types/provider.js'
11
+ import { snapOrderSize } from './snap.js'
12
+
13
+ /** @public */
14
+ export interface OrderAmountsInput {
15
+ sdk: PerpsSDKClient
16
+ market: Market
17
+ /** The field the user typed; the other two are calculated from it. */
18
+ held: 'margin' | 'size' | 'notional'
19
+ amount: DecimalString
20
+ leverage: number
21
+ price: DecimalString
22
+ /** Decimals for the quote-asset amounts (margin, notional). Default 2. */
23
+ quoteDecimals?: number
24
+ }
25
+
26
+ /** @public */
27
+ export interface OrderAmounts {
28
+ /**
29
+ * On the `quoteDecimals` grid: rounded up when derived, so it funds `size`
30
+ * at the requested leverage, and truncated when the user holds it.
31
+ */
32
+ margin: DecimalString
33
+ /** Snapped onto the venue lot grid. */
34
+ size: DecimalString
35
+ /** Truncated to `quoteDecimals`. */
36
+ notional: DecimalString
37
+ }
38
+
39
+ const DEFAULT_QUOTE_DECIMALS = 2
40
+ const TEN = new Big(10)
41
+
42
+ /** Round a quote amount down onto its decimal grid, with no trailing zeros. */
43
+ function quoteAmount(value: Big, decimals: number): DecimalString {
44
+ const truncated = value.round(decimals, Big.roundDown)
45
+ return truncated.eq(0) ? '0' : truncated.toFixed()
46
+ }
47
+
48
+ /**
49
+ * The smallest margin on the `decimals` grid that funds `notional` at
50
+ * `leverage`, so `margin × leverage ≥ notional` holds. The one derived amount
51
+ * that rounds up: a margin rounded down under-funds the size it backs.
52
+ *
53
+ * The ceiling is exact: the remainder decides the carry, so the result never
54
+ * leans on a fixed decimal-place limit the way `div` then `round` would.
55
+ */
56
+ function coveringMargin(
57
+ notional: Big,
58
+ leverage: Big,
59
+ decimals: number
60
+ ): DecimalString {
61
+ const scale = TEN.pow(decimals)
62
+ const scaled = notional.times(scale)
63
+ const remainder = scaled.mod(leverage)
64
+ const whole = scaled.minus(remainder).div(leverage)
65
+ const covering = remainder.eq(0) ? whole : whole.plus(1)
66
+ return covering.eq(0) ? '0' : covering.div(scale).toFixed()
67
+ }
68
+
69
+ /**
70
+ * An order needs three positive amounts. A grid that snaps any of them to
71
+ * zero — a sub-lot size, a sub-cent quote amount — describes no order a venue
72
+ * can take, so the caller gets `null` instead of a result it has to re-check.
73
+ */
74
+ function executable(amounts: OrderAmounts): OrderAmounts | null {
75
+ const positive =
76
+ new Big(amounts.size).gt(0) &&
77
+ new Big(amounts.margin).gt(0) &&
78
+ new Big(amounts.notional).gt(0)
79
+ return positive ? amounts : null
80
+ }
81
+
82
+ function positiveDecimal(value: DecimalString): Big | null {
83
+ if (!isDecimalString(value)) {
84
+ return null
85
+ }
86
+ const parsed = new TruncBig(value)
87
+ return parsed.gt(0) ? parsed : null
88
+ }
89
+
90
+ /**
91
+ * The three order-entry amounts, derived from whichever one the user typed.
92
+ *
93
+ * The held field is normalised first — truncated to `quoteDecimals` for a
94
+ * margin or notional, snapped onto the venue lot grid for a size — and the
95
+ * other two are then derived from that normalised value, so the three agree
96
+ * with each other rather than with an input the user cannot see.
97
+ *
98
+ * Rounding is directional, so the result always funds itself:
99
+ * `size × price ≤ margin × leverage`. A derived size truncates onto the lot
100
+ * grid and a derived notional truncates onto the quote grid, but a derived
101
+ * margin rounds **up** onto the quote grid, because it is the one amount that
102
+ * has to cover the others rather than cap them.
103
+ *
104
+ * Formulas: `size = margin × leverage ÷ price`,
105
+ * `margin = size × price ÷ leverage`, `notional = size × price`
106
+ * (or `margin × leverage` when the margin is held).
107
+ *
108
+ * @returns `null` when `amount` or `price` is not a positive decimal string,
109
+ * when `leverage` is not a positive finite number, or when the venue and
110
+ * quote grids snap the result to a non-positive amount — a sub-lot size or
111
+ * a sub-cent quote amount describes no order a venue can take.
112
+ * @throws {PerpsError} `ValidationError` when `quoteDecimals` is not a
113
+ * non-negative integer, or `SDKError` when `market.providerId` names no
114
+ * registered provider plugin.
115
+ * @public
116
+ */
117
+ export function calculateOrderAmounts(
118
+ input: OrderAmountsInput
119
+ ): OrderAmounts | null {
120
+ const {
121
+ sdk,
122
+ market,
123
+ held,
124
+ leverage,
125
+ quoteDecimals = DEFAULT_QUOTE_DECIMALS,
126
+ } = input
127
+ if (!Number.isInteger(quoteDecimals) || quoteDecimals < 0) {
128
+ throw new PerpsError(
129
+ PerpsErrorCode.ValidationError,
130
+ `Invalid quoteDecimals for order amounts: ${quoteDecimals}`
131
+ )
132
+ }
133
+ const amount = positiveDecimal(input.amount)
134
+ const price = positiveDecimal(input.price)
135
+ if (
136
+ amount === null ||
137
+ price === null ||
138
+ !Number.isFinite(leverage) ||
139
+ leverage <= 0
140
+ ) {
141
+ return null
142
+ }
143
+ const leverageFactor = new TruncBig(leverage)
144
+
145
+ if (held === 'size') {
146
+ const size = snapOrderSize(sdk, market, amount.toFixed())
147
+ const notional = new TruncBig(size).times(price)
148
+ return executable({
149
+ margin: coveringMargin(notional, leverageFactor, quoteDecimals),
150
+ size,
151
+ notional: quoteAmount(notional, quoteDecimals),
152
+ })
153
+ }
154
+
155
+ if (held === 'notional') {
156
+ const notional = quoteAmount(amount, quoteDecimals)
157
+ const exact = new TruncBig(notional)
158
+ return executable({
159
+ margin: coveringMargin(exact, leverageFactor, quoteDecimals),
160
+ size: snapOrderSize(sdk, market, exact.div(price).toFixed()),
161
+ notional,
162
+ })
163
+ }
164
+
165
+ const margin = quoteAmount(amount, quoteDecimals)
166
+ const notional = new TruncBig(margin).times(leverage)
167
+ return executable({
168
+ margin,
169
+ size: snapOrderSize(sdk, market, notional.div(price).toFixed()),
170
+ notional: quoteAmount(notional, quoteDecimals),
171
+ })
172
+ }