@drift-labs/sdk 0.2.0-master.25 → 0.2.0-master.27

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 (124) hide show
  1. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +14 -13
  2. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +30 -27
  3. package/lib/accounts/types.d.ts +9 -9
  4. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +15 -14
  5. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +38 -34
  6. package/lib/addresses/pda.d.ts +7 -6
  7. package/lib/addresses/pda.js +31 -27
  8. package/lib/admin.d.ts +13 -7
  9. package/lib/admin.js +111 -44
  10. package/lib/clearingHouse.d.ts +71 -42
  11. package/lib/clearingHouse.js +767 -278
  12. package/lib/clearingHouseConfig.d.ts +2 -2
  13. package/lib/clearingHouseUser.d.ts +24 -22
  14. package/lib/clearingHouseUser.js +273 -177
  15. package/lib/config.d.ts +7 -7
  16. package/lib/config.js +21 -21
  17. package/lib/constants/numericConstants.d.ts +12 -12
  18. package/lib/constants/numericConstants.js +13 -13
  19. package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
  20. package/lib/constants/{markets.js → perpMarkets.js} +4 -4
  21. package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
  22. package/lib/constants/{banks.js → spotMarkets.js} +16 -16
  23. package/lib/dlob/DLOB.d.ts +73 -0
  24. package/lib/dlob/DLOB.js +557 -0
  25. package/lib/dlob/DLOBNode.d.ts +52 -0
  26. package/lib/dlob/DLOBNode.js +82 -0
  27. package/lib/dlob/NodeList.d.ts +26 -0
  28. package/lib/dlob/NodeList.js +138 -0
  29. package/lib/events/types.d.ts +2 -1
  30. package/lib/events/types.js +1 -0
  31. package/lib/examples/makeTradeExample.js +7 -7
  32. package/lib/idl/clearing_house.json +1152 -503
  33. package/lib/index.d.ts +10 -3
  34. package/lib/index.js +10 -3
  35. package/lib/math/amm.d.ts +2 -2
  36. package/lib/math/amm.js +1 -1
  37. package/lib/math/funding.d.ts +6 -6
  38. package/lib/math/funding.js +2 -1
  39. package/lib/math/margin.d.ts +4 -4
  40. package/lib/math/margin.js +18 -11
  41. package/lib/math/market.d.ts +11 -10
  42. package/lib/math/market.js +30 -7
  43. package/lib/math/oracles.d.ts +2 -1
  44. package/lib/math/oracles.js +11 -1
  45. package/lib/math/orders.d.ts +6 -6
  46. package/lib/math/orders.js +31 -16
  47. package/lib/math/position.d.ts +13 -13
  48. package/lib/math/position.js +19 -19
  49. package/lib/math/spotBalance.d.ts +22 -0
  50. package/lib/math/spotBalance.js +193 -0
  51. package/lib/math/spotMarket.d.ts +4 -0
  52. package/lib/math/spotMarket.js +8 -0
  53. package/lib/math/spotPosition.d.ts +6 -0
  54. package/lib/math/spotPosition.js +23 -0
  55. package/lib/math/state.js +2 -2
  56. package/lib/math/trade.d.ts +4 -4
  57. package/lib/orderParams.d.ts +4 -4
  58. package/lib/orderParams.js +12 -4
  59. package/lib/serum/serumSubscriber.d.ts +23 -0
  60. package/lib/serum/serumSubscriber.js +41 -0
  61. package/lib/serum/types.d.ts +11 -0
  62. package/lib/serum/types.js +2 -0
  63. package/lib/tx/retryTxSender.d.ts +1 -1
  64. package/lib/tx/retryTxSender.js +4 -2
  65. package/lib/tx/types.d.ts +1 -1
  66. package/lib/types.d.ts +148 -57
  67. package/lib/types.js +39 -11
  68. package/lib/userMap/userMap.d.ts +25 -0
  69. package/lib/userMap/userMap.js +73 -0
  70. package/lib/userMap/userStatsMap.d.ts +19 -0
  71. package/lib/userMap/userStatsMap.js +68 -0
  72. package/package.json +6 -3
  73. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +42 -38
  74. package/src/accounts/types.ts +12 -9
  75. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +65 -52
  76. package/src/addresses/pda.ts +49 -44
  77. package/src/admin.ts +190 -55
  78. package/src/clearingHouse.ts +1092 -365
  79. package/src/clearingHouseConfig.ts +2 -2
  80. package/src/clearingHouseUser.ts +518 -255
  81. package/src/config.ts +30 -30
  82. package/src/constants/numericConstants.ts +17 -15
  83. package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
  84. package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
  85. package/src/dlob/DLOB.ts +884 -0
  86. package/src/dlob/DLOBNode.ts +163 -0
  87. package/src/dlob/NodeList.ts +185 -0
  88. package/src/events/types.ts +3 -0
  89. package/src/examples/makeTradeExample.js +152 -75
  90. package/src/examples/makeTradeExample.ts +10 -8
  91. package/src/idl/clearing_house.json +1152 -503
  92. package/src/index.ts +10 -3
  93. package/src/math/amm.ts +6 -3
  94. package/src/math/funding.ts +7 -7
  95. package/src/math/margin.ts +34 -23
  96. package/src/math/market.ts +72 -20
  97. package/src/math/oracles.ts +18 -1
  98. package/src/math/orders.ts +33 -25
  99. package/src/math/position.ts +31 -31
  100. package/src/math/spotBalance.ts +316 -0
  101. package/src/math/spotMarket.ts +9 -0
  102. package/src/math/spotPosition.ts +47 -0
  103. package/src/math/state.ts +2 -2
  104. package/src/math/trade.ts +4 -4
  105. package/src/orderParams.ts +16 -8
  106. package/src/serum/serumSubscriber.ts +80 -0
  107. package/src/serum/types.ts +13 -0
  108. package/src/tx/retryTxSender.ts +5 -2
  109. package/src/tx/types.ts +2 -1
  110. package/src/types.ts +135 -56
  111. package/src/userMap/userMap.ts +100 -0
  112. package/src/userMap/userStatsMap.ts +110 -0
  113. package/tests/bn/test.ts +2 -3
  114. package/tests/dlob/helpers.ts +322 -0
  115. package/tests/dlob/test.ts +2865 -0
  116. package/lib/math/bankBalance.d.ts +0 -15
  117. package/lib/math/bankBalance.js +0 -150
  118. package/src/constants/numericConstants.js +0 -41
  119. package/src/math/bankBalance.ts +0 -258
  120. package/src/math/oracles.js +0 -26
  121. package/src/math/state.js +0 -15
  122. package/src/orderParams.js +0 -20
  123. package/src/slot/SlotSubscriber.js +0 -39
  124. package/src/tokenFaucet.js +0 -189
