@d8x/perpetuals-sdk 2.0.13-alpha → 2.1.1-alpha2

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 (282) hide show
  1. package/dist/cjs/abi/IPerpetualManager.json +154 -4
  2. package/dist/cjs/abi/OracleFactory.json +94 -25
  3. package/dist/cjs/abi/PerpetualManagerProxy.json +212 -2
  4. package/dist/cjs/accountTrade.d.ts +3 -3
  5. package/dist/cjs/accountTrade.js +1 -1
  6. package/dist/cjs/accountTrade.js.map +1 -1
  7. package/dist/cjs/brokerTool.d.ts +5 -1
  8. package/dist/cjs/brokerTool.js +20 -7
  9. package/dist/cjs/brokerTool.js.map +1 -1
  10. package/dist/cjs/config/defaultConfig.json +0 -12
  11. package/dist/cjs/config/priceFeedConfig.json +1 -19
  12. package/dist/cjs/constants.d.ts +0 -1
  13. package/dist/cjs/constants.js +2 -3
  14. package/dist/cjs/constants.js.map +1 -1
  15. package/dist/cjs/contracts/IPerpetualManager.d.ts +93 -13
  16. package/dist/cjs/contracts/OracleFactory.d.ts +69 -20
  17. package/dist/cjs/contracts/PerpetualManagerProxy.d.ts +109 -4
  18. package/dist/cjs/contracts/factories/IPerpetualManager__factory.d.ts +118 -4
  19. package/dist/cjs/contracts/factories/IPerpetualManager__factory.js +154 -4
  20. package/dist/cjs/contracts/factories/IPerpetualManager__factory.js.map +1 -1
  21. package/dist/cjs/contracts/factories/OracleFactory__factory.d.ts +75 -20
  22. package/dist/cjs/contracts/factories/OracleFactory__factory.js +94 -25
  23. package/dist/cjs/contracts/factories/OracleFactory__factory.js.map +1 -1
  24. package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.d.ts +159 -2
  25. package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.js +212 -2
  26. package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.js.map +1 -1
  27. package/dist/cjs/d8XMath.d.ts +59 -1
  28. package/dist/cjs/d8XMath.js +259 -3
  29. package/dist/cjs/d8XMath.js.map +1 -1
  30. package/dist/cjs/liquidatorTool.d.ts +1 -0
  31. package/dist/cjs/liquidatorTool.js +24 -7
  32. package/dist/cjs/liquidatorTool.js.map +1 -1
  33. package/dist/cjs/marketData.d.ts +45 -23
  34. package/dist/cjs/marketData.js +292 -197
  35. package/dist/cjs/marketData.js.map +1 -1
  36. package/dist/cjs/nodeSDKTypes.d.ts +24 -1
  37. package/dist/cjs/nodeSDKTypes.js.map +1 -1
  38. package/dist/cjs/orderExecutorTool.d.ts +3 -3
  39. package/dist/cjs/orderExecutorTool.js +38 -13
  40. package/dist/cjs/orderExecutorTool.js.map +1 -1
  41. package/dist/cjs/perpetualDataHandler.d.ts +28 -17
  42. package/dist/cjs/perpetualDataHandler.js +71 -45
  43. package/dist/cjs/perpetualDataHandler.js.map +1 -1
  44. package/dist/cjs/perpetualEventHandler.d.ts +1 -1
  45. package/dist/cjs/perpetualEventHandler.js +6 -7
  46. package/dist/cjs/perpetualEventHandler.js.map +1 -1
  47. package/dist/cjs/polyMktsPxFeed.d.ts +5 -3
  48. package/dist/cjs/polyMktsPxFeed.js +34 -2
  49. package/dist/cjs/polyMktsPxFeed.js.map +1 -1
  50. package/dist/cjs/priceFeeds.d.ts +6 -7
  51. package/dist/cjs/priceFeeds.js +36 -14
  52. package/dist/cjs/priceFeeds.js.map +1 -1
  53. package/dist/cjs/version.d.ts +1 -1
  54. package/dist/cjs/version.js +1 -1
  55. package/dist/cjs/writeAccessHandler.js +1 -1
  56. package/dist/cjs/writeAccessHandler.js.map +1 -1
  57. package/dist/esm/abi/IPerpetualManager.json +154 -4
  58. package/dist/esm/abi/OracleFactory.json +94 -25
  59. package/dist/esm/abi/PerpetualManagerProxy.json +212 -2
  60. package/dist/esm/accountTrade.d.ts +3 -3
  61. package/dist/esm/accountTrade.js +1 -1
  62. package/dist/esm/accountTrade.js.map +1 -1
  63. package/dist/esm/brokerTool.d.ts +5 -1
  64. package/dist/esm/brokerTool.js +21 -8
  65. package/dist/esm/brokerTool.js.map +1 -1
  66. package/dist/esm/config/defaultConfig.json +0 -12
  67. package/dist/esm/config/priceFeedConfig.json +1 -19
  68. package/dist/esm/constants.d.ts +0 -1
  69. package/dist/esm/constants.js +1 -2
  70. package/dist/esm/constants.js.map +1 -1
  71. package/dist/esm/contracts/IPerpetualManager.d.ts +93 -13
  72. package/dist/esm/contracts/OracleFactory.d.ts +69 -20
  73. package/dist/esm/contracts/PerpetualManagerProxy.d.ts +109 -4
  74. package/dist/esm/contracts/factories/IPerpetualManager__factory.d.ts +118 -4
  75. package/dist/esm/contracts/factories/IPerpetualManager__factory.js +154 -4
  76. package/dist/esm/contracts/factories/IPerpetualManager__factory.js.map +1 -1
  77. package/dist/esm/contracts/factories/OracleFactory__factory.d.ts +75 -20
  78. package/dist/esm/contracts/factories/OracleFactory__factory.js +94 -25
  79. package/dist/esm/contracts/factories/OracleFactory__factory.js.map +1 -1
  80. package/dist/{cjs/contracts/factories/MockToken__factory.d.ts → esm/contracts/factories/PerpStorage__factory.d.ts} +115 -128
  81. package/dist/esm/contracts/factories/{MockToken__factory.js → PerpStorage__factory.js} +128 -139
  82. package/dist/esm/contracts/factories/PerpStorage__factory.js.map +1 -0
  83. package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.d.ts +159 -2
  84. package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.js +212 -2
  85. package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.js.map +1 -1
  86. package/dist/esm/d8XMath.d.ts +59 -1
  87. package/dist/esm/d8XMath.js +251 -2
  88. package/dist/esm/d8XMath.js.map +1 -1
  89. package/dist/esm/liquidatorTool.d.ts +1 -0
  90. package/dist/esm/liquidatorTool.js +25 -8
  91. package/dist/esm/liquidatorTool.js.map +1 -1
  92. package/dist/esm/marketData.d.ts +45 -23
  93. package/dist/esm/marketData.js +295 -200
  94. package/dist/esm/marketData.js.map +1 -1
  95. package/dist/esm/nodeSDKTypes.d.ts +24 -1
  96. package/dist/esm/nodeSDKTypes.js.map +1 -1
  97. package/dist/esm/orderExecutorTool.d.ts +3 -3
  98. package/dist/esm/orderExecutorTool.js +38 -13
  99. package/dist/esm/orderExecutorTool.js.map +1 -1
  100. package/dist/esm/perpetualDataHandler.d.ts +28 -17
  101. package/dist/esm/perpetualDataHandler.js +74 -48
  102. package/dist/esm/perpetualDataHandler.js.map +1 -1
  103. package/dist/esm/perpetualEventHandler.d.ts +1 -1
  104. package/dist/esm/perpetualEventHandler.js +6 -7
  105. package/dist/esm/perpetualEventHandler.js.map +1 -1
  106. package/dist/esm/polyMktsPxFeed.d.ts +5 -3
  107. package/dist/esm/polyMktsPxFeed.js +34 -2
  108. package/dist/esm/polyMktsPxFeed.js.map +1 -1
  109. package/dist/esm/priceFeeds.d.ts +6 -7
  110. package/dist/esm/priceFeeds.js +36 -14
  111. package/dist/esm/priceFeeds.js.map +1 -1
  112. package/dist/esm/version.d.ts +1 -1
  113. package/dist/esm/version.js +1 -1
  114. package/dist/esm/writeAccessHandler.js +3 -3
  115. package/dist/esm/writeAccessHandler.js.map +1 -1
  116. package/doc/brokerTool.md +3 -1
  117. package/doc/d8x-perpetuals-sdk.md +804 -132
  118. package/doc/marketData.md +813 -0
  119. package/doc/perpetualDataHandler.md +76 -7
  120. package/package.json +1 -1
  121. package/src/abi/IPerpetualManager.json +154 -4
  122. package/src/abi/OracleFactory.json +523 -454
  123. package/src/abi/PerpetualManagerProxy.json +1596 -1386
  124. package/src/accountTrade.ts +3 -3
  125. package/src/brokerTool.ts +22 -8
  126. package/src/config/defaultConfig.json +0 -13
  127. package/src/config/priceFeedConfig.json +1 -19
  128. package/src/constants.ts +1 -2
  129. package/src/contracts/IPerpetualManager.ts +140 -10
  130. package/src/contracts/OracleFactory.ts +100 -26
  131. package/src/contracts/PerpetualManagerProxy.ts +192 -3
  132. package/src/contracts/factories/IPerpetualManager__factory.ts +154 -4
  133. package/src/contracts/factories/OracleFactory__factory.ts +94 -25
  134. package/src/contracts/factories/PerpetualManagerProxy__factory.ts +212 -2
  135. package/src/d8XMath.ts +327 -2
  136. package/src/liquidatorTool.ts +29 -14
  137. package/src/marketData.ts +448 -250
  138. package/src/nodeSDKTypes.ts +30 -1
  139. package/src/orderExecutorTool.ts +48 -20
  140. package/src/perpetualDataHandler.ts +108 -55
  141. package/src/perpetualEventHandler.ts +6 -7
  142. package/src/polyMktsPxFeed.ts +40 -4
  143. package/src/priceFeeds.ts +41 -17
  144. package/src/version.ts +1 -1
  145. package/src/writeAccessHandler.ts +2 -2
  146. package/dist/cjs/abi/BeaconProxy.json +0 -71
  147. package/dist/cjs/abi/Maintainer.json +0 -774
  148. package/dist/cjs/abi/MockToken.json +0 -347
  149. package/dist/cjs/abi/UUPSUpgradeable.json +0 -104
  150. package/dist/cjs/abi/WeETH.json +0 -310
  151. package/dist/cjs/abi-zkevm/LimitOrderBook.json +0 -910
  152. package/dist/cjs/abi-zkevm/LimitOrderBookFactory.json +0 -236
  153. package/dist/cjs/contracts/BeaconProxy.d.ts +0 -63
  154. package/dist/cjs/contracts/BeaconProxy.js +0 -3
  155. package/dist/cjs/contracts/BeaconProxy.js.map +0 -1
  156. package/dist/cjs/contracts/Maintainer.d.ts +0 -799
  157. package/dist/cjs/contracts/Maintainer.js +0 -3
  158. package/dist/cjs/contracts/Maintainer.js.map +0 -1
  159. package/dist/cjs/contracts/MockToken.d.ts +0 -263
  160. package/dist/cjs/contracts/MockToken.js +0 -3
  161. package/dist/cjs/contracts/MockToken.js.map +0 -1
  162. package/dist/cjs/contracts/UUPSUpgradeable.d.ts +0 -118
  163. package/dist/cjs/contracts/UUPSUpgradeable.js +0 -3
  164. package/dist/cjs/contracts/UUPSUpgradeable.js.map +0 -1
  165. package/dist/cjs/contracts/WeETH.d.ts +0 -503
  166. package/dist/cjs/contracts/WeETH.js +0 -3
  167. package/dist/cjs/contracts/WeETH.js.map +0 -1
  168. package/dist/cjs/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  169. package/dist/cjs/contracts/factories/BeaconProxy__factory.js +0 -89
  170. package/dist/cjs/contracts/factories/BeaconProxy__factory.js.map +0 -1
  171. package/dist/cjs/contracts/factories/Maintainer__factory.d.ts +0 -609
  172. package/dist/cjs/contracts/factories/Maintainer__factory.js +0 -792
  173. package/dist/cjs/contracts/factories/Maintainer__factory.js.map +0 -1
  174. package/dist/cjs/contracts/factories/MockToken__factory.js +0 -365
  175. package/dist/cjs/contracts/factories/MockToken__factory.js.map +0 -1
  176. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  177. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js +0 -122
  178. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  179. package/dist/cjs/contracts/factories/WeETH__factory.d.ts +0 -545
  180. package/dist/cjs/contracts/factories/WeETH__factory.js +0 -721
  181. package/dist/cjs/contracts/factories/WeETH__factory.js.map +0 -1
  182. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  183. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5324
  184. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  185. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  186. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -254
  187. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  188. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  189. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js +0 -928
  190. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  191. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  192. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js +0 -456
  193. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  194. package/dist/cjs/contracts/factories/lean0/index.d.ts +0 -4
  195. package/dist/cjs/contracts/factories/lean0/index.js +0 -15
  196. package/dist/cjs/contracts/factories/lean0/index.js.map +0 -1
  197. package/dist/cjs/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  198. package/dist/cjs/contracts/lean0/IPerpetualManager.js +0 -3
  199. package/dist/cjs/contracts/lean0/IPerpetualManager.js.map +0 -1
  200. package/dist/cjs/contracts/lean0/LimitOrderBook.d.ts +0 -533
  201. package/dist/cjs/contracts/lean0/LimitOrderBook.js +0 -3
  202. package/dist/cjs/contracts/lean0/LimitOrderBook.js.map +0 -1
  203. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  204. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js +0 -3
  205. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  206. package/dist/cjs/contracts/lean0/ShareToken.d.ts +0 -320
  207. package/dist/cjs/contracts/lean0/ShareToken.js +0 -3
  208. package/dist/cjs/contracts/lean0/ShareToken.js.map +0 -1
  209. package/dist/cjs/contracts/lean0/index.d.ts +0 -4
  210. package/dist/cjs/contracts/lean0/index.js +0 -3
  211. package/dist/cjs/contracts/lean0/index.js.map +0 -1
  212. package/dist/esm/abi/BeaconProxy.json +0 -71
  213. package/dist/esm/abi/Maintainer.json +0 -774
  214. package/dist/esm/abi/MockToken.json +0 -347
  215. package/dist/esm/abi/UUPSUpgradeable.json +0 -104
  216. package/dist/esm/abi/WeETH.json +0 -310
  217. package/dist/esm/abi/lean0/IPerpetualManager.json +0 -5306
  218. package/dist/esm/abi/lean0/LimitOrderBook.json +0 -910
  219. package/dist/esm/abi/lean0/LimitOrderBookFactory.json +0 -236
  220. package/dist/esm/abi/lean0/ShareToken.json +0 -438
  221. package/dist/esm/abi-zkevm/LimitOrderBook.json +0 -910
  222. package/dist/esm/abi-zkevm/LimitOrderBookFactory.json +0 -236
  223. package/dist/esm/contracts/BeaconProxy.d.ts +0 -63
  224. package/dist/esm/contracts/BeaconProxy.js +0 -2
  225. package/dist/esm/contracts/BeaconProxy.js.map +0 -1
  226. package/dist/esm/contracts/Maintainer.d.ts +0 -799
  227. package/dist/esm/contracts/Maintainer.js +0 -2
  228. package/dist/esm/contracts/Maintainer.js.map +0 -1
  229. package/dist/esm/contracts/MockToken.d.ts +0 -263
  230. package/dist/esm/contracts/MockToken.js +0 -2
  231. package/dist/esm/contracts/MockToken.js.map +0 -1
  232. package/dist/esm/contracts/UUPSUpgradeable.d.ts +0 -118
  233. package/dist/esm/contracts/UUPSUpgradeable.js +0 -2
  234. package/dist/esm/contracts/UUPSUpgradeable.js.map +0 -1
  235. package/dist/esm/contracts/WeETH.d.ts +0 -503
  236. package/dist/esm/contracts/WeETH.js +0 -2
  237. package/dist/esm/contracts/WeETH.js.map +0 -1
  238. package/dist/esm/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  239. package/dist/esm/contracts/factories/BeaconProxy__factory.js +0 -85
  240. package/dist/esm/contracts/factories/BeaconProxy__factory.js.map +0 -1
  241. package/dist/esm/contracts/factories/Maintainer__factory.d.ts +0 -609
  242. package/dist/esm/contracts/factories/Maintainer__factory.js +0 -788
  243. package/dist/esm/contracts/factories/Maintainer__factory.js.map +0 -1
  244. package/dist/esm/contracts/factories/MockToken__factory.d.ts +0 -273
  245. package/dist/esm/contracts/factories/MockToken__factory.js.map +0 -1
  246. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  247. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js +0 -118
  248. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  249. package/dist/esm/contracts/factories/WeETH__factory.d.ts +0 -545
  250. package/dist/esm/contracts/factories/WeETH__factory.js +0 -717
  251. package/dist/esm/contracts/factories/WeETH__factory.js.map +0 -1
  252. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  253. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5320
  254. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  255. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  256. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -250
  257. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  258. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  259. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js +0 -924
  260. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  261. package/dist/esm/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  262. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js +0 -452
  263. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  264. package/dist/esm/contracts/factories/lean0/index.d.ts +0 -4
  265. package/dist/esm/contracts/factories/lean0/index.js +0 -8
  266. package/dist/esm/contracts/factories/lean0/index.js.map +0 -1
  267. package/dist/esm/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  268. package/dist/esm/contracts/lean0/IPerpetualManager.js +0 -2
  269. package/dist/esm/contracts/lean0/IPerpetualManager.js.map +0 -1
  270. package/dist/esm/contracts/lean0/LimitOrderBook.d.ts +0 -533
  271. package/dist/esm/contracts/lean0/LimitOrderBook.js +0 -2
  272. package/dist/esm/contracts/lean0/LimitOrderBook.js.map +0 -1
  273. package/dist/esm/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  274. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js +0 -2
  275. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  276. package/dist/esm/contracts/lean0/ShareToken.d.ts +0 -320
  277. package/dist/esm/contracts/lean0/ShareToken.js +0 -2
  278. package/dist/esm/contracts/lean0/ShareToken.js.map +0 -1
  279. package/dist/esm/contracts/lean0/index.d.ts +0 -4
  280. package/dist/esm/contracts/lean0/index.js +0 -2
  281. package/dist/esm/contracts/lean0/index.js.map +0 -1
  282. package/src/abi-zkevm/IPerpetualManager.json +0 -5366
