@drift-labs/sdk 0.1.12 → 0.1.13

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 (56) hide show
  1. package/lib/accounts/types.d.ts +0 -21
  2. package/lib/accounts/types.d.ts.map +1 -1
  3. package/lib/clearingHouseUser.d.ts +27 -3
  4. package/lib/clearingHouseUser.d.ts.map +1 -1
  5. package/lib/clearingHouseUser.js +195 -47
  6. package/lib/constants/markets.d.ts.map +1 -1
  7. package/lib/constants/markets.js +7 -0
  8. package/lib/constants/numericConstants.d.ts +1 -0
  9. package/lib/constants/numericConstants.d.ts.map +1 -1
  10. package/lib/constants/numericConstants.js +2 -1
  11. package/lib/examples/makeTradeExample.d.ts.map +1 -1
  12. package/lib/examples/makeTradeExample.js +14 -13
  13. package/lib/idl/clearing_house.json +94 -42
  14. package/lib/index.d.ts +2 -1
  15. package/lib/index.d.ts.map +1 -1
  16. package/lib/index.js +2 -1
  17. package/lib/math/amm.d.ts +26 -1
  18. package/lib/math/amm.d.ts.map +1 -1
  19. package/lib/math/amm.js +84 -10
  20. package/lib/math/funding.d.ts +6 -6
  21. package/lib/math/funding.d.ts.map +1 -1
  22. package/lib/math/funding.js +41 -22
  23. package/lib/math/insuranceFund.d.ts +14 -0
  24. package/lib/math/insuranceFund.d.ts.map +1 -0
  25. package/lib/math/insuranceFund.js +35 -0
  26. package/lib/math/position.d.ts +1 -1
  27. package/lib/math/position.d.ts.map +1 -1
  28. package/lib/math/position.js +15 -23
  29. package/lib/math/trade.d.ts +1 -1
  30. package/lib/math/trade.d.ts.map +1 -1
  31. package/lib/math/trade.js +9 -4
  32. package/lib/types.d.ts +0 -13
  33. package/lib/types.d.ts.map +1 -1
  34. package/lib/wallet.d.ts +10 -0
  35. package/lib/wallet.d.ts.map +1 -0
  36. package/lib/wallet.js +35 -0
  37. package/package.json +2 -2
  38. package/src/accounts/types.ts +0 -27
  39. package/src/clearingHouse.ts +2 -2
  40. package/src/clearingHouseUser.ts +282 -65
  41. package/src/constants/markets.ts +7 -0
  42. package/src/constants/numericConstants.ts +3 -0
  43. package/src/examples/makeTradeExample.ts +2 -1
  44. package/src/idl/clearing_house.json +94 -42
  45. package/src/index.ts +2 -1
  46. package/src/math/amm.ts +119 -12
  47. package/src/math/funding.ts +47 -25
  48. package/src/math/insuranceFund.ts +22 -0
  49. package/src/math/position.ts +15 -28
  50. package/src/math/trade.ts +9 -5
  51. package/src/types.ts +0 -14
  52. package/src/wallet.ts +22 -0
  53. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -29
  54. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts.map +0 -1
  55. package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
  56. package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -179
@@ -4,6 +4,7 @@ import { EventEmitter } from 'events';
4
4
  import StrictEventEmitter from 'strict-event-emitter-types';
5
5
  import { ClearingHouse } from './clearingHouse';
6
6
  import { UserAccount, UserPosition, UserPositionsAccount } from './types';