@@ -5,10 +5,11 @@ const types_1 = require("./types");
5
5
  const position_1 = require("./math/position");
6
6
  const numericConstants_1 = require("./constants/numericConstants");
7
7
  const _1 = require(".");
8
- const bankBalance_1 = require("./math/bankBalance");
8
+ const spotBalance_1 = require("./math/spotBalance");
9
9
  const margin_1 = require("./math/margin");
10
10
  const pollingUserAccountSubscriber_1 = require("./accounts/pollingUserAccountSubscriber");
11
11
  const webSocketUserAccountSubscriber_1 = require("./accounts/webSocketUserAccountSubscriber");
12
+ const spotPosition_1 = require("./math/spotPosition");
12
13
  class ClearingHouseUser {
13
14
  constructor(config) {
14
15
  var _a;
@@ -59,11 +60,12 @@ class ClearingHouseUser {
59
60
  * @returns userPosition
60
61
  */
61
62
  getUserPosition(marketIndex) {
62
- return this.getUserAccount().positions.find((position) => position.marketIndex.eq(marketIndex));
63
+ return this.getUserAccount().perpPositions.find((position) => position.marketIndex.eq(marketIndex));
63
64
  }
64
65
  getEmptyPosition(marketIndex) {
65
66
  return {
66
67
  baseAssetAmount: numericConstants_1.ZERO,
68
+ remainderBaseAssetAmount: numericConstants_1.ZERO,
67
69
  lastCumulativeFundingRate: numericConstants_1.ZERO,
68
70
  marketIndex,
69
71
  quoteAssetAmount: numericConstants_1.ZERO,
@@ -112,7 +114,7 @@ class ClearingHouseUser {
112
114
  getSettledLPPosition(marketIndex) {
113
115
  const _position = this.getUserPosition(marketIndex);
114
116
  const position = this.getClonedPosition(_position);
115
- const market = this.clearingHouse.getMarketAccount(position.marketIndex);
117
+ const market = this.clearingHouse.getPerpMarketAccount(position.marketIndex);
116
118
  const nShares = position.lpShares;
117
119
  const deltaBaa = market.amm.marketPositionPerLp.baseAssetAmount
118
120
  .sub(position.lastNetBaseAssetAmountPerLp)
@@ -126,22 +128,22 @@ class ClearingHouseUser {
126
128
  const sign = { true: new _1.BN(1), false: new _1.BN(-1) }[v.gte(numericConstants_1.ZERO).toString()];
127
129
  return sign;
128
130
  }
129
- const remainder = deltaBaa
130
- .abs()
131
- .mod(market.amm.baseAssetAmountStepSize)
132
- .mul(sign(deltaBaa));
133
- const _standardizedBaa = deltaBaa.sub(remainder);
134
- let remainderBaa;
135
- if (_standardizedBaa.abs().gte(market.amm.baseAssetAmountStepSize)) {
136
- remainderBaa = remainder;
131
+ function standardize(amount, stepsize) {
132
+ const remainder = amount.abs().mod(stepsize).mul(sign(amount));
133
+ const standardizedAmount = amount.sub(remainder);
134
+ return [standardizedAmount, remainder];
137
135
  }
138
- else {
139
- remainderBaa = deltaBaa;
136
+ const [standardizedBaa, remainderBaa] = standardize(deltaBaa, market.amm.baseAssetAmountStepSize);
137
+ position.remainderBaseAssetAmount =
138
+ position.remainderBaseAssetAmount.add(remainderBaa);
139
+ if (position.remainderBaseAssetAmount
140
+ .abs()
141
+ .gte(market.amm.baseAssetAmountStepSize)) {
142
+ const [newStandardizedBaa, newRemainderBaa] = standardize(position.remainderBaseAssetAmount, market.amm.baseAssetAmountStepSize);
143
+ position.baseAssetAmount =
144
+ position.baseAssetAmount.add(newStandardizedBaa);
145
+ position.remainderBaseAssetAmount = newRemainderBaa;
140
146
  }
141
- const standardizedBaa = deltaBaa.sub(remainderBaa);
142
- const reaminderPerLP = remainderBaa.mul(numericConstants_1.AMM_RESERVE_PRECISION).div(nShares);
143
- position.lastNetBaseAssetAmountPerLp =
144
- market.amm.marketPositionPerLp.baseAssetAmount.sub(reaminderPerLP);
145
147
  let updateType;
146
148
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
147
149
  updateType = 'open';
@@ -211,54 +213,8 @@ class ClearingHouseUser {
211
213
  /**
212
214
  * @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
213
215
  */
214
- getMarginRequirement(type) {
215
- return this.getUserAccount()
216
- .positions.reduce((marginRequirement, marketPosition) => {
217
- const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
218
- if (marketPosition.lpShares.gt(numericConstants_1.ZERO)) {
219
- // is an lp
220
- // clone so we dont mutate the position
221
- marketPosition = this.getClonedPosition(marketPosition);
222
- // settle position
223
- const [settledPosition, dustBaa, _] = this.getSettledLPPosition(market.marketIndex);
224
- marketPosition.baseAssetAmount =
225
- settledPosition.baseAssetAmount.add(dustBaa);
226
- marketPosition.quoteAssetAmount = settledPosition.quoteAssetAmount;
227
- // open orders
228
- let openAsks;
229
- if (market.amm.maxBaseAssetReserve > market.amm.baseAssetReserve) {
230
- openAsks = market.amm.maxBaseAssetReserve
231
- .sub(market.amm.baseAssetReserve)
232
- .mul(marketPosition.lpShares)
233
- .div(market.amm.sqrtK)
234
- .mul(new _1.BN(-1));
235
- }
236
- else {
237
- openAsks = numericConstants_1.ZERO;
238
- }
239
- let openBids;
240
- if (market.amm.minBaseAssetReserve < market.amm.baseAssetReserve) {
241
- openBids = market.amm.baseAssetReserve
242
- .sub(market.amm.minBaseAssetReserve)
243
- .mul(marketPosition.lpShares)
244
- .div(market.amm.sqrtK);
245
- }
246
- else {
247
- openBids = numericConstants_1.ZERO;
248
- }
249
- marketPosition.openAsks = marketPosition.openAsks.add(openAsks);
250
- marketPosition.openBids = marketPosition.openBids.add(openBids);
251
- }
252
- const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
253
- const worstCaseAssetValue = worstCaseBaseAssetAmount
254
- .abs()
255
- .mul(this.getOracleDataForMarket(market.marketIndex).price)
256
- .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
257
- return marginRequirement.add(worstCaseAssetValue
258
- .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), type)))
259
- .div(numericConstants_1.MARGIN_PRECISION));
260
- }, numericConstants_1.ZERO)
261
- .add(this.getBankLiabilityValue(undefined, type));
216
+ getMarginRequirement(marginCategory, liquidationBuffer) {
217
+ return this.getTotalPerpPositionValue(marginCategory, liquidationBuffer, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, liquidationBuffer, true));
262
218
  }
263
219
  /**
264
220
  * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
@@ -269,24 +225,26 @@ class ClearingHouseUser {
269
225
  /**
270
226
  * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
271
227
  */
272
- getMaintenanceMarginRequirement() {
273
- return this.getMarginRequirement('Maintenance');
228
+ getMaintenanceMarginRequirement(liquidationBuffer) {
229
+ return this.getMarginRequirement('Maintenance', liquidationBuffer);
274
230
  }
275
231
  /**
276
232
  * calculates unrealized position price pnl
277
233
  * @returns : Precision QUOTE_PRECISION
278
234
  */
279
235
  getUnrealizedPNL(withFunding, marketIndex, withWeightMarginCategory) {
236
+ const quoteSpotMarket = this.clearingHouse.getQuoteSpotMarketAccount();
280
237
  return this.getUserAccount()
281
- .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
282
- .reduce((unrealizedPnl, marketPosition) => {
283
- const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
284
- let positionUnrealizedPnl = (0, _1.calculatePositionPNL)(market, marketPosition, withFunding, this.getOracleDataForMarket(market.marketIndex));
238
+ .perpPositions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
239
+ .reduce((unrealizedPnl, perpPosition) => {
240
+ const market = this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex);
241
+ const oraclePriceData = this.getOracleDataForMarket(market.marketIndex);
242
+ let positionUnrealizedPnl = (0, _1.calculatePositionPNL)(market, perpPosition, withFunding, oraclePriceData);
285
243
  if (withWeightMarginCategory !== undefined) {
286
244
  if (positionUnrealizedPnl.gt(numericConstants_1.ZERO)) {
287
245
  positionUnrealizedPnl = positionUnrealizedPnl
288
- .mul((0, _1.calculateUnrealizedAssetWeight)(market, positionUnrealizedPnl, withWeightMarginCategory))
289
- .div(new _1.BN(numericConstants_1.BANK_WEIGHT_PRECISION));
246
+ .mul((0, _1.calculateUnrealizedAssetWeight)(market, quoteSpotMarket, positionUnrealizedPnl, withWeightMarginCategory, oraclePriceData))
247
+ .div(new _1.BN(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION));
290
248
  }
291
249
  }
292
250
  return unrealizedPnl.add(positionUnrealizedPnl);
@@ -298,84 +256,217 @@ class ClearingHouseUser {
298
256
  */
299
257
  getUnrealizedFundingPNL(marketIndex) {
300
258
  return this.getUserAccount()
301
- .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
302
- .reduce((pnl, marketPosition) => {
303
- const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
304
- return pnl.add((0, _1.calculatePositionFundingPNL)(market, marketPosition));
259
+ .perpPositions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
260
+ .reduce((pnl, perpPosition) => {
261
+ const market = this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex);
262
+ return pnl.add((0, _1.calculatePositionFundingPNL)(market, perpPosition));
305
263
  }, numericConstants_1.ZERO);
306
264
  }
307
- getBankLiabilityValue(bankIndex, withWeightMarginCategory) {
308
- return this.getUserAccount().bankBalances.reduce((totalLiabilityValue, bankBalance) => {
309
- if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
310
- (0, types_1.isVariant)(bankBalance.balanceType, 'deposit') ||
311
- (bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))) {
265
+ getSpotMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders) {
266
+ return this.getUserAccount().spotPositions.reduce((totalLiabilityValue, spotPosition) => {
267
+ if ((0, spotPosition_1.isSpotPositionAvailable)(spotPosition) ||
268
+ (marketIndex !== undefined &&
269
+ !spotPosition.marketIndex.eq(marketIndex))) {
312
270
  return totalLiabilityValue;
313
271
  }
314
- // Todo this needs to account for whether it's based on initial or maintenance requirements
315
- const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
316
- const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
317
- let liabilityValue = tokenAmount
318
- .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
319
- .div(numericConstants_1.MARK_PRICE_PRECISION)
320
- .div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP)));
321
- if (withWeightMarginCategory !== undefined) {
322
- const weight = (0, bankBalance_1.calculateLiabilityWeight)(tokenAmount, bankAccount, withWeightMarginCategory);
323
- liabilityValue = liabilityValue
272
+ const spotMarketAccount = this.clearingHouse.getSpotMarketAccount(spotPosition.marketIndex);
273
+ if (spotPosition.marketIndex.eq(numericConstants_1.QUOTE_SPOT_MARKET_INDEX)) {
274
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
275
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
276
+ let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
277
+ if (marginCategory === 'Initial') {
278
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().customMarginRatio));
279
+ }
280
+ const weightedTokenValue = tokenAmount
281
+ .mul(weight)
282
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
283
+ return totalLiabilityValue.add(weightedTokenValue);
284
+ }
285
+ else {
286
+ return totalLiabilityValue;
287
+ }
288
+ }
289
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
290
+ if (!includeOpenOrders) {
291
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
292
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
293
+ const liabilityValue = this.getSpotLiabilityValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer);
294
+ return totalLiabilityValue.add(liabilityValue);
295
+ }
296
+ else {
297
+ return totalLiabilityValue;
298
+ }
299
+ }
300
+ const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, this.getOracleDataForSpotMarket(spotPosition.marketIndex));
301
+ let newTotalLiabilityValue = totalLiabilityValue;
302
+ if (worstCaseTokenAmount.lt(numericConstants_1.ZERO)) {
303
+ const baseLiabilityValue = this.getSpotLiabilityValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer);
304
+ newTotalLiabilityValue =
305
+ newTotalLiabilityValue.add(baseLiabilityValue);
306
+ }
307
+ if (worstCaseQuoteTokenAmount.lt(numericConstants_1.ZERO)) {
308
+ let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
309
+ if (marginCategory === 'Initial') {
310
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().customMarginRatio));
311
+ }
312
+ const weightedTokenValue = worstCaseQuoteTokenAmount
324
313
  .mul(weight)
325
- .div(numericConstants_1.BANK_WEIGHT_PRECISION);
314
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
315
+ newTotalLiabilityValue =
316
+ newTotalLiabilityValue.add(weightedTokenValue);
326
317
  }
327
- return totalLiabilityValue.add(liabilityValue);
318
+ return newTotalLiabilityValue;
328
319
  }, numericConstants_1.ZERO);
329
320
  }
330
- getBankAssetValue(bankIndex, withWeightMarginCategory) {
331
- return this.getUserAccount().bankBalances.reduce((totalAssetValue, bankBalance) => {
332
- if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
333
- (0, types_1.isVariant)(bankBalance.balanceType, 'borrow') ||
334
- (bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))) {
321
+ getSpotLiabilityValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer) {
322
+ let liabilityValue = (0, _1.getTokenValue)(tokenAmount, spotMarketAccount.decimals, oraclePriceData);
323
+ if (marginCategory !== undefined) {
324
+ let weight = (0, spotBalance_1.calculateLiabilityWeight)(tokenAmount, spotMarketAccount, marginCategory);
325
+ if (marginCategory === 'Initial') {
326
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().customMarginRatio));
327
+ }
328
+ if (liquidationBuffer !== undefined) {
329
+ weight = weight.add(liquidationBuffer);
330
+ }
331
+ liabilityValue = liabilityValue
332
+ .mul(weight)
333
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
334
+ }
335
+ return liabilityValue;
336
+ }
337
+ getSpotMarketAssetValue(marketIndex, marginCategory, includeOpenOrders) {
338
+ return this.getUserAccount().spotPositions.reduce((totalAssetValue, spotPosition) => {
339
+ if ((0, spotPosition_1.isSpotPositionAvailable)(spotPosition) ||
340
+ (marketIndex !== undefined &&
341
+ !spotPosition.marketIndex.eq(marketIndex))) {
335
342
  return totalAssetValue;
336
343
  }
337
344
  // Todo this needs to account for whether it's based on initial or maintenance requirements
338
- const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
339
- const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
340
- let assetValue = tokenAmount
341
- .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
342
- .div(numericConstants_1.MARK_PRICE_PRECISION)
343
- .div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP)));
344
- if (withWeightMarginCategory !== undefined) {
345
- const weight = (0, bankBalance_1.calculateAssetWeight)(tokenAmount, bankAccount, withWeightMarginCategory);
346
- assetValue = assetValue.mul(weight).div(numericConstants_1.BANK_WEIGHT_PRECISION);
345
+ const spotMarketAccount = this.clearingHouse.getSpotMarketAccount(spotPosition.marketIndex);
346
+ if (spotPosition.marketIndex.eq(numericConstants_1.QUOTE_SPOT_MARKET_INDEX)) {
347
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
348
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
349
+ return totalAssetValue.add(tokenAmount);
350
+ }
351
+ else {
352
+ return totalAssetValue;
353
+ }
354
+ }
355
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
356
+ if (!includeOpenOrders) {
357
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
358
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
359
+ const assetValue = this.getSpotAssetValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory);
360
+ return totalAssetValue.add(assetValue);
361
+ }
362
+ else {
363
+ return totalAssetValue;
364
+ }
365
+ }
366
+ const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, this.getOracleDataForSpotMarket(spotPosition.marketIndex));
367
+ let newTotalAssetValue = totalAssetValue;
368
+ if (worstCaseTokenAmount.gt(numericConstants_1.ZERO)) {
369
+ const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, marginCategory);
370
+ newTotalAssetValue = newTotalAssetValue.add(baseAssetValue);
347
371
  }