package/src/marketData.ts CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  } from "./constants";
17
17
  import {
18
18
  ERC20__factory,
19
+ IPerpetualManager__factory,
19
20
  LimitOrderBook__factory,
20
21
  Multicall3__factory,
21
22
  type LimitOrderBook,
@@ -34,6 +35,10 @@ import {
34
35
  floatToABK64x64,
35
36
  getDepositAmountForLvgTrade,
36
37
  getMaxSignedPositionSize,
38
+ entropy,
39
+ expectedLoss,
40
+ pmExchangeFee,
41
+ pmFindMaxTradeSize,
37
42
  } from "./d8XMath";
38
43
  import {
39
44
  type ExchangeInfo,
@@ -45,6 +50,7 @@ import {
45
50
  type PoolState,
46
51
  type PoolStaticInfo,
47
52
  type SmartContractOrder,
53
+ type IdxPriceInfo,
48
54
  } from "./nodeSDKTypes";
49
55
  import PerpetualDataHandler from "./perpetualDataHandler";
50
56
  import PriceFeeds from "./priceFeeds";
@@ -109,7 +115,7 @@ export default class MarketData extends PerpetualDataHandler {
109
115
  const mktData = providerOrMarketData;
110
116
  this.nodeURL = mktData.config.nodeURL;
111
117
  this.provider = new JsonRpcProvider(mktData.config.nodeURL, mktData.network, { staticNetwork: true });
112
- this.proxyContract = new Contract(mktData.getProxyAddress(), this.config.proxyABI!, this.provider);
118
+ this.proxyContract = IPerpetualManager__factory.connect(mktData.getProxyAddress(), this.provider);
113
119
  this.multicall = Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, this.provider);
114
120
  ({
115
121
  nestedPerpetualIDs: this.nestedPerpetualIDs,
@@ -174,9 +180,9 @@ export default class MarketData extends PerpetualDataHandler {
174
180
  * }
175
181
  * main();
176
182
  *
177
- * @returns {Contract} read-only proxy instance
183
+ * @returns read-only proxy instance
178
184
  */
179
- public getReadOnlyProxyInstance(): Contract {
185
+ public getReadOnlyProxyInstance() {
180
186
  if (this.proxyContract == null) {
181
187
  throw Error("no proxy contract initialized. Use createProxyInstance().");
182
188
  }
@@ -405,12 +411,14 @@ export default class MarketData extends PerpetualDataHandler {
405
411
  overrides?: Overrides
406
412
  ): Promise<MarginAccount> {
407
413
  let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
414
+ const isPred = this.isPredictionMarket(symbol);
408
415
  let mgnAcct = await PerpetualDataHandler.getMarginAccount(
409
416
  traderAddr,
410
417
  symbol,
411
418
  this.symbolToPerpStaticInfo,
412
419
  new Contract(this.proxyAddr, this.config.proxyABI!, provider),
413
- [obj.idxPrices[0], obj.idxPrices[1]],
420
+ obj,
421
+ isPred,
414
422
  overrides
415
423
  );
416
424
  return mgnAcct;
@@ -430,142 +438,86 @@ export default class MarketData extends PerpetualDataHandler {
430
438
  overrides?: Overrides
431
439
  ): Promise<MarginAccount[]> {
432
440
  const MAX_SYMBOLS_PER_CALL = 10;
433
- const S2S3 = new Array<[number, number]>();
441
+ const pxInfo = new Array<IdxPriceInfo>();
434
442
  for (let i = 0; i < symbols.length; i++) {
435
443
  let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbols[i]);
436
- S2S3.push([obj.idxPrices[0], obj.idxPrices[1]]);
444
+ pxInfo.push(obj);
437
445
  }
438
446
  let mgnAcct: MarginAccount[] = [];
439
447
  let callSymbols = symbols.slice(0, MAX_SYMBOLS_PER_CALL);
440
- let pxS2S3 = S2S3.slice(0, MAX_SYMBOLS_PER_CALL);
448
+ let _px = pxInfo.slice(0, MAX_SYMBOLS_PER_CALL);
441
449
  while (callSymbols.length > 0) {
450
+ const isPred = callSymbols.map((_sym) => this.isPredictionMarket(_sym));
442
451
  let acc = await PerpetualDataHandler.getMarginAccounts(
443
452
  Array(callSymbols.length).fill(traderAddr),
444
453
  callSymbols,
445
454
  this.symbolToPerpStaticInfo,
446
455
  Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, provider),
447
456
  new Contract(this.proxyAddr, this.config.proxyABI!, provider),
448
- pxS2S3,
457
+ _px,
458
+ isPred,
449
459
  overrides
450
460
  );
451
461
  mgnAcct = mgnAcct.concat(acc);
452
462
  callSymbols = symbols.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
453
- pxS2S3 = S2S3.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
463
+ _px = pxInfo.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
454
464
  }
455
465
  return mgnAcct;
456
466
  }
457
467
 
458
- /**
459
- * Estimates what the position risk will be if a given order is executed.
460
- * @param traderAddr Address of trader
461
- * @param order Order to be submitted
462
- * @param account Position risk before trade. Defaults to current position if not given.
463
- * @param indexPriceInfo Index prices and market status (open/closed). Defaults to current market status if not given.
464
- * @returns Position risk after trade, including order cost and maximal trade sizes for position
465
- * @example
466
- * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
467
- * async function main() {
468
- * console.log(MarketData);
469
- * // setup
470
- * const config = PerpetualDataHandler.readSDKConfig("cardona");
471
- * const mktData = new MarketData(config);
472
- * await mktData.createProxyInstance();
473
- * const order: Order = {
474
- * symbol: "MATIC-USD-MATIC",
475
- * side: "BUY",
476
- * type: "MARKET",
477
- * quantity: 100,
478
- * leverage: 2,
479
- * executionTimestamp: Date.now()/1000,
480
- * };
481
- * // Get position risk conditional on this order being executed
482
- * const posRisk = await mktData.positionRiskOnTrade("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", order);
483
- * console.log(posRisk);
484
- * }
485
- * main();
486
- */
487
- public async positionRiskOnTrade(
468
+ private async dataForPositionRiskOnTrade(
469
+ symbol: string,
488
470
  traderAddr: string,
489
- order: Order,
490
- account?: MarginAccount,
491
- indexPriceInfo?: [number, number, boolean, boolean],
492
- overrides?: Overrides & { tradingFeeTbps?: number }
493
- ): Promise<{ newPositionRisk: MarginAccount; orderCost: number; maxLongTrade: number; maxShortTrade: number }> {
471
+ tradeAmountBC: number,
472
+ indexPriceInfo: IdxPriceInfo,
473
+ signedPositionNotionalBaseCCY: number,
474
+ overrides?: Overrides
475
+ ): Promise<{ account: MarginAccount; ammPrice: number; maxShortTrade: number; maxLongTrade: number }> {
494
476
  if (this.proxyContract == null || this.multicall == null) {
495
477
  throw Error("no proxy contract initialized. Use createProxyInstance().");
496
478
  }
497
-
498
- // fetch prices
499
- if (indexPriceInfo == undefined) {
500
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(order.symbol);
501
- indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
502
- }
503
-
504
- // override total fee
505
- let tradingFeeTbps: number | undefined;
506
- if (overrides) {
507
- ({ tradingFeeTbps, ...overrides } = overrides);
508
- }
509
-
510
- // signed trade amount
511
- let tradeAmountBC = Math.abs(order.quantity) * (order.side == BUY_SIDE ? 1 : -1);
512
-
513
- const accountGiven = account !== undefined;
514
-
479
+ const isPredMkt = this.isPredictionMarket(symbol);
515
480
  // create all calls
516
- const poolId = PerpetualDataHandler._getPoolIdFromSymbol(order.symbol, this.poolStaticInfos);
517
- const perpId = PerpetualDataHandler.symbolToPerpetualId(order.symbol, this.symbolToPerpStaticInfo);
518
- const fS2S3 = [indexPriceInfo[0], indexPriceInfo[1]].map((x) => floatToABK64x64(x)) as [bigint, bigint];
481
+ const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
482
+ const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
483
+ floatToABK64x64(x)
484
+ ) as [bigint, bigint, bigint];
519
485
  const proxyCalls: Multicall3.Call3Struct[] = [
520
486
  // 0: traderState
521
487
  {
522
488
  target: this.proxyContract.target,
523
489
  allowFailure: true,
524
- callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, fS2S3]),
525
- },
526
- // 1: ammState
527
- {
528
- target: this.proxyContract.target,
529
- allowFailure: true,
530
- callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, fS2S3]),
531
- },
532
- // 2: exchangeFee
533
- {
534
- target: this.proxyContract.target,
535
- allowFailure: false,
536
- callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
537
- poolId,
538
- traderAddr,
539
- order.brokerAddr ?? ZERO_ADDRESS,
540
- ]),
490
+ callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
541
491
  },
542
- // 3: perpetual price
492
+ // 1: perpetual price
543
493
  {
544
494
  target: this.proxyContract.target,
545
495
  allowFailure: true,
546
496
  callData: this.proxyContract.interface.encodeFunctionData("queryPerpetualPrice", [
547
497
  perpId,
548
498
  floatToABK64x64(tradeAmountBC),
549
- fS2S3,
499
+ [fS2, fS3],
500
+ indexPriceInfo.conf,
501
+ indexPriceInfo.predMktCLOBParams,
550
502
  ]),
551
503
  },
552
- // 4: max long pos
504
+ // 2: max long pos
553
505
  {
554
506
  target: this.proxyContract.target,
555
507
  allowFailure: false,
556
508
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
557
509
  perpId,
558
- account ? floatToABK64x64(account.positionNotionalBaseCCY * (account.side === BUY_SIDE ? 1 : -1)) : 0n,
510
+ floatToABK64x64(signedPositionNotionalBaseCCY),
559
511
  true,
560
512
  ]),