7
+ import { calculateEntryPrice } from './math/position';
7
8
  import {
8
9
  MARK_PRICE_PRECISION,
9
10
  AMM_TO_QUOTE_PRECISION_RATIO,
@@ -13,6 +14,8 @@ import {
13
14
  PARTIAL_LIQUIDATION_RATIO,
14
15
  FULL_LIQUIDATION_RATIO,
15
16
  QUOTE_PRECISION,
17
+ AMM_RESERVE_PRECISION,
18
+ PRICE_TO_QUOTE_PRECISION,
16
19
  } from './constants/numericConstants';
17
20
  import { UserAccountSubscriber, UserAccountEvents } from './accounts/types';
18
21
  import { DefaultUserAccountSubscriber } from './accounts/defaultUserAccountSubscriber';
@@ -81,23 +84,25 @@ export class ClearingHouseUser {
81
84
  }
82
85
 
83
86
  /**
84
- * Gets the user's current position for a given market
87
+ * Gets the user's current position for a given market. If the user has no position returns undefined
85
88
  * @param marketIndex
86
89
  * @returns userPosition
87
90
  */
88
- public getUserPosition(marketIndex: BN): UserPosition {
89
- return (
90
- this.getUserPositionsAccount().positions.find((position) =>
91
- position.marketIndex.eq(marketIndex)
92
- ) ?? {
93
- baseAssetAmount: ZERO,
94
- lastCumulativeFundingRate: ZERO,
95
- marketIndex,
96
- quoteAssetAmount: ZERO,
97
- }
91
+ public getUserPosition(marketIndex: BN): UserPosition | undefined {
92
+ return this.getUserPositionsAccount().positions.find((position) =>
93
+ position.marketIndex.eq(marketIndex)
98
94
  );
99
95
  }
100
96
 
97
+ public getEmptyPosition(marketIndex: BN): UserPosition {
98
+ return {
99
+ baseAssetAmount: ZERO,
100
+ lastCumulativeFundingRate: ZERO,
101
+ marketIndex,
102
+ quoteAssetAmount: ZERO,
103
+ };
104
+ }
105
+
101
106
  public async getUserAccountPublicKey(): Promise<PublicKey> {
102
107
  if (this.userAccountPublicKey) {
103
108
  return this.userAccountPublicKey;
@@ -205,7 +210,8 @@ export class ClearingHouseUser {
205
210
  * @returns : Precision QUOTE_PRECISION
206
211
  */
207
212
  public getPositionValue(marketIndex: BN): BN {
208
- const userPosition = this.getUserPosition(marketIndex);
213
+ const userPosition =
214
+ this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
209
215
  const market = this.clearingHouse.getMarket(userPosition.marketIndex);
210
216
  return calculateBaseAssetValue(market, userPosition);
211
217
  }
@@ -226,15 +232,17 @@ export class ClearingHouseUser {
226
232
  * calculates average exit price for closing 100% of position
227
233
  * @returns : Precision MARK_PRICE_PRECISION
228
234
  */
229
- public getPositionEstimatedExitPrice(
235
+ public getPositionEstimatedExitPriceAndPnl(
230
236
  position: UserPosition,
231
237
  amountToClose?: BN
232
- ): BN {
238
+ ): [BN, BN] {
233
239
  const market = this.clearingHouse.getMarket(position.marketIndex);
234
240
 
241
+ const entryPrice = calculateEntryPrice(position);
242
+
235
243
  if (amountToClose) {
236
244
  if (amountToClose.eq(ZERO)) {
237
- return calculateMarkPrice(market);
245
+ return [calculateMarkPrice(market), ZERO];
238
246
  }
239
247
  position = {
240
248
  baseAssetAmount: amountToClose,
@@ -246,12 +254,21 @@ export class ClearingHouseUser {
246
254
 
247
255
  const baseAssetValue = calculateBaseAssetValue(market, position);
248
256
  if (position.baseAssetAmount.eq(ZERO)) {
249
- return ZERO;
257
+ return [ZERO, ZERO];
250
258
  }
251
- return baseAssetValue
259
+
260
+ const exitPrice = baseAssetValue
252
261
  .mul(AMM_TO_QUOTE_PRECISION_RATIO)
253
262
  .mul(MARK_PRICE_PRECISION)
254
263
  .div(position.baseAssetAmount.abs());
264
+
265
+ const pnlPerBase = exitPrice.sub(entryPrice);
266
+ const pnl = pnlPerBase
267
+ .mul(position.baseAssetAmount)
268
+ .div(MARK_PRICE_PRECISION)
269
+ .div(AMM_TO_QUOTE_PRECISION_RATIO);
270
+
271
+ return [exitPrice, pnl];
255
272
  }
256
273
 
257
274
  /**
@@ -350,7 +367,7 @@ export class ClearingHouseUser {
350
367
  * @param partial
351
368
  * @returns Precision : MARK_PRICE_PRECISION
352
369
  */
353
- public liquidationPrice(
370
+ public liquidationPriceOld(
354
371
  targetMarket: Pick<UserPosition, 'marketIndex'>,
355
372
  positionBaseSizeChange: BN = ZERO,
356
373
  partial = false
@@ -379,13 +396,11 @@ export class ClearingHouseUser {
379
396
  const totalCurrentPositionValueIgnoringTargetUSDC =
380
397
  this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
381
398
 
382
- const currentMarketPosition = this.getUserPosition(
383
- targetMarket.marketIndex
384
- );
399
+ const currentMarketPosition =
400
+ this.getUserPosition(targetMarket.marketIndex) ||
401
+ this.getEmptyPosition(targetMarket.marketIndex);
385
402
 
386
- const currentMarketPositionBaseSize = currentMarketPosition
387
- ? currentMarketPosition.baseAssetAmount
388
- : ZERO;
403
+ const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
389
404
 
390
405
  // calculate position for current market after trade
391
406
  const proposedMarketPosition: UserPosition = {
@@ -412,9 +427,23 @@ export class ClearingHouseUser {
412
427
  proposedMarketPositionValueUSDC
413
428
  );
414
429
 
430
+ let totalFreeCollateralUSDC = this.getTotalCollateral().sub(
431
+ this.getTotalPositionValue()
432
+ .mul(TEN_THOUSAND)
433
+ .div(this.getMaxLeverage('Maintenance'))
434
+ );
435
+
436
+ if (partial) {
437
+ totalFreeCollateralUSDC = this.getTotalCollateral().sub(
438
+ this.getTotalPositionValue()
439
+ .mul(TEN_THOUSAND)
440
+ .div(this.getMaxLeverage('Partial'))
441
+ );
442
+ }
443
+
415
444
  // if the position value after the trade is less than total collateral, there is no liq price
416
445
  if (
417
- targetTotalPositionValueUSDC.lte(totalCollateralUSDC) &&
446
+ targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
418
447
  proposedMarketPosition.baseAssetAmount.gt(ZERO)
419
448
  ) {
420
449
  return new BN(-1);
@@ -456,6 +485,127 @@ export class ClearingHouseUser {
456
485
  return liqPrice;
457
486
  }
458
487
 
488
+ /**
489
+ * Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
490
+ * @param targetMarket
491
+ * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
492
+ * @param partial
493
+ * @returns Precision : MARK_PRICE_PRECISION
494
+ */
495
+ public liquidationPrice(
496
+ targetMarket: Pick<UserPosition, 'marketIndex'>,
497
+ positionBaseSizeChange: BN = ZERO,
498
+ partial = false
499
+ ): BN {
500
+ // solves formula for example calc below
501
+
502
+ /* example: assume BTC price is $40k (examine 10% up/down)
503
+
504
+ if 10k deposit and levered 10x short BTC => BTC up $400 means:
505
+ 1. higher base_asset_value (+$4k)
506
+ 2. lower collateral (-$4k)
507
+ 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
508
+
509
+ for 10x long, BTC down $400:
510
+ 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
511
+
512
+ const tc = this.getTotalCollateral();
513
+ const tpv = this.getTotalPositionValue();
514
+
515
+ const partialLev = 16;
516
+ const maintLev = 20;
517
+
518
+ const thisLev = partial ? new BN(partialLev) : new BN(maintLev);
519
+
520
+ // calculate the total position value ignoring any value from the target market of the trade
521
+ const totalCurrentPositionValueIgnoringTargetUSDC =
522
+ this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
523
+
524
+ const currentMarketPosition =
525
+ this.getUserPosition(targetMarket.marketIndex) ||
526
+ this.getEmptyPosition(targetMarket.marketIndex);
527
+
528
+ const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
529
+
530
+ const proposedBaseAssetAmount = currentMarketPositionBaseSize.add(
531
+ positionBaseSizeChange
532
+ );
533
+
534
+ // calculate position for current market after trade
535
+ const proposedMarketPosition: UserPosition = {
536
+ marketIndex: targetMarket.marketIndex,
537
+ baseAssetAmount: proposedBaseAssetAmount,
538
+ lastCumulativeFundingRate:
539
+ currentMarketPosition.lastCumulativeFundingRate,
540
+ quoteAssetAmount: new BN(0),
541
+ };
542
+
543
+ const market = this.clearingHouse.getMarket(
544
+ proposedMarketPosition.marketIndex
545
+ );
546
+
547
+ const proposedMarketPositionValueUSDC = calculateBaseAssetValue(
548
+ market,
549
+ proposedMarketPosition
550
+ );
551
+
552
+ // total position value after trade
553
+ const targetTotalPositionValueUSDC =
554
+ totalCurrentPositionValueIgnoringTargetUSDC.add(
555
+ proposedMarketPositionValueUSDC
556
+ );
557
+
558
+ let totalFreeCollateralUSDC = tc.sub(
559
+ totalCurrentPositionValueIgnoringTargetUSDC
560
+ .mul(TEN_THOUSAND)
561
+ .div(this.getMaxLeverage('Maintenance'))
562
+ );
563
+
564
+ if (partial) {
565
+ totalFreeCollateralUSDC = tc.sub(
566
+ totalCurrentPositionValueIgnoringTargetUSDC
567
+ .mul(TEN_THOUSAND)
568
+ .div(this.getMaxLeverage('Partial'))
569
+ );
570
+ }
571
+
572
+ let priceDelt;
573
+ if (currentMarketPositionBaseSize.lt(ZERO)) {
574
+ priceDelt = tc
575
+ .mul(thisLev)
576
+ .sub(tpv)
577
+ .mul(PRICE_TO_QUOTE_PRECISION)
578
+ .div(thisLev.add(new BN(1)));
579
+ } else {
580
+ priceDelt = tc
581
+ .mul(thisLev)
582
+ .sub(tpv)
583
+ .mul(PRICE_TO_QUOTE_PRECISION)
584
+ .div(thisLev.sub(new BN(1)));
585
+ }
586
+
587
+ const currentPrice = calculateMarkPrice(
588
+ this.clearingHouse.getMarket(targetMarket.marketIndex)
589
+ );
590
+
591
+ // if the position value after the trade is less than total collateral, there is no liq price
592
+ if (
593
+ targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
594
+ proposedMarketPosition.baseAssetAmount.gt(ZERO)
595
+ ) {
596
+ return new BN(-1);
597
+ }
598
+
599
+ if (proposedBaseAssetAmount.eq(ZERO)) return new BN(-1);
600
+
601
+ const eatMargin2 = priceDelt
602
+ .mul(AMM_RESERVE_PRECISION)
603
+ .div(proposedBaseAssetAmount);
604
+
605
+ const liqPrice = currentPrice.sub(eatMargin2);
606
+ return liqPrice;
607
+ }
608
+
459
609
  /**
460
610
  * Calculates the estimated liquidation price for a position after closing a quote amount of the position.
461
611
  * @param positionMarketIndex
@@ -466,7 +616,9 @@ export class ClearingHouseUser {
466
616
  positionMarketIndex: BN,
467
617
  closeQuoteAmount: BN
468
618
  ): BN {
469
- const currentPosition = this.getUserPosition(positionMarketIndex);
619
+ const currentPosition =
620
+ this.getUserPosition(positionMarketIndex) ||
621
+ this.getEmptyPosition(positionMarketIndex);
470
622
 
471
623
  const closeBaseAmount = currentPosition.baseAssetAmount
472
624
  .mul(closeQuoteAmount)
@@ -488,6 +640,21 @@ export class ClearingHouseUser {
488
640
 
489
641
  /**
490
642
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
643
+ *
644
+ * To Calculate Max Quote Available:
645
+ *
646
+ * Case 1: SameSide
647
+ * => Remaining quote to get to maxLeverage
648
+ *
649
+ * Case 2: NOT SameSide && currentLeverage <= maxLeverage
650
+ * => Current opposite position x2 + remaining to get to maxLeverage
651
+ *
652
+ * Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
653
+ * => strictly reduce current position size
654
+ *
655
+ * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
656
+ * => current position + remaining to get to maxLeverage
657
+ *
491
658
  * @param marketIndex
492
659
  * @param tradeSide
493
660
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
@@ -498,32 +665,28 @@ export class ClearingHouseUser {
498
665
  tradeSide: PositionDirection,
499
666
  userMaxLeverageSetting: BN
500
667
  ): BN {
501
- // inline function which get's the current position size on the opposite side of the target trade
502
- const getOppositePositionValueUSDC = () => {
503
- if (!currentPosition) return ZERO;
668
+ const currentPosition =
669
+ this.getUserPosition(targetMarketIndex) ||
670
+ this.getEmptyPosition(targetMarketIndex);
504
671
 
505
- const side = tradeSide === PositionDirection.SHORT ? 'short' : 'long';
672
+ const targetSide = tradeSide === PositionDirection.SHORT ? 'short' : 'long';
506
673
 
507
- if (side === 'long' && currentPosition?.baseAssetAmount.isNeg()) {
508
- return this.getPositionValue(targetMarketIndex);
509
- } else if (
510
- side === 'short' &&
511
- !currentPosition?.baseAssetAmount.isNeg()
512
- ) {
513
- return this.getPositionValue(targetMarketIndex);
514
- }
674
+ const currentPositionSide = currentPosition?.baseAssetAmount.isNeg()
675
+ ? 'short'
676
+ : 'long';
515
677
 
516
- return ZERO;
517
- };
678
+ const targettingSameSide = !currentPosition
679
+ ? true
680
+ : targetSide === currentPositionSide;
518
681
 
519
- const currentPosition = this.getUserPosition(targetMarketIndex);
682
+ // 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.
683
+ const oppositeSizeValueUSDC = targettingSameSide
684
+ ? ZERO
685
+ : this.getPositionValue(targetMarketIndex);
520
686
 
521
687
  // get current leverage
522
688
  const currentLeverage = this.getLeverage();
523
689
 
524
- // remaining leverage
525
- // let remainingLeverage = userMaxLeverageSetting;
526
-
527
690
  const remainingLeverage = BN.max(
528
691
  userMaxLeverageSetting.sub(currentLeverage),
529
692
  ZERO
@@ -537,10 +700,57 @@ export class ClearingHouseUser {
537
700
  .mul(totalCollateral)
538
701
  .div(TEN_THOUSAND);
539
702
 
540
- // 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.
541
- const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
703
+ if (userMaxLeverageSetting.sub(currentLeverage).gte(ZERO)) {
704
+ if (oppositeSizeValueUSDC.eq(ZERO)) {
705
+ // case 1 : Regular trade where current total position less than max, and no opposite position to account for
706
+ // do nothing
707
+ } else {
708
+ // case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
709
+ maxPositionSize = maxPositionSize.add(
710
+ oppositeSizeValueUSDC.mul(new BN(2))
711
+ );
712
+ }
713
+ } else {
714
+ // current leverage is greater than max leverage - can only reduce position size
542
715
 
543
- maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC);
716
+ if (!targettingSameSide) {
717
+ const currentPositionQuoteSize =
718
+ this.getPositionValue(targetMarketIndex);
719
+
720
+ const currentTotalQuoteSize = currentLeverage
721
+ .mul(totalCollateral)
722
+ .div(TEN_THOUSAND);
723
+
724
+ const otherPositionsTotalQuoteSize = currentTotalQuoteSize.sub(
725
+ currentPositionQuoteSize
726
+ );
727
+
728
+ const quoteValueOfMaxLeverage = userMaxLeverageSetting
729
+ .mul(totalCollateral)
730
+ .div(TEN_THOUSAND);
731
+
732
+ if (
733
+ otherPositionsTotalQuoteSize
734
+ .sub(currentPositionQuoteSize)
735
+ .gte(quoteValueOfMaxLeverage)
736
+ ) {
737
+ // case 3: Can only reduce the current position because it will still be greater than max leverage
738
+
739
+ maxPositionSize = currentPositionQuoteSize;
740
+ } else {
741
+ // case 4: Can reduce the position, and then take extra remaining quote to get to max leverage
742
+
743
+ const allowedQuoteSizeAfterClosingCurrentPosition =
744
+ quoteValueOfMaxLeverage.sub(otherPositionsTotalQuoteSize);
745
+
746
+ maxPositionSize = currentPositionQuoteSize.add(
747
+ allowedQuoteSizeAfterClosingCurrentPosition
748
+ );
749
+ }
750
+ } else {
751
+ // do nothing if targetting same side
752
+ }
753
+ }
544
754
 
545
755
  // subtract oneMillionth of maxPositionSize
546
756
  // => to avoid rounding errors when taking max leverage
@@ -562,12 +772,16 @@ export class ClearingHouseUser {
562
772
  tradeQuoteAmount: BN,
563
773
  tradeSide: PositionDirection
564
774
  ): BN {
565
- const currentPosition = this.getUserPosition(targetMarketIndex);
566
- let currentPositionQuoteAmount = currentPosition.quoteAssetAmount;
775
+ const currentPosition =
776
+ this.getUserPosition(targetMarketIndex) ||
777
+ this.getEmptyPosition(targetMarketIndex);
778
+
779
+ let currentPositionQuoteAmount = this.getPositionValue(targetMarketIndex);
567
780
 
568
- const currentSide = currentPosition.baseAssetAmount.isNeg()
569
- ? PositionDirection.SHORT
570
- : PositionDirection.LONG;
781
+ const currentSide =
782
+ currentPosition && currentPosition.baseAssetAmount.isNeg()
783
+ ? PositionDirection.SHORT
784
+ : PositionDirection.LONG;
571
785
 
572
786
  if (currentSide === PositionDirection.SHORT)
573
787
  currentPositionQuoteAmount = currentPositionQuoteAmount.neg();
@@ -582,11 +796,18 @@ export class ClearingHouseUser {
582
796
  const totalPositionAfterTradeExcludingTargetMarket =
583
797
  this.getTotalPositionValueExcludingMarket(targetMarketIndex);
584
798
 
585
- return currentMarketPositionAfterTrade
586
- .add(totalPositionAfterTradeExcludingTargetMarket)
587
- .abs()
588
- .mul(TEN_THOUSAND)
589
- .div(this.getTotalCollateral());
799
+ const totalCollateral = this.getTotalCollateral();
800
+
801
+ if (totalCollateral.gt(ZERO)) {
802
+ const newLeverage = currentMarketPositionAfterTrade
803
+ .add(totalPositionAfterTradeExcludingTargetMarket)
804
+ .abs()
805
+ .mul(TEN_THOUSAND)
806
+ .div(totalCollateral);
807
+ return newLeverage;
808
+ } else {
809
+ return new BN(0);
810
+ }
590
811
  }
591
812
 
592
813
  /**
@@ -608,17 +829,13 @@ export class ClearingHouseUser {
608
829
  * @returns positionValue : Precision QUOTE_PRECISION
609
830
  */
610
831
  private getTotalPositionValueExcludingMarket(marketToIgnore: BN): BN {
611
- const currentMarketPosition = this.getUserPosition(marketToIgnore);
832
+ const currentMarketPosition =
833
+ this.getUserPosition(marketToIgnore) ||
834
+ this.getEmptyPosition(marketToIgnore);
612
835
 
613
836
  let currentMarketPositionValueUSDC = ZERO;
614
837
  if (currentMarketPosition) {
615
- const market = this.clearingHouse.getMarket(
616
- currentMarketPosition.marketIndex
617
- );
618
- currentMarketPositionValueUSDC = calculateBaseAssetValue(
619
- market,
620
- currentMarketPosition
621
- );
838
+ currentMarketPositionValueUSDC = this.getPositionValue(marketToIgnore);
622
839
  }
623
840
 
624
841
  return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
@@ -51,4 +51,11 @@ export const Markets: Market[] = [
51
51
  devnetPythOracle: 'GwzBgrXb4PG59zjce24SF2b9JXbLEjJJTBkmytuEZj1b',
52
52
  mainnetPythOracle: '4CkQJBxhU8EZ2UjhigbtdaPbpTe6mqf811fipYBFbSYN',
53
53
  },
54
+ {
55
+ symbol: 'MATIC-PERP',
56
+ baseAssetSymbol: 'MATIC',
57
+ marketIndex: new BN(6),
58
+ devnetPythOracle: 'FBirwuDFuRAu4iSGc7RGxN5koHB7EJM1wbCmyPuQoGur',
59
+ mainnetPythOracle: '7KVswB9vkCgeM3SHP7aGDijvdRAHK8P5wi9JXViCrtYh',
60
+ },
54
61
  ];
@@ -19,3 +19,6 @@ export const AMM_TO_QUOTE_PRECISION_RATIO =
19
19
  AMM_RESERVE_PRECISION.div(QUOTE_PRECISION); // 10^7
20
20
  export const PRICE_TO_QUOTE_PRECISION =
21
21
  MARK_PRICE_PRECISION.div(QUOTE_PRECISION);
22
+ export const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO =
23
+ AMM_RESERVE_PRECISION.mul(PEG_PRECISION).div(QUOTE_PRECISION); // 10^10
24
+
@@ -1,4 +1,5 @@
1
- import { BN, Provider, Wallet } from '@project-serum/anchor';
1
+ import { BN, Provider } from '@project-serum/anchor';
2
+ import {Wallet} from "..";
2
3
  import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
3
4
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
4
5
  import {