348
- return totalAssetValue.add(assetValue);
372
+ if (worstCaseQuoteTokenAmount.gt(numericConstants_1.ZERO)) {
373
+ newTotalAssetValue = newTotalAssetValue.add(worstCaseQuoteTokenAmount);
374
+ }
375
+ return newTotalAssetValue;
349
376
  }, numericConstants_1.ZERO);
350
377
  }
351
- getNetBankValue(withWeightMarginCategory) {
352
- return this.getBankAssetValue(undefined, withWeightMarginCategory).sub(this.getBankLiabilityValue(undefined, withWeightMarginCategory));
378
+ getSpotAssetValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory) {
379
+ let assetValue = (0, _1.getTokenValue)(tokenAmount, spotMarketAccount.decimals, oraclePriceData);
380
+ if (marginCategory !== undefined) {
381
+ const weight = (0, spotBalance_1.calculateAssetWeight)(tokenAmount, spotMarketAccount, marginCategory);
382
+ assetValue = assetValue.mul(weight).div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
383
+ }
384
+ return assetValue;
385
+ }
386
+ getNetSpotMarketValue(withWeightMarginCategory) {
387
+ return this.getSpotMarketAssetValue(undefined, withWeightMarginCategory).sub(this.getSpotMarketLiabilityValue(undefined, withWeightMarginCategory));
353
388
  }