561
513
  },
562
- // 5: max short pos
514
+ // 3: max short pos
563
515
  {
564
516
  target: this.proxyContract.target,
565
517
  allowFailure: false,
566
518
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
567
519
  perpId,
568
- account ? floatToABK64x64(account.positionNotionalBaseCCY * (account.side === BUY_SIDE ? 1 : -1)) : 0n,
520
+ floatToABK64x64(signedPositionNotionalBaseCCY),
569
521
  false,
570
522
  ]),
571
523
  },
@@ -575,58 +527,126 @@ export default class MarketData extends PerpetualDataHandler {
575
527
  const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, (overrides || {}) as Overrides);
576
528
 
577
529
  // positionRisk to apply this trade on: if not given, defaults to the current trader's position
578
- if (!account) {
579
- let traderState: bigint[];
580
- if (encodedResults[0].success) {
581
- traderState = this.proxyContract.interface.decodeFunctionResult(
582
- "getTraderState",
583
- encodedResults[0].returnData
584
- )[0];
585
- } else {
586
- traderState = await this.proxyContract.getTraderState(perpId, traderAddr, fS2S3);
587
- }
588
- account = MarketData.buildMarginAccountFromState(order.symbol, traderState, this.symbolToPerpStaticInfo, [
589
- indexPriceInfo[0],
590
- indexPriceInfo[1],
591
- ]);
592
- }
593
-
594
- // perpetualState, for prices
595
- let ammState: bigint[];
596
- if (encodedResults[1].success) {
597
- ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[1].returnData)[0];
530
+ let traderState: bigint[];
531
+ if (encodedResults[0].success) {
532
+ traderState = this.proxyContract.interface.decodeFunctionResult(
533
+ "getTraderState",
534
+ encodedResults[0].returnData
535
+ )[0];
598
536
  } else {
599
- ammState = await this.proxyContract.getAMMState(perpId, fS2S3);
537
+ traderState = await this.proxyContract.getTraderState(perpId, traderAddr, [fEma, fS3]);
600
538
  }
601
- const perpetualState = PerpetualDataHandler._parseAMMState(
602
- order.symbol,
603
- ammState,
604
- [0n, 0n], // not used below
605
- indexPriceInfo,
606
- this.symbolToPerpStaticInfo
539
+ const account = MarketData.buildMarginAccountFromState(
540
+ symbol,
541
+ traderState,
542
+ this.symbolToPerpStaticInfo,
543
+ indexPriceInfo!,
544
+ isPredMkt
607
545
  );
608
- let [S2, S3, Sm] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice, perpetualState.markPrice];
609
-
610
- // exchange fee based on this trader's address (volume, token holding, etc) and his broker address (if any)
611
- const exchangeFeeTbps = this.proxyContract.interface.decodeFunctionResult(
612
- "queryExchangeFee",
613
- encodedResults[2].returnData
614
- )[0] as bigint;
615
546
 
616
547
  // amm price for this trade amount
617
548
  let ammPrice: number;
618
549
  {
619
550
  let fPrice: bigint;
620
- if (encodedResults[3].success) {
551
+ if (encodedResults[1].success) {
621
552
  fPrice = this.proxyContract.interface.decodeFunctionResult(
622
553
  "queryPerpetualPrice",
623
- encodedResults[3].returnData
554
+ encodedResults[1].returnData
624
555
  )[0];
625
556
  } else {
626
- fPrice = await this.proxyContract.queryPerpetualPrice(perpId, floatToABK64x64(tradeAmountBC), fS2S3);
557
+ fPrice = await this.proxyContract.queryPerpetualPrice(
558
+ perpId,
559
+ floatToABK64x64(tradeAmountBC),
560
+ [floatToABK64x64(indexPriceInfo.s2), floatToABK64x64(indexPriceInfo.s3 ?? 0)],
561
+ indexPriceInfo.conf,
562
+ indexPriceInfo.predMktCLOBParams
563
+ );
627
564
  }
628
565
  ammPrice = ABK64x64ToFloat(fPrice);
629
566
  }
567
+
568
+ // max buy
569
+ const fMaxLong = this.proxyContract.interface.decodeFunctionResult(
570
+ "getMaxSignedOpenTradeSizeForPos",
571
+ encodedResults[2].returnData
572
+ )[0] as bigint;
573
+ const maxLongTrade = Math.max(0, ABK64x64ToFloat(fMaxLong) - signedPositionNotionalBaseCCY);
574
+ // max sell
575
+ const fMaxShort = this.proxyContract.interface.decodeFunctionResult(
576
+ "getMaxSignedOpenTradeSizeForPos",
577
+ encodedResults[3].returnData
578
+ )[0] as bigint;
579
+ const maxShortTrade = Math.max(0, Math.abs(ABK64x64ToFloat(fMaxShort)) - signedPositionNotionalBaseCCY);
580
+ return { account: account, ammPrice: ammPrice, maxShortTrade: maxShortTrade, maxLongTrade: maxLongTrade };
581
+ }
582
+
583
+ /**
584
+ * Estimates what the position risk will be if a given order is executed.
585
+ * @param traderAddr Address of trader
586
+ * @param order Order to be submitted
587
+ * @param signedPositionNotionalBaseCCY signed position notional of current position (before trade)
588
+ * @param tradingFeeTbps trading fee in tenth of basis points (exchange fee and broker fee)
589
+ * @param indexPriceInfo Index prices and market status (open/closed). Defaults to current market status if not given.
590
+ * @returns Position risk after trade, including order cost and maximal trade sizes for position
591
+ * @example
592
+ * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
593
+ * async function main() {
594
+ * console.log(MarketData);
595
+ * // setup
596
+ * const config = PerpetualDataHandler.readSDKConfig("cardona");
597
+ * const mktData = new MarketData(config);
598
+ * await mktData.createProxyInstance();
599
+ * const order: Order = {
600
+ * symbol: "MATIC-USD-MATIC",
601
+ * side: "BUY",
602
+ * type: "MARKET",
603
+ * quantity: 100,
604
+ * leverage: 2,
605
+ * executionTimestamp: Date.now()/1000,
606
+ * };
607
+ * // Get position risk conditional on this order being executed
608
+ * const posRisk = await mktData.positionRiskOnTrade("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", order, 0, 60);
609
+ * console.log(posRisk);
610
+ * }
611
+ * main();
612
+ */
613
+ public async positionRiskOnTrade(
614
+ traderAddr: string,
615
+ order: Order,
616
+ signedPositionNotionalBaseCCY: number,
617
+ tradingFeeTbps: number,
618
+ indexPriceInfo?: IdxPriceInfo,
619
+ overrides?: Overrides
620
+ ): Promise<{ newPositionRisk: MarginAccount; orderCost: number; maxLongTrade: number; maxShortTrade: number }> {
621
+ if (this.proxyContract == null || this.multicall == null) {
622
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
623
+ }
624
+ const isPredMkt = this.isPredictionMarket(order.symbol);
625
+ // fetch prices
626
+ if (indexPriceInfo == undefined) {
627
+ indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(order.symbol);
628
+ }
629
+
630
+ // signed trade amount
631
+ let tradeAmountBC = Math.abs(order.quantity) * (order.side == BUY_SIDE ? 1 : -1);
632
+ const symbol = order.symbol;
633
+
634
+ let obj = await this.dataForPositionRiskOnTrade(
635
+ symbol,
636
+ traderAddr,
637
+ tradeAmountBC,
638
+ indexPriceInfo,
639
+ signedPositionNotionalBaseCCY,
640
+ overrides
641
+ );
642
+ const account = obj.account;
643
+ const maxLongTrade = obj.maxLongTrade;
644
+ const maxShortTrade = obj.maxShortTrade;
645
+ const ammPrice = obj.ammPrice;
646
+ let Sm = account.markPrice;
647
+ let S2 = indexPriceInfo.s2;
648
+ let S3 = account.collToQuoteConversion;
649
+
630
650
  // price for this order = amm price if no limit given, else conservatively adjusted
631
651
  let tradePrice: number;
632
652
  if (order.limitPrice == undefined) {
@@ -660,27 +680,6 @@ export default class MarketData extends PerpetualDataHandler {
660
680
  }
661
681
  }
662
682
  }