354
389
  /**
355
390
  * calculates TotalCollateral: collateral + unrealized pnl
356
391
  * @returns : Precision QUOTE_PRECISION
357
392
  */
358
393
  getTotalCollateral(marginCategory = 'Initial') {
359
- return this.getBankAssetValue(undefined, marginCategory).add(this.getUnrealizedPNL(true, undefined, marginCategory));
394
+ return this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
360
395
  }
361
396
  /**
362
397
  * calculates sum of position value across all positions in margin system
363
398
  * @returns : Precision QUOTE_PRECISION
364
399
  */
365
- getTotalPositionValue() {
366
- return this.getUserAccount().positions.reduce((positionValue, marketPosition) => {
367
- const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
368
- const posVal = (0, margin_1.calculateBaseAssetValueWithOracle)(market, marketPosition, this.getOracleDataForMarket(market.marketIndex));
369
- return positionValue.add(posVal);
400
+ getTotalPerpPositionValue(marginCategory, liquidationBuffer, includeOpenOrders) {
401
+ return this.getUserAccount().perpPositions.reduce((totalPerpValue, perpPosition) => {
402
+ const market = this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex);
403
+ if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
404
+ // is an lp
405
+ // clone so we dont mutate the position
406
+ perpPosition = this.getClonedPosition(perpPosition);
407
+ // settle position
408
+ const [settledPosition, dustBaa, _] = this.getSettledLPPosition(market.marketIndex);
409
+ perpPosition.baseAssetAmount =
410
+ settledPosition.baseAssetAmount.add(dustBaa);
411
+ perpPosition.quoteAssetAmount = settledPosition.quoteAssetAmount;
412
+ // open orders
413
+ let openAsks;
414
+ if (market.amm.maxBaseAssetReserve > market.amm.baseAssetReserve) {
415
+ openAsks = market.amm.maxBaseAssetReserve
416
+ .sub(market.amm.baseAssetReserve)
417
+ .mul(perpPosition.lpShares)
418
+ .div(market.amm.sqrtK)
419
+ .mul(new _1.BN(-1));
420
+ }
421
+ else {
422
+ openAsks = numericConstants_1.ZERO;
423
+ }
424
+ let openBids;
425
+ if (market.amm.minBaseAssetReserve < market.amm.baseAssetReserve) {
426
+ openBids = market.amm.baseAssetReserve
427
+ .sub(market.amm.minBaseAssetReserve)
428
+ .mul(perpPosition.lpShares)
429
+ .div(market.amm.sqrtK);
430
+ }
431
+ else {
432
+ openBids = numericConstants_1.ZERO;
433
+ }
434
+ perpPosition.openAsks = perpPosition.openAsks.add(openAsks);
435
+ perpPosition.openBids = perpPosition.openBids.add(openBids);
436
+ }
437
+ let valuationPrice = this.getOracleDataForMarket(market.marketIndex).price;
438
+ if ((0, types_1.isVariant)(market.status, 'settlement')) {
439
+ valuationPrice = market.settlementPrice;
440
+ }
441
+ const baseAssetAmount = includeOpenOrders
442
+ ? (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition)
443
+ : perpPosition.baseAssetAmount;
444
+ let baseAssetValue = baseAssetAmount
445
+ .abs()
446
+ .mul(valuationPrice)
447
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
448
+ if (marginCategory) {
449
+ let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory));
450
+ if (marginCategory === 'Initial') {
451
+ marginRatio = _1.BN.max(marginRatio, new _1.BN(this.getUserAccount().customMarginRatio));
452
+ }
453
+ if (liquidationBuffer !== undefined) {
454
+ marginRatio = marginRatio.add(liquidationBuffer);
455
+ }
456
+ baseAssetValue = baseAssetValue
457
+ .mul(marginRatio)
458
+ .div(numericConstants_1.MARGIN_PRECISION);
459
+ }
460
+ return totalPerpValue.add(baseAssetValue);
370
461
  }, numericConstants_1.ZERO);