663
- // max buy
664
- const fMaxLong = this.proxyContract.interface.decodeFunctionResult(
665
- "getMaxSignedOpenTradeSizeForPos",
666
- encodedResults[4].returnData
667
- )[0] as bigint;
668
- const maxLongTrade =
669
- account.side == BUY_SIDE
670
- ? Math.max(0, ABK64x64ToFloat(fMaxLong) - (accountGiven ? 0 : account.positionNotionalBaseCCY))
671
- : ABK64x64ToFloat(fMaxLong) + account.positionNotionalBaseCCY;
672
- // max sell
673
- const fMaxShort = this.proxyContract.interface.decodeFunctionResult(
674
- "getMaxSignedOpenTradeSizeForPos",
675
- encodedResults[5].returnData
676
- )[0] as bigint;
677
- const maxShortTrade =
678
- account.side == SELL_SIDE
679
- ? Math.max(
680
- 0,
681
- Math.abs(ABK64x64ToFloat(fMaxShort)) - (accountGiven ? 0 : Math.abs(account.positionNotionalBaseCCY))
682
- )
683
- : Math.abs(ABK64x64ToFloat(fMaxShort)) + Math.abs(account.positionNotionalBaseCCY);
684
683
 
685
684
  // Current state:
686
685
  let lotSizeBC = MarketData._getLotSize(order.symbol, this.symbolToPerpStaticInfo);
@@ -705,10 +704,6 @@ export default class MarketData extends PerpetualDataHandler {
705
704
  }
706
705
  let newSide = newPositionBC > 0 ? BUY_SIDE : newPositionBC < 0 ? SELL_SIDE : CLOSED_SIDE;
707
706
 
708
- if (tradingFeeTbps === undefined) {
709
- // use usual input if not overriden
710
- tradingFeeTbps = Number(exchangeFeeTbps) + (order.brokerFeeTbps ?? 0);
711
- }
712
707
  let tradingFeeCC = (Math.abs(tradeAmountBC) * tradingFeeTbps * 1e-5 * S2) / S3;
713
708
  let referralFeeCC = this.symbolToPerpStaticInfo.get(account.symbol)!.referralRebate;
714
709
  // Trade type:
@@ -733,7 +728,7 @@ export default class MarketData extends PerpetualDataHandler {
733
728
  let initialMarginRate = this.symbolToPerpStaticInfo.get(account.symbol)!.initialMarginRate;
734
729
  targetLvg = isFlip || isOpen ? order.leverage ?? 1 / initialMarginRate : 0;
735
730
  let [b0, pos0] = isOpen ? [0, 0] : [account.collateralCC, currentPositionBC];
736
- traderDepositCC = getDepositAmountForLvgTrade(pos0, b0, tradeAmountBC, targetLvg, tradePrice, S3, Sm);
731
+ traderDepositCC = getDepositAmountForLvgTrade(pos0, b0, tradeAmountBC, targetLvg, tradePrice, S3, Sm, isPredMkt);
737
732
  // fees are paid from wallet in this case
738
733
  traderDepositCC += tradingFeeCC + referralFeeCC;
739
734
  }
@@ -754,12 +749,20 @@ export default class MarketData extends PerpetualDataHandler {
754
749
  let newMarginCashCC = currentMarginCashCC + deltaCashCC + traderDepositCC;
755
750
  let newEntryPrice = newPositionBC == 0 ? 0 : Math.abs(newLockedInValueQC / newPositionBC);
756
751
  let newMarginBalanceCC = newMarginCashCC + (newPositionBC * Sm - newLockedInValueQC) / S3;
757
- let newLeverage =
758
- newPositionBC == 0
759
- ? 0
760
- : newMarginBalanceCC <= 0
761
- ? Infinity
762
- : (Math.abs(newPositionBC) * Sm) / S3 / newMarginBalanceCC;
752
+
753
+ let newLeverage: number;
754
+ if (newPositionBC === 0) {
755
+ newLeverage = 0;
756
+ } else if (newMarginBalanceCC <= 0) {
757
+ newLeverage = Infinity;
758
+ } else {
759
+ let p = Sm;
760
+ if (isPredMkt) {
761
+ p -= 1;
762
+ p = newPositionBC > 0 ? p : 1 - p;
763
+ }
764
+ newLeverage = Math.abs(newPositionBC * p) / S3 / newMarginBalanceCC;
765
+ }
763
766
 
764
767
  // Liquidation params
765
768
  let [S2Liq, S3Liq, tau] = MarketData._getLiquidationParams(
@@ -769,6 +772,7 @@ export default class MarketData extends PerpetualDataHandler {
769
772
  newMarginCashCC,
770
773
  Sm,
771
774
  S3,
775
+ S2,
772
776
  this.symbolToPerpStaticInfo
773
777
  );
774
778
 
@@ -795,6 +799,25 @@ export default class MarketData extends PerpetualDataHandler {
795
799
  };
796
800
  }
797
801
 
802
+ /**
803
+ * Fee is relative to base-currency amount (=trade amount)
804
+ * @param state current perpetual state (need longBC and shortBC)
805
+ * @param maxMaintMgnRate maintenance margin rate param for pred mkts
806
+ * @param Sm Mark price
807
+ * @param tradeAmtBC signed trade amount
808
+ * @param tradeMgnRate margin rate param from perpetual
809
+ * @returns relative exchange fee in decimals
810
+ */
811
+ public static exchangeFeePrdMkts(
812
+ state: PerpetualState,
813
+ maxMaintMgnRate: number,
814
+ Sm: number,
815
+ tradeAmtBC: number,
816
+ tradeMgnRate: number
817
+ ): number {
818
+ return pmExchangeFee(Sm - 1, maxMaintMgnRate, state.shortBC, state.longBC, tradeAmtBC, tradeMgnRate);
819
+ }
820
+
798
821
  /**
799
822
  * Estimates what the position risk will be if given amount of collateral is added/removed from the account.
800
823
  * @param {number} deltaCollateral Amount of collateral to add or remove (signed)
@@ -819,7 +842,7 @@ export default class MarketData extends PerpetualDataHandler {
819
842
  public async positionRiskOnCollateralAction(
820
843
  deltaCollateral: number,
821
844
  account: MarginAccount,
822
- indexPriceInfo?: [number, number, boolean, boolean],
845
+ indexPriceInfo?: IdxPriceInfo,
823
846
  overrides?: Overrides
824
847
  ): Promise<MarginAccount> {
825
848
  if (this.proxyContract == null) {
@@ -829,11 +852,17 @@ export default class MarketData extends PerpetualDataHandler {
829
852
  throw new Error("not enough margin to remove");
830
853
  }
831
854
  if (indexPriceInfo == undefined) {
832
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
833
- indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
855
+ indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
834
856
  }
835
857
  let perpetualState = await this.getPerpetualState(account.symbol, indexPriceInfo, overrides);
836
- let [S2, S3, Sm] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice, perpetualState.markPrice];
858
+ let Sm; //mark price
859
+ if (this.isPredictionMarket(account.symbol)) {
860
+ Sm = indexPriceInfo.ema + perpetualState.markPremium;
861
+ } else {
862
+ Sm = perpetualState.indexPrice * (1 + perpetualState.markPremium);
863
+ }
864
+
865
+ let [S2, S3] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice];
837
866
 
838
867
  // no position: just increase collateral and kill liquidation vars
839
868
  if (account.positionNotionalBaseCCY == 0) {
@@ -884,6 +913,7 @@ export default class MarketData extends PerpetualDataHandler {
884
913
  newMarginCashCC,
885
914
  Sm,
886
915
  S3,
916
+ S2,
887
917
  this.symbolToPerpStaticInfo
888
918
  );
889
919
 
@@ -906,13 +936,15 @@ export default class MarketData extends PerpetualDataHandler {
906
936
  }
907
937
 
908
938
  /**
909
- * Calculates liquidation prices for a given position
939
+ * Calculates liquidation prices for a position
940
+ * constructed in positionRiskOnTrade/positionRiskOnCollateralAction
910
941
  * @param symbol Perpetual symbol
911
942
  * @param lockedInQC Locked in value
912
943
  * @param signedPositionBC Signed position size
913
- * @param marginCashCC Cash in margin account
944
+ * @param marginCashCC Available cash in margin account (includes unpaid funding)
914
945
  * @param markPrice Mark price
915
- * @param collToQuoteConversion Collateral index price
946
+ * @param collToQuoteConversion Collateral index price (S3)
947
+ * @param S2 index price
916
948
  * @param symbolToPerpStaticInfo Symbol-to-perp static info mapping
917
949
  * @returns [Base index price, Collateral index price, Maintenance margin rate]
918
950
  * @ignore
@@ -924,30 +956,35 @@ export default class MarketData extends PerpetualDataHandler {
924
956
  marginCashCC: number,
925
957
  markPrice: number,
926
958
  collToQuoteConversion: number,
959
+ S2: number,
927
960
  symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>
928
961
  ): [number, number | undefined, number] {
929
962
  let S2Liq: number, S3Liq: number | undefined;
930
- let tau = symbolToPerpStaticInfo.get(symbol)!.maintenanceMarginRate;
931
- let ccyType = symbolToPerpStaticInfo.get(symbol)!.collateralCurrencyType;
932
- if (ccyType == CollaterlCCY.BASE) {
933
- S2Liq = calculateLiquidationPriceCollateralBase(lockedInQC, signedPositionBC, marginCashCC, tau);
934
- S3Liq = S2Liq;
935
- } else if (ccyType == CollaterlCCY.QUANTO) {
936
- S3Liq = collToQuoteConversion;
937
- S2Liq = calculateLiquidationPriceCollateralQuanto(
938
- lockedInQC,
939
- signedPositionBC,
940
- marginCashCC,
941
- tau,
942
- collToQuoteConversion,
943
- markPrice
944
- );
945
- } else {
946
- S2Liq = calculateLiquidationPriceCollateralQuote(lockedInQC, signedPositionBC, marginCashCC, tau);
947
- }
948
- // floor at 0
949
- S2Liq = S2Liq < 0 ? 0 : S2Liq;
950
- S3Liq = S3Liq && S3Liq < 0 ? 0 : S3Liq;
963
+ const staticInfo = symbolToPerpStaticInfo.get(symbol)!;
964
+ let tau = staticInfo.maintenanceMarginRate;
965
+ let ccyType = staticInfo.collateralCurrencyType;
966
+ const isPred = MarketData.isPredictionMarketStatic(staticInfo);
967
+ const idx_availableCashCC = 2;
968
+ const idx_cash = 3;
969
+ const idx_notional = 4;
970
+ const idx_locked_in = 5;
971
+ const idx_mark_price = 8;
972
+ const idx_s3 = 9;
973
+ let traderState = new Array<bigint>(10);
974
+ traderState[idx_availableCashCC] = floatToABK64x64(marginCashCC);
975
+ traderState[idx_cash] = traderState[idx_availableCashCC];
976
+ traderState[idx_notional] = floatToABK64x64(signedPositionBC);
977
+ traderState[idx_locked_in] = floatToABK64x64(lockedInQC);
978
+ traderState[idx_mark_price] = floatToABK64x64(markPrice);
979
+ traderState[idx_s3] = floatToABK64x64(collToQuoteConversion);
980
+
981
+ [S2Liq, S3Liq, tau, ,] = MarketData._calculateLiquidationPrice(
982
+ symbol,
983
+ traderState,
984
+ S2,
985
+ symbolToPerpStaticInfo,
986
+ isPred
987
+ );
951
988
  return [S2Liq, S3Liq, tau];
952
989
  }
953
990
 
@@ -1137,23 +1174,35 @@ export default class MarketData extends PerpetualDataHandler {
1137
1174
  if (!this.proxyContract || !this.multicall) {
1138
1175
  throw new Error("proxy contract not initialized");
1139
1176
  }
1177
+ if (this.isPredictionMarket(symbol)) {
1178
+ // prediction markets
1179
+ return this.pmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
1180
+ }
1181
+ // regular markets
1182
+ return this.rmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
1183
+ }
1184
+
1185
+ private async pmMaxOrderSizeForTrader(
1186
+ traderAddr: string,
1187
+ symbol: string,
1188
+ overrides?: Overrides
1189
+ ): Promise<{ buy: number; sell: number }> {
1190
+ if (!this.proxyContract || !this.multicall) {
1191
+ throw new Error("proxy contract not initialized");
1192
+ }
1193
+ const IERC20 = new Interface(ERC20_ABI) as ERC20Interface;
1140
1194
  const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
1141
- const poolId = this.getPoolIdFromSymbol(symbol);
1142
1195
  const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
1143
- const perpInfo = this.getPerpetualStaticInfo(symbol);
1144
- const IERC20 = new Interface(ERC20_ABI) as ERC20Interface;
1145
-
1146
- const indexPriceInfo: [number, number, boolean, boolean] = await this.priceFeedGetter
1147
- .fetchPricesForPerpetual(symbol)
1148
- .then((obj) => [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]]);
1149
- const fS2S3 = [indexPriceInfo[0], indexPriceInfo[1]].map((x) => floatToABK64x64(x)) as [bigint, bigint];
1150
- let coll2SettlePromise = this.fetchCollateralToSettlementConversion(symbol);
1196
+ const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1197
+ const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
1198
+ floatToABK64x64(x)
1199
+ ) as [bigint, bigint, bigint];
1151
1200
  const proxyCalls: Multicall3.Call3Struct[] = [
1152
1201
  // 0: traderState
1153
1202
  {
1154
1203
  target: this.proxyContract.target,
1155
1204
  allowFailure: false,
1156
- callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, fS2S3]),
1205
+ callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
1157
1206
  },
1158
1207
 
1159
1208
  // 1: wallet balance
@@ -1162,46 +1211,100 @@ export default class MarketData extends PerpetualDataHandler {
1162
1211
  allowFailure: false,
1163
1212
  callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
1164
1213
  },
1165
- // 2: exchange fee
1214
+ // 2: amm state
1166
1215
  {
1167
1216
  target: this.proxyContract.target,
1168
1217
  allowFailure: false,
1169
- callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
1170
- poolId,
1171
- traderAddr,
1172
- ZERO_ADDRESS,
1173
- ]),
1218
+ callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, [fS2, fS3]]),
1174
1219
  },
1175
1220
  ];
1176
1221
 
1177
1222
  // multicall
1178
1223
  const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, overrides || {});
1179
-
1180
- // position risk
1181
- const idxNotional = 4;
1182
1224
  const traderState = this.proxyContract.interface.decodeFunctionResult(
1183
1225
  "getTraderState",
1184
1226
  encodedResults[0].returnData
1185
1227
  )[0];
1186
- const account = MarketData.buildMarginAccountFromState(symbol, traderState, this.symbolToPerpStaticInfo, [
1187
- indexPriceInfo[0],
1188
- indexPriceInfo[1],
1189
- ]);
1190
-
1191
- // fee rate
1192
- const feeRateTbps = this.proxyContract.interface.decodeFunctionResult(
1193
- "queryExchangeFee",
1194
- encodedResults[2].returnData
1195
- )[0] as bigint;
1196
-
1197
- const feeRate = 1e-5 * Number(feeRateTbps);
1198
-
1199
- // Max based on margin requirements:
1200
1228
  const walletBalance = decNToFloat(
1201
1229
  IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0],
1202
1230
  poolInfo.poolSettleTokenDecimals
1203
1231
  );
1232
+ const ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[2].returnData)[0];
1204
1233
 
1234
+ const account = MarketData.buildMarginAccountFromState(
1235
+ symbol,
1236
+ traderState,
1237
+ this.symbolToPerpStaticInfo,
1238
+ indexPriceInfo,
1239
+ true //isPredMkt
1240
+ );
1241
+ const openInterestBC = ABK64x64ToFloat(ammState[11]);
1242
+ const net = -ABK64x64ToFloat(ammState[1]);
1243
+ let totLong, totShort;
1244
+ if (net < 0) {
1245
+ totLong = openInterestBC;
1246
+ totShort = openInterestBC - Math.abs(net);
1247
+ } else {
1248
+ totLong = openInterestBC - net;
1249
+ totShort = openInterestBC;
1250
+ }
1251
+
1252
+ let currentPositionBC = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
1253
+ const Sm = ABK64x64ToFloat(traderState[8]);
1254
+ // settlement token must be equal to collateral token for walletBalance to be correct
1255
+ const availCashCC = account.collateralCC + walletBalance + account.unrealizedFundingCollateralCCY;
1256
+ const idxNotional = 4;
1257
+ const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(
1258
+ perpId,
1259
+ traderState[idxNotional],
1260
+ overrides
1261
+ );
1262
+
1263
+ const maxShort = pmFindMaxTradeSize(
1264
+ -1,
1265
+ currentPositionBC,
1266
+ availCashCC,
1267
+ account.entryPrice * currentPositionBC,
1268
+ Sm,
1269
+ Sm,
1270
+ indexPriceInfo.s3 ?? 0,
1271
+ totLong,
1272
+ totShort,
1273
+ maxShortPosPerp,
1274
+ maxLongPosPerp
1275
+ );
1276
+ const maxLong = pmFindMaxTradeSize(
1277
+ 1,
1278
+ currentPositionBC,
1279
+ availCashCC,
1280
+ account.entryPrice * currentPositionBC,
1281
+ Sm,
1282
+ Sm,
1283
+ indexPriceInfo.s3 ?? 0,
1284
+ totLong,
1285
+ totShort,
1286
+ maxShortPosPerp,
1287
+ maxLongPosPerp
1288
+ );
1289
+ return { buy: maxLong, sell: maxShort };
1290
+ }
1291
+
1292
+ /**
1293
+ * Returns the maximal allowed short pos and long pos (signed) for a trader
1294
+ * with given notional (in ABDK format) in the perpetual, ignoring the traders wallet balance
1295
+ * @param perpId
1296
+ * @param currentTraderPos ABDK64x64 notional position of trader
1297
+ * @param overrides
1298
+ * @returns [maxShortPos, maxLongPos] signed maximal position sizes
1299
+ */
1300
+ public async getMaxShortLongPos(
1301
+ perpId: number,
1302
+ currentTraderPos: bigint,
1303
+ overrides?: Overrides
1304
+ ): Promise<[number, number]> {
1305
+ if (!this.proxyContract || !this.multicall) {
1306
+ throw new Error("proxy contract not initialized");
1307
+ }
1205
1308
  const proxyCalls2: Multicall3.Call3Struct[] = [
1206
1309
  // 0: max long
1207
1310
  {
@@ -1209,7 +1312,7 @@ export default class MarketData extends PerpetualDataHandler {
1209
1312
  allowFailure: false,
1210
1313
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
1211
1314
  perpId,
1212
- traderState[idxNotional],
1315
+ currentTraderPos,
1213
1316
  true,
1214
1317
  ]),
1215
1318
  },
@@ -1219,7 +1322,7 @@ export default class MarketData extends PerpetualDataHandler {
1219
1322
  allowFailure: false,
1220
1323
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
1221
1324
  perpId,
1222
- traderState[idxNotional],
1325
+ currentTraderPos,
1223
1326
  false,
1224
1327
  ]),
1225
1328
  },