371
462
  }
372
463
  /**
373
464
  * calculates position value in margin system
374
465
  * @returns : Precision QUOTE_PRECISION
375
466
  */
376
- getPositionValue(marketIndex, oraclePriceData) {
467
+ getPerpPositionValue(marketIndex, oraclePriceData) {
377
468
  const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
378
- const market = this.clearingHouse.getMarketAccount(userPosition.marketIndex);
469
+ const market = this.clearingHouse.getPerpMarketAccount(userPosition.marketIndex);
379
470
  return (0, margin_1.calculateBaseAssetValueWithOracle)(market, userPosition, oraclePriceData);
380
471
  }
381
472
  getPositionSide(currentPosition) {
@@ -394,7 +485,7 @@ class ClearingHouseUser {
394
485
  * @returns : Precision MARK_PRICE_PRECISION
395
486
  */
396
487
  getPositionEstimatedExitPriceAndPnl(position, amountToClose, useAMMClose = false) {
397
- const market = this.clearingHouse.getMarketAccount(position.marketIndex);
488
+ const market = this.clearingHouse.getPerpMarketAccount(position.marketIndex);
398
489
  const entryPrice = (0, position_1.calculateEntryPrice)(position);
399
490
  const oraclePriceData = this.getOracleDataForMarket(position.marketIndex);
400
491
  if (amountToClose) {
@@ -433,13 +524,13 @@ class ClearingHouseUser {
433
524
  * calculates current user leverage across all positions
434
525
  * @returns : Precision TEN_THOUSAND
435
526
  */
436
- getLeverage() {
437
- const totalCollateral = this.getTotalCollateral();
438
- const totalPositionValue = this.getTotalPositionValue();
439
- if (totalPositionValue.eq(numericConstants_1.ZERO) && totalCollateral.eq(numericConstants_1.ZERO)) {
527
+ getLeverage(marginCategory) {
528
+ const totalLiabilityValue = this.getTotalPerpPositionValue(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
529
+ const totalAssetValue = this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
530
+ if (totalAssetValue.eq(numericConstants_1.ZERO) && totalLiabilityValue.eq(numericConstants_1.ZERO)) {
440
531
  return numericConstants_1.ZERO;
441
532
  }
442
- return totalPositionValue.mul(numericConstants_1.TEN_THOUSAND).div(totalCollateral);
533
+ return totalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(totalAssetValue);
443
534
  }
444
535
  /**
445
536
  * calculates max allowable leverage exceeding hitting requirement category
@@ -447,7 +538,7 @@ class ClearingHouseUser {
447
538
  * @returns : Precision TEN_THOUSAND
448
539
  */
449
540
  getMaxLeverage(marketIndex, category = 'Initial') {
450
- const market = this.clearingHouse.getMarketAccount(marketIndex);
541
+ const market = this.clearingHouse.getPerpMarketAccount(marketIndex);
451
542
  const marginRatioCategory = (0, _1.calculateMarketMarginRatio)(market,
452
543
  // worstCaseBaseAssetAmount.abs(),
453
544
  numericConstants_1.ZERO, // todo
@@ -459,30 +550,34 @@ class ClearingHouseUser {
459
550
  * calculates margin ratio: total collateral / |total position value|
460
551
  * @returns : Precision TEN_THOUSAND
461
552
  */
462
- getMarginRatio() {
463
- const totalPositionValue = this.getTotalPositionValue();
464
- if (totalPositionValue.eq(numericConstants_1.ZERO)) {
553
+ getMarginRatio(marginCategory) {
554
+ const totalLiabilityValue = this.getTotalPerpPositionValue(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
555
+ if (totalLiabilityValue.eq(numericConstants_1.ZERO)) {
465
556
  return numericConstants_1.BN_MAX;
466
557
  }
467
- return this.getTotalCollateral().mul(numericConstants_1.TEN_THOUSAND).div(totalPositionValue);
558
+ const totalAssetValue = this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
559
+ return totalAssetValue.mul(numericConstants_1.TEN_THOUSAND).div(totalLiabilityValue);
468
560
  }
469
561
  canBeLiquidated() {
470
562
  const totalCollateral = this.getTotalCollateral();
471
- const partialMaintenanceRequirement = this.getMaintenanceMarginRequirement();
472
- const marginRatio = this.getMarginRatio();
473
- const canLiquidate = totalCollateral.lt(partialMaintenanceRequirement);
474
- return [canLiquidate, marginRatio];
563
+ // if user being liq'd, can continue to be liq'd until total collateral above the margin requirement plus buffer
564
+ let liquidationBuffer = undefined;
565
+ if (this.getUserAccount().beingLiquidated) {
566
+ liquidationBuffer = new _1.BN(this.clearingHouse.getStateAccount().liquidationMarginBufferRatio);
567
+ }
568
+ const maintenanceRequirement = this.getMaintenanceMarginRequirement(liquidationBuffer);
569
+ return totalCollateral.lt(maintenanceRequirement);
475
570
  }
476
571
  /**
477
572
  * Checks if any user position cumulative funding differs from respective market cumulative funding
478
573
  * @returns
479
574
  */
480
575
  needsToSettleFundingPayment() {
481
- for (const userPosition of this.getUserAccount().positions) {
576
+ for (const userPosition of this.getUserAccount().perpPositions) {
482
577
  if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
483
578
  continue;
484
579
  }
485
- const market = this.clearingHouse.getMarketAccount(userPosition.marketIndex);
580
+ const market = this.clearingHouse.getPerpMarketAccount(userPosition.marketIndex);
486
581
  if (market.amm.cumulativeFundingRateLong.eq(userPosition.lastCumulativeFundingRate) ||
487
582
  market.amm.cumulativeFundingRateShort.eq(userPosition.lastCumulativeFundingRate)) {
488
583
  continue;
@@ -493,12 +588,12 @@ class ClearingHouseUser {
493
588
  }
494
589
  /**
495
590
  * Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
496
- * @param marketPosition
591
+ * @param PerpPosition
497
592
  * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
498
593
  * @param partial
499
594
  * @returns Precision : MARK_PRICE_PRECISION
500
595
  */
501
- liquidationPrice(marketPosition, positionBaseSizeChange = numericConstants_1.ZERO) {
596
+ liquidationPrice(perpPosition, positionBaseSizeChange = numericConstants_1.ZERO) {
502
597
  // solves formula for example canBeLiquidated below
503
598
  /* example: assume BTC price is $40k (examine 10% up/down)
504
599
 
@@ -511,15 +606,16 @@ class ClearingHouseUser {
511
606
  3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
512
607
  const totalCollateral = this.getTotalCollateral();
513
608
  // calculate the total position value ignoring any value from the target market of the trade
514
- const totalPositionValueExcludingTargetMarket = this.getTotalPositionValueExcludingMarket(marketPosition.marketIndex);
515
- const currentMarketPosition = this.getUserPosition(marketPosition.marketIndex) ||
516
- this.getEmptyPosition(marketPosition.marketIndex);
517
- const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
518
- const proposedBaseAssetAmount = currentMarketPositionBaseSize.add(positionBaseSizeChange);
609
+ const totalPositionValueExcludingTargetMarket = this.getTotalPerpPositionValueExcludingMarket(perpPosition.marketIndex);
610
+ const currentPerpPosition = this.getUserPosition(perpPosition.marketIndex) ||
611
+ this.getEmptyPosition(perpPosition.marketIndex);
612
+ const currentPerpPositionBaseSize = currentPerpPosition.baseAssetAmount;
613
+ const proposedBaseAssetAmount = currentPerpPositionBaseSize.add(positionBaseSizeChange);
519
614
  // calculate position for current market after trade
520
- const proposedMarketPosition = {
521
- marketIndex: marketPosition.marketIndex,
615
+ const proposedPerpPosition = {
616
+ marketIndex: perpPosition.marketIndex,
522
617
  baseAssetAmount: proposedBaseAssetAmount,
618
+ remainderBaseAssetAmount: numericConstants_1.ZERO,
523
619
  quoteAssetAmount: new _1.BN(0),
524
620
  lastCumulativeFundingRate: numericConstants_1.ZERO,
525
621
  quoteEntryAmount: new _1.BN(0),
@@ -534,13 +630,13 @@ class ClearingHouseUser {
534
630
  };
535
631
  if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
536
632
  return new _1.BN(-1);
537
- const market = this.clearingHouse.getMarketAccount(proposedMarketPosition.marketIndex);
538
- const proposedMarketPositionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, proposedMarketPosition, this.getOracleDataForMarket(market.marketIndex));
633
+ const market = this.clearingHouse.getPerpMarketAccount(proposedPerpPosition.marketIndex);
634
+ const proposedPerpPositionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, proposedPerpPosition, this.getOracleDataForMarket(market.marketIndex));
539
635
  // total position value after trade
540
- const totalPositionValueAfterTrade = totalPositionValueExcludingTargetMarket.add(proposedMarketPositionValue);
541
- const marginRequirementExcludingTargetMarket = this.getUserAccount().positions.reduce((totalMarginRequirement, position) => {
542
- if (!position.marketIndex.eq(marketPosition.marketIndex)) {
543
- const market = this.clearingHouse.getMarketAccount(position.marketIndex);
636
+ const totalPositionValueAfterTrade = totalPositionValueExcludingTargetMarket.add(proposedPerpPositionValue);
637
+ const marginRequirementExcludingTargetMarket = this.getUserAccount().perpPositions.reduce((totalMarginRequirement, position) => {
638
+ if (!position.marketIndex.eq(perpPosition.marketIndex)) {
639
+ const market = this.clearingHouse.getPerpMarketAccount(position.marketIndex);
544
640
  const positionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, position, this.getOracleDataForMarket(market.marketIndex));
545
641
  const marketMarginRequirement = positionValue
546
642
  .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, position.baseAssetAmount.abs(), 'Maintenance')))
@@ -552,14 +648,14 @@ class ClearingHouseUser {
552
648
  const freeCollateralExcludingTargetMarket = totalCollateral.sub(marginRequirementExcludingTargetMarket);
553
649
  // if the position value after the trade is less than free collateral, there is no liq price
554
650
  if (totalPositionValueAfterTrade.lte(freeCollateralExcludingTargetMarket) &&
555
- proposedMarketPosition.baseAssetAmount.abs().gt(numericConstants_1.ZERO)) {
651
+ proposedPerpPosition.baseAssetAmount.abs().gt(numericConstants_1.ZERO)) {
556
652
  return new _1.BN(-1);
557
653
  }
558
- const marginRequirementAfterTrade = marginRequirementExcludingTargetMarket.add(proposedMarketPositionValue
559
- .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, proposedMarketPosition.baseAssetAmount.abs(), 'Maintenance')))
654
+ const marginRequirementAfterTrade = marginRequirementExcludingTargetMarket.add(proposedPerpPositionValue
655
+ .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, proposedPerpPosition.baseAssetAmount.abs(), 'Maintenance')))
560
656
  .div(numericConstants_1.MARGIN_PRECISION));
561
657
  const freeCollateralAfterTrade = totalCollateral.sub(marginRequirementAfterTrade);
562
- const marketMaxLeverage = this.getMaxLeverage(proposedMarketPosition.marketIndex, 'Maintenance');
658
+ const marketMaxLeverage = this.getMaxLeverage(proposedPerpPosition.marketIndex, 'Maintenance');
563
659
  let priceDelta;
564
660
  if (proposedBaseAssetAmount.lt(numericConstants_1.ZERO)) {
565
661
  priceDelta = freeCollateralAfterTrade
@@ -579,13 +675,13 @@ class ClearingHouseUser {
579
675
  }
580
676
  let markPriceAfterTrade;
581
677
  if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
582
- markPriceAfterTrade = (0, _1.calculateMarkPrice)(this.clearingHouse.getMarketAccount(marketPosition.marketIndex), this.getOracleDataForMarket(marketPosition.marketIndex));
678
+ markPriceAfterTrade = (0, _1.calculateMarkPrice)(this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex), this.getOracleDataForMarket(perpPosition.marketIndex));
583
679
  }
584
680
  else {
585
681
  const direction = positionBaseSizeChange.gt(numericConstants_1.ZERO)
586
682
  ? _1.PositionDirection.LONG
587
683
  : _1.PositionDirection.SHORT;
588
- markPriceAfterTrade = (0, _1.calculateTradeSlippage)(direction, positionBaseSizeChange.abs(), this.clearingHouse.getMarketAccount(marketPosition.marketIndex), 'base', this.getOracleDataForMarket(marketPosition.marketIndex))[3]; // newPrice after swap
684
+ markPriceAfterTrade = (0, _1.calculateTradeSlippage)(direction, positionBaseSizeChange.abs(), this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex), 'base', this.getOracleDataForMarket(perpPosition.marketIndex))[3]; // newPrice after swap
589
685
  }
590
686
  if (priceDelta.gt(markPriceAfterTrade)) {
591
687
  return new _1.BN(-1);
@@ -647,7 +743,7 @@ class ClearingHouseUser {
647
743
  // add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
648
744
  const oppositeSizeValueUSDC = targetingSameSide
649
745
  ? numericConstants_1.ZERO
650
- : this.getPositionValue(targetMarketIndex, oracleData);
746
+ : this.getPerpPositionValue(targetMarketIndex, oracleData);
651
747
  let maxPositionSize = this.getBuyingPower(targetMarketIndex);
652
748
  if (maxPositionSize.gte(numericConstants_1.ZERO)) {
653
749
  if (oppositeSizeValueUSDC.eq(numericConstants_1.ZERO)) {
@@ -662,23 +758,23 @@ class ClearingHouseUser {
662
758
  else {
663
759
  // current leverage is greater than max leverage - can only reduce position size
664
760
  if (!targetingSameSide) {
665
- const market = this.clearingHouse.getMarketAccount(targetMarketIndex);
666
- const marketPositionValue = this.getPositionValue(targetMarketIndex, oracleData);
761
+ const market = this.clearingHouse.getPerpMarketAccount(targetMarketIndex);
762
+ const perpPositionValue = this.getPerpPositionValue(targetMarketIndex, oracleData);
667
763
  const totalCollateral = this.getTotalCollateral();
668
764
  const marginRequirement = this.getInitialMarginRequirement();
669
- const marginFreedByClosing = marketPositionValue
765
+ const marginFreedByClosing = perpPositionValue
670
766
  .mul(new _1.BN(market.marginRatioInitial))
671
767
  .div(numericConstants_1.MARGIN_PRECISION);
672
768
  const marginRequirementAfterClosing = marginRequirement.sub(marginFreedByClosing);
673
769
  if (marginRequirementAfterClosing.gt(totalCollateral)) {
674
- maxPositionSize = marketPositionValue;
770
+ maxPositionSize = perpPositionValue;
675
771
  }
676
772
  else {
677
773
  const freeCollateralAfterClose = totalCollateral.sub(marginRequirementAfterClosing);
678
774
  const buyingPowerAfterClose = freeCollateralAfterClose
679
775
  .mul(this.getMaxLeverage(targetMarketIndex))
680
776
  .div(numericConstants_1.TEN_THOUSAND);
681
- maxPositionSize = marketPositionValue.add(buyingPowerAfterClose);
777
+ maxPositionSize = perpPositionValue.add(buyingPowerAfterClose);
682
778
  }
683
779
  }
684
780
  else {
@@ -702,7 +798,7 @@ class ClearingHouseUser {
702
798
  const currentPosition = this.getUserPosition(targetMarketIndex) ||
703
799
  this.getEmptyPosition(targetMarketIndex);
704
800
  const oracleData = this.getOracleDataForMarket(targetMarketIndex);
705
- let currentPositionQuoteAmount = this.getPositionValue(targetMarketIndex, oracleData);
801
+ let currentPositionQuoteAmount = this.getPerpPositionValue(targetMarketIndex, oracleData);
706
802
  const currentSide = currentPosition && currentPosition.baseAssetAmount.isNeg()
707
803
  ? _1.PositionDirection.SHORT
708
804
  : _1.PositionDirection.LONG;
@@ -710,13 +806,13 @@ class ClearingHouseUser {
710
806
  currentPositionQuoteAmount = currentPositionQuoteAmount.neg();
711
807
  if (tradeSide === _1.PositionDirection.SHORT)
712
808
  tradeQuoteAmount = tradeQuoteAmount.neg();
713
- const currentMarketPositionAfterTrade = currentPositionQuoteAmount
809
+ const currentPerpPositionAfterTrade = currentPositionQuoteAmount
714
810
  .add(tradeQuoteAmount)
715
811
  .abs();
716
- const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPositionValueExcludingMarket(targetMarketIndex);
812
+ const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPerpPositionValueExcludingMarket(targetMarketIndex);
717
813
  const totalCollateral = this.getTotalCollateral();
718
814
  if (totalCollateral.gt(numericConstants_1.ZERO)) {
719
- const newLeverage = currentMarketPositionAfterTrade
815
+ const newLeverage = currentPerpPositionAfterTrade
720
816
  .add(totalPositionAfterTradeExcludingTargetMarket)
721
817
  .abs()
722
818
  .mul(numericConstants_1.TEN_THOUSAND)
@@ -733,7 +829,7 @@ class ClearingHouseUser {
733
829
  * @returns feeForQuote : Precision QUOTE_PRECISION
734
830
  */
735
831
  calculateFeeForQuoteAmount(quoteAmount) {
736
- const feeStructure = this.clearingHouse.getStateAccount().feeStructure;
832
+ const feeStructure = this.clearingHouse.getStateAccount().perpFeeStructure;
737
833
  return quoteAmount
738
834
  .mul(feeStructure.feeNumerator)
739
835
  .div(feeStructure.feeDenominator);
@@ -743,23 +839,23 @@ class ClearingHouseUser {
743
839
  * @param marketToIgnore
744
840
  * @returns positionValue : Precision QUOTE_PRECISION
745
841
  */
746
- getTotalPositionValueExcludingMarket(marketToIgnore) {
747
- const currentMarketPosition = this.getUserPosition(marketToIgnore) ||
842
+ getTotalPerpPositionValueExcludingMarket(marketToIgnore) {
843
+ const currentPerpPosition = this.getUserPosition(marketToIgnore) ||
748
844
  this.getEmptyPosition(marketToIgnore);
749
845
  const oracleData = this.getOracleDataForMarket(marketToIgnore);
750
- let currentMarketPositionValueUSDC = numericConstants_1.ZERO;
751
- if (currentMarketPosition) {
752
- currentMarketPositionValueUSDC = this.getPositionValue(marketToIgnore, oracleData);
846
+ let currentPerpPositionValueUSDC = numericConstants_1.ZERO;
847
+ if (currentPerpPosition) {
848
+ currentPerpPositionValueUSDC = this.getPerpPositionValue(marketToIgnore, oracleData);
753
849
  }
754
- return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
850
+ return this.getTotalPerpPositionValue().sub(currentPerpPositionValueUSDC);
755
851
  }
756
852
  getOracleDataForMarket(marketIndex) {
757
- const oracleKey = this.clearingHouse.getMarketAccount(marketIndex).amm.oracle;
853
+ const oracleKey = this.clearingHouse.getPerpMarketAccount(marketIndex).amm.oracle;
758
854
  const oracleData = this.clearingHouse.getOraclePriceDataAndSlot(oracleKey).data;
759
855
  return oracleData;
760
856
  }
761
- getOracleDataForBank(bankIndex) {
762
- const oracleKey = this.clearingHouse.getBankAccount(bankIndex).oracle;
857
+ getOracleDataForSpotMarket(marketIndex) {
858
+ const oracleKey = this.clearingHouse.getSpotMarketAccount(marketIndex).oracle;
763
859
  const oracleData = this.clearingHouse.getOraclePriceDataAndSlot(oracleKey).data;
764
860
  return oracleData;
765
861
  }