@@ -1236,7 +1339,7 @@ export default class MarketData extends PerpetualDataHandler {
1236
1339
  encodedResults2[0].returnData
1237
1340
  )[0] as bigint
1238
1341
  );
1239
- const maxLongPosPerp = maxLongOrderPerp + ABK64x64ToFloat(traderState[idxNotional]);
1342
+ const maxLongPosPerp = maxLongOrderPerp + ABK64x64ToFloat(currentTraderPos);
1240
1343
  // max short
1241
1344
  const maxShortOrderPerp = ABK64x64ToFloat(
1242
1345
  this.proxyContract.interface.decodeFunctionResult(
@@ -1244,8 +1347,91 @@ export default class MarketData extends PerpetualDataHandler {
1244
1347
  encodedResults2[1].returnData
1245
1348
  )[0] as bigint
1246
1349
  );
1247
- const maxShortPosPerp = maxShortOrderPerp + ABK64x64ToFloat(traderState[idxNotional]);
1350
+ const maxShortPosPerp = maxShortOrderPerp + ABK64x64ToFloat(currentTraderPos);
1351
+ return [maxShortPosPerp, maxLongPosPerp];
1352
+ }
1353
+
1354
+ private async rmMaxOrderSizeForTrader(
1355
+ traderAddr: string,
1356
+ symbol: string,
1357
+ overrides?: Overrides
1358
+ ): Promise<{ buy: number; sell: number }> {
1359
+ const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
1360
+ const poolId = this.getPoolIdFromSymbol(symbol);
1361
+ const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
1362
+ const perpInfo = this.getPerpetualStaticInfo(symbol);
1363
+ const IERC20 = new Interface(ERC20_ABI) as ERC20Interface;
1364
+ const isPredMkt = false;
1365
+ const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1366
+ let coll2SettlePromise = this.fetchCollateralToSettlementConversion(symbol);
1367
+ const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
1368
+ floatToABK64x64(x)
1369
+ ) as [bigint, bigint, bigint];
1370
+ if (!this.proxyContract || !this.multicall) {
1371
+ throw new Error("proxy contract not initialized");
1372
+ }
1373
+ const proxyCalls: Multicall3.Call3Struct[] = [
1374
+ // 0: traderState
1375
+ {
1376
+ target: this.proxyContract.target,
1377
+ allowFailure: false,
1378
+ callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
1379
+ },
1248
1380
 
1381
+ // 1: wallet balance
1382
+ {
1383
+ target: poolInfo.poolSettleTokenAddr,
1384
+ allowFailure: false,
1385
+ callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
1386
+ },
1387
+ // 2: exchange fee
1388
+ {
1389
+ target: this.proxyContract.target,
1390
+ allowFailure: false,
1391
+ callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
1392
+ poolId,
1393
+ traderAddr,
1394
+ ZERO_ADDRESS,
1395
+ ]),
1396
+ },
1397
+ ];
1398
+
1399
+ // multicall
1400
+ const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, overrides || {});
1401
+
1402
+ // position risk
1403
+ const idxNotional = 4;
1404
+ const traderState = this.proxyContract.interface.decodeFunctionResult(
1405
+ "getTraderState",
1406
+ encodedResults[0].returnData
1407
+ )[0];
1408
+ const account = MarketData.buildMarginAccountFromState(
1409
+ symbol,
1410
+ traderState,
1411
+ this.symbolToPerpStaticInfo,
1412
+ indexPriceInfo,
1413
+ isPredMkt
1414
+ );
1415
+
1416
+ // fee rate
1417
+ const feeRateTbps = this.proxyContract.interface.decodeFunctionResult(
1418
+ "queryExchangeFee",
1419
+ encodedResults[2].returnData
1420
+ )[0] as bigint;
1421
+
1422
+ const feeRate = 1e-5 * Number(feeRateTbps);
1423
+
1424
+ // Max based on margin requirements:
1425
+ const walletBalance = decNToFloat(
1426
+ IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0],
1427
+ poolInfo.poolSettleTokenDecimals
1428
+ );
1429
+
1430
+ const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(
1431
+ perpId,
1432
+ traderState[idxNotional],
1433
+ overrides
1434
+ );
1249
1435
  const curPos = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
1250
1436
 
1251
1437
  const px: number = await coll2SettlePromise;
@@ -1259,7 +1445,7 @@ export default class MarketData extends PerpetualDataHandler {
1259
1445
  perpInfo.initialMarginRate,
1260
1446
  feeRate,
1261
1447
  account.markPrice,
1262
- indexPriceInfo[0],
1448
+ indexPriceInfo.s2,
1263
1449
  account.collToQuoteConversion
1264
1450
  );
1265
1451
  const maxShortPosAccount = getMaxSignedPositionSize(
@@ -1271,7 +1457,7 @@ export default class MarketData extends PerpetualDataHandler {
1271
1457
  perpInfo.initialMarginRate,
1272
1458
  feeRate,
1273
1459
  account.markPrice,
1274
- indexPriceInfo[0],
1460
+ indexPriceInfo.s2,
1275
1461
  account.collToQuoteConversion
1276
1462
  );
1277
1463
 
@@ -1339,12 +1525,11 @@ export default class MarketData extends PerpetualDataHandler {
1339
1525
  *
1340
1526
  * @returns {number} Price of index in given currency.
1341
1527
  */
1342
- public async getOraclePrice(base: string, quote: string, overrides?: Overrides): Promise<number | undefined> {
1528
+ public async getOraclePrice(base: string, quote: string, overrides?: Overrides) {
1343
1529
  if (!this.proxyContract) {
1344
1530
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1345
1531
  }
1346
- let px = await this.proxyContract.getOraclePrice([toBytes4(base), toBytes4(quote)], overrides || {});
1347
- return px == undefined ? undefined : ABK64x64ToFloat(px);
1532
+ return await this.proxyContract.getOraclePrice([toBytes4(base), toBytes4(quote)], overrides || {});
1348
1533
  }
1349
1534
 
1350
1535
  /**
@@ -1420,6 +1605,7 @@ export default class MarketData extends PerpetualDataHandler {
1420
1605
  /**
1421
1606
  * Get the current mark price
1422
1607
  * @param symbol symbol of the form ETH-USD-MATIC
1608
+ * @param indexPrices optional. IdxPriceInfo
1423
1609
  * @example
1424
1610
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
1425
1611
  * async function main() {
@@ -1436,19 +1622,19 @@ export default class MarketData extends PerpetualDataHandler {
1436
1622
  *
1437
1623
  * @returns {number} mark price
1438
1624
  */
1439
- public async getMarkPrice(symbol: string, indexPrices?: [number, number]): Promise<number> {
1625
+ public async getMarkPrice(symbol: string, indexPrices?: IdxPriceInfo): Promise<number> {
1440
1626
  if (this.proxyContract == null) {
1441
1627
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1442
1628
  }
1443
1629
  if (indexPrices == undefined) {
1444
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1445
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
1630
+ indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1446
1631
  }
1447
1632
  return await PerpetualDataHandler._queryPerpetualMarkPrice(
1448
1633
  symbol,
1449
1634
  this.symbolToPerpStaticInfo,
1450
1635
  this.proxyContract,
1451
- indexPrices
1636
+ indexPrices,
1637
+ this.isPredictionMarket(symbol)
1452
1638
  );
1453
1639
  }
1454
1640
 
@@ -1456,6 +1642,7 @@ export default class MarketData extends PerpetualDataHandler {
1456
1642
  * get the current price for a given quantity
1457
1643
  * @param symbol symbol of the form ETH-USD-MATIC
1458
1644
  * @param quantity quantity to be traded, negative if short
1645
+ * @param priceInfo [s2, s3, conf, params]; for non-prediction markets conf/params can be 0
1459
1646
  * @example
1460
1647
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
1461
1648
  * async function main() {
@@ -1475,23 +1662,24 @@ export default class MarketData extends PerpetualDataHandler {
1475
1662
  public async getPerpetualPrice(
1476
1663
  symbol: string,
1477
1664
  quantity: number,
1478
- indexPrices?: [number, number],
1665
+ priceInfo?: IdxPriceInfo,
1479
1666
  overrides?: Overrides
1480
1667
  ): Promise<number> {
1481
1668
  if (this.proxyContract == null) {
1482
1669
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1483
1670
  }
1484
- if (indexPrices == undefined) {
1671
+ if (priceInfo == undefined) {
1485
1672
  // fetch from API
1486
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1487
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
1673
+ priceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1488
1674
  }
1489
1675
  return await PerpetualDataHandler._queryPerpetualPrice(
1490
1676
  symbol,
1491
1677
  quantity,
1492
1678
  this.symbolToPerpStaticInfo,
1493
1679
  this.proxyContract,
1494
- indexPrices,
1680
+ [priceInfo.s2, priceInfo.s3 ?? 0], //s2,s3
1681
+ priceInfo.conf, //conf
1682
+ priceInfo.predMktCLOBParams, //params
1495
1683
  overrides
1496
1684
  );
1497
1685
  }
@@ -1503,15 +1691,14 @@ export default class MarketData extends PerpetualDataHandler {
1503
1691
  */
1504
1692
  public async getPerpetualState(
1505
1693
  symbol: string,
1506
- indexPriceInfo?: [number, number, boolean, boolean],
1694
+ indexPriceInfo?: IdxPriceInfo,
1507
1695
  overrides?: Overrides
1508
1696
  ): Promise<PerpetualState> {
1509
1697
  if (this.proxyContract == null || this.multicall == null) {
1510
1698
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1511
1699
  }
1512
1700
  if (indexPriceInfo == undefined) {
1513
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1514
- indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
1701
+ indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1515
1702
  }
1516
1703
  let state: PerpetualState = await PerpetualDataHandler._queryPerpetualState(
1517
1704
  symbol,
@@ -1743,7 +1930,7 @@ export default class MarketData extends PerpetualDataHandler {
1743
1930
  * Result is in collateral currency
1744
1931
  * @param {string} traderAddr address of the trader
1745
1932
  * @param {string} symbol perpetual symbol of the form BTC-USD-MATIC
1746
- * @param indexPrices optional index prices, will otherwise fetch from REST API
1933
+ * @param indexPrices optional indexPriceInfo
1747
1934
  * @returns available margin in collateral currency
1748
1935
  * @example
1749
1936
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
@@ -1762,7 +1949,7 @@ export default class MarketData extends PerpetualDataHandler {
1762
1949
  public async getAvailableMargin(
1763
1950
  traderAddr: string,
1764
1951
  symbol: string,
1765
- indexPrices?: [number, number],
1952
+ indexPrices?: IdxPriceInfo,
1766
1953
  overrides?: Overrides
1767
1954
  ): Promise<number> {
1768
1955
  if (!this.proxyContract) {
@@ -1771,14 +1958,16 @@ export default class MarketData extends PerpetualDataHandler {
1771
1958
 
1772
1959
  if (indexPrices == undefined) {
1773
1960
  // fetch from API
1774
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1775
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
1961
+ indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1776
1962
  }
1777
1963
  let perpID = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
1778
1964
  let traderState = await this.proxyContract.getTraderState(
1779
1965
  perpID,
1780
1966
  traderAddr,
1781
- indexPrices.map((x) => floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x)) as [bigint, bigint],
1967
+ [indexPrices.s2, indexPrices.s3].map((x) => floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x)) as [
1968
+ bigint,
1969
+ bigint
1970
+ ],
1782
1971
  overrides || {}
1783
1972
  );
1784
1973
  const idx_availableMargin = 1;
@@ -2111,7 +2300,8 @@ export default class MarketData extends PerpetualDataHandler {
2111
2300
  quoteCurrency: contractSymbolToSymbol(perp.S2QuoteCCY!, _symbolList)!,
2112
2301
  indexPrice: 0, //fill later
2113
2302
  collToQuoteIndexPrice: 0, //fill later
2114
- markPrice: ABK64x64ToFloat(perp.currentMarkPremiumRate!.fPrice), // fill later: indexS2 * (1 + markPremiumRate),
2303
+ markPremium: ABK64x64ToFloat(perp.currentMarkPremiumRate!.fPrice),
2304
+ markPrice: 0, //fill later
2115
2305
  midPrice: 0, // fill later
2116
2306
  currentFundingRateBps: 1e4 * ABK64x64ToFloat(perp.fCurrentFundingRate!),
2117
2307
  openInterestBC: ABK64x64ToFloat(perp.fOpenInterest!),
@@ -2188,7 +2378,6 @@ export default class MarketData extends PerpetualDataHandler {
2188
2378
  perp.isMarketClosed = perp.isMarketClosed || idxPriceS3Pair![1];
2189
2379
  }
2190
2380
  perp.indexPrice = idxPriceS2Pair![0];
2191
- perp.markPrice = idxPriceS2Pair![0] * (1 + perp.markPrice); // currently filled with mark premium rate
2192
2381
  let indexS3 = 1;
2193
2382
  if (info!.collateralCurrencyType == COLLATERAL_CURRENCY_BASE) {
2194
2383
  indexS3 = idxPriceS2Pair![0];
@@ -2196,6 +2385,18 @@ export default class MarketData extends PerpetualDataHandler {
2196
2385
  indexS3 = idxPriceS3Pair[0];
2197
2386
  }
2198
2387
  perp.collToQuoteIndexPrice = indexS3;
2388
+
2389
+ const emaKey = info!.S2Symbol + ":ema";
2390
+ let markPrice: number;
2391
+ if (idxPriceMap.has(emaKey)) {
2392
+ let ema: number;
2393
+ let res = idxPriceMap.get(emaKey);
2394
+ ema = res![0];
2395
+ markPrice = ema + perp.markPremium;
2396
+ } else {
2397
+ markPrice = perp.indexPrice * (1 + perp.markPremium);
2398
+ }
2399
+ perp.markPrice = markPrice;
2199
2400
  perp.midPrice = midPriceMap.get(symbol3s!)!;
2200
2401
  // which pool?
2201
2402
  const poolId = info!.poolId;
@@ -2293,10 +2494,7 @@ export default class MarketData extends PerpetualDataHandler {
2293
2494
  * @param symbol Perpetual symbol of the form BTC-USDc-USDC
2294
2495
  * @returns Prices and market-closed information
2295
2496
  */
2296
- public async fetchPricesForPerpetual(symbol: string): Promise<{
2297
- idxPrices: number[];
2298
- mktClosed: boolean[];
2299
- }> {
2497
+ public async fetchPricesForPerpetual(symbol: string): Promise<IdxPriceInfo> {
2300
2498
  return this.priceFeedGetter.fetchPricesForPerpetual(symbol);
2301
2499
  }
2302
2500
  }