@drift-labs/sdk 0.1.9 → 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 +29 -5
  4. package/lib/clearingHouseUser.d.ts.map +1 -1
  5. package/lib/clearingHouseUser.js +206 -78
  6. package/lib/constants/markets.d.ts.map +1 -1
  7. package/lib/constants/markets.js +21 -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 +69 -25
  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 +7 -1
  27. package/lib/math/position.d.ts.map +1 -1
  28. package/lib/math/position.js +32 -24
  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 -50
  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 +301 -107
  41. package/src/constants/markets.ts +21 -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 +109 -51
  48. package/src/math/insuranceFund.ts +22 -0
  49. package/src/math/position.ts +32 -26
  50. package/src/math/trade.ts +9 -5
  51. package/src/types.ts +0 -54
  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
@@ -37,27 +37,6 @@ export interface ClearingHouseAccountSubscriber {
37
37
  getCurveHistoryAccount(): CurveHistoryAccount;
38
38
  getLiquidationHistoryAccount(): LiquidationHistoryAccount;
39
39
  }
40
- export interface HistoryAccountEvents {
41
- fundingPaymentHistoryAccountUpdate: (payload: FundingPaymentHistoryAccount) => void;
42
- fundingRateHistoryAccountUpdate: (payload: FundingRateHistoryAccount) => void;
43
- tradeHistoryAccountUpdate: (payload: TradeHistoryAccount) => void;
44
- liquidationHistoryAccountUpdate: (payload: LiquidationHistoryAccount) => void;
45
- depositHistoryAccountUpdate: (payload: DepositHistoryAccount) => void;
46
- curveHistoryAccountUpdate: (payload: CurveHistoryAccount) => void;
47
- update: void;
48
- }
49
- export interface HistoryAccountSubscriber {
50
- eventEmitter: StrictEventEmitter<EventEmitter, HistoryAccountEvents>;
51
- isSubscribed: boolean;
52
- subscribe(): Promise<boolean>;
53
- unsubscribe(): Promise<void>;
54
- getTradeHistoryAccount(): TradeHistoryAccount;
55
- getDepositHistoryAccount(): DepositHistoryAccount;
56
- getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
57
- getFundingRateHistoryAccount(): FundingRateHistoryAccount;
58
- getCurveHistoryAccount(): CurveHistoryAccount;
59
- getLiquidationHistoryAccount(): LiquidationHistoryAccount;
60
- }
61
40
  export interface UserAccountEvents {
62
41
  userAccountData: (payload: UserAccount) => void;
63
42
  userPositionsData: (payload: UserPositionsAccount) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/accounts/types.ts"],"names":[],"mappings":";AAAA,OAAO,EACN,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,MAAM,UAAU,CAAC;AAClB,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,iBAAiB,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,WAAW,IAAI,IAAI,CAAC;CACpB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,IAAI,SAAwB;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,kBAAkB,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,oBAAoB,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IACxD,kCAAkC,EAAE,CACnC,OAAO,EAAE,4BAA4B,KACjC,IAAI,CAAC;IACV,+BAA+B,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9E,yBAAyB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClE,+BAA+B,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9E,2BAA2B,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACtE,yBAAyB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClE,MAAM,EAAE,IAAI,CAAC;CACb;AAED,oBAAY,yBAAyB,GAClC,qBAAqB,GACrB,uBAAuB,GACvB,8BAA8B,GAC9B,2BAA2B,GAC3B,qBAAqB,GACrB,2BAA2B,CAAC;AAE/B,MAAM,WAAW,8BAA8B;IAC9C,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,0BAA0B,CAAC,CAAC;IAC3E,YAAY,EAAE,OAAO,CAAC;IAEtB,0BAA0B,EAAE,yBAAyB,EAAE,CAAC;IAExD,SAAS,CACR,qBAAqB,CAAC,EAAE,yBAAyB,EAAE,GACjD,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,eAAe,IAAI,YAAY,CAAC;IAChC,iBAAiB,IAAI,cAAc,CAAC;IACpC,sBAAsB,IAAI,mBAAmB,CAAC;IAC9C,wBAAwB,IAAI,qBAAqB,CAAC;IAClD,+BAA+B,IAAI,4BAA4B,CAAC;IAChE,4BAA4B,IAAI,yBAAyB,CAAC;IAC1D,sBAAsB,IAAI,mBAAmB,CAAC;IAC9C,4BAA4B,IAAI,yBAAyB,CAAC;CAC1D;AAED,MAAM,WAAW,oBAAoB;IACpC,kCAAkC,EAAE,CACnC,OAAO,EAAE,4BAA4B,KACjC,IAAI,CAAC;IACV,+BAA+B,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9E,yBAAyB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClE,+BAA+B,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9E,2BAA2B,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACtE,yBAAyB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClE,MAAM,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,wBAAwB;IACxC,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;IACrE,YAAY,EAAE,OAAO,CAAC;IAEtB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,sBAAsB,IAAI,mBAAmB,CAAC;IAC9C,wBAAwB,IAAI,qBAAqB,CAAC;IAClD,+BAA+B,IAAI,4BAA4B,CAAC;IAChE,4BAA4B,IAAI,yBAAyB,CAAC;IAC1D,sBAAsB,IAAI,mBAAmB,CAAC;IAC9C,4BAA4B,IAAI,yBAAyB,CAAC;CAC1D;AAED,MAAM,WAAW,iBAAiB;IACjC,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC3D,MAAM,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACrC,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IAClE,YAAY,EAAE,OAAO,CAAC;IAEtB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,cAAc,IAAI,WAAW,CAAC;IAC9B,uBAAuB,IAAI,oBAAoB,CAAC;CAChD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/accounts/types.ts"],"names":[],"mappings":";AAAA,OAAO,EACN,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,MAAM,UAAU,CAAC;AAClB,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,iBAAiB,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,WAAW,IAAI,IAAI,CAAC;CACpB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,IAAI,SAAwB;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,kBAAkB,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,oBAAoB,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IACxD,kCAAkC,EAAE,CACnC,OAAO,EAAE,4BAA4B,KACjC,IAAI,CAAC;IACV,+BAA+B,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9E,yBAAyB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClE,+BAA+B,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9E,2BAA2B,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACtE,yBAAyB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClE,MAAM,EAAE,IAAI,CAAC;CACb;AAED,oBAAY,yBAAyB,GAClC,qBAAqB,GACrB,uBAAuB,GACvB,8BAA8B,GAC9B,2BAA2B,GAC3B,qBAAqB,GACrB,2BAA2B,CAAC;AAE/B,MAAM,WAAW,8BAA8B;IAC9C,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,0BAA0B,CAAC,CAAC;IAC3E,YAAY,EAAE,OAAO,CAAC;IAEtB,0BAA0B,EAAE,yBAAyB,EAAE,CAAC;IAExD,SAAS,CACR,qBAAqB,CAAC,EAAE,yBAAyB,EAAE,GACjD,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,eAAe,IAAI,YAAY,CAAC;IAChC,iBAAiB,IAAI,cAAc,CAAC;IACpC,sBAAsB,IAAI,mBAAmB,CAAC;IAC9C,wBAAwB,IAAI,qBAAqB,CAAC;IAClD,+BAA+B,IAAI,4BAA4B,CAAC;IAChE,4BAA4B,IAAI,yBAAyB,CAAC;IAC1D,sBAAsB,IAAI,mBAAmB,CAAC;IAC9C,4BAA4B,IAAI,yBAAyB,CAAC;CAC1D;AAED,MAAM,WAAW,iBAAiB;IACjC,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC3D,MAAM,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACrC,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IAClE,YAAY,EAAE,OAAO,CAAC;IAEtB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,cAAc,IAAI,WAAW,CAAC;IAC9B,uBAAuB,IAAI,oBAAoB,CAAC;CAChD"}
@@ -25,11 +25,12 @@ export declare class ClearingHouseUser {
25
25
  getUserAccount(): UserAccount;
26
26
  getUserPositionsAccount(): UserPositionsAccount;
27
27
  /**
28
- * Gets the user's current position for a given market
28
+ * Gets the user's current position for a given market. If the user has no position returns undefined
29
29
  * @param marketIndex
30
30
  * @returns userPosition
31
31
  */
32
- getUserPosition(marketIndex: BN): UserPosition;
32
+ getUserPosition(marketIndex: BN): UserPosition | undefined;
33
+ getEmptyPosition(marketIndex: BN): UserPosition;
33
34
  getUserAccountPublicKey(): Promise<PublicKey>;
34
35
  exists(): Promise<boolean>;
35
36
  /**
@@ -46,12 +47,12 @@ export declare class ClearingHouseUser {
46
47
  * calculates unrealized position price pnl
47
48
  * @returns : Precision QUOTE_PRECISION
48
49
  */
49
- getUnrealizedPNL(withFunding?: boolean): BN;
50
+ getUnrealizedPNL(withFunding?: boolean, marketIndex?: BN): BN;
50
51
  /**
51
52
  * calculates unrealized funding payment pnl
52
53
  * @returns : Precision QUOTE_PRECISION
53
54
  */
54
- getUnrealizedFundingPNL(): BN;
55
+ getUnrealizedFundingPNL(marketIndex?: BN): BN;
55
56
  /**
56
57
  * calculates TotalCollateral: collateral + unrealized pnl
57
58
  * @returns : Precision QUOTE_PRECISION
@@ -72,7 +73,7 @@ export declare class ClearingHouseUser {
72
73
  * calculates average exit price for closing 100% of position
73
74
  * @returns : Precision MARK_PRICE_PRECISION
74
75
  */
75
- getPositionEstimatedExitPrice(position: UserPosition, amountToClose?: BN): BN;
76
+ getPositionEstimatedExitPriceAndPnl(position: UserPosition, amountToClose?: BN): [BN, BN];
76
77
  /**
77
78
  * calculates current user leverage across all positions
78
79
  * @returns : Precision TEN_THOUSAND
@@ -95,6 +96,14 @@ export declare class ClearingHouseUser {
95
96
  * @returns
96
97
  */
97
98
  needsToSettleFundingPayment(): boolean;
99
+ /**
100
+ * Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
101
+ * @param targetMarket
102
+ * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
103
+ * @param partial
104
+ * @returns Precision : MARK_PRICE_PRECISION
105
+ */
106
+ liquidationPriceOld(targetMarket: Pick<UserPosition, 'marketIndex'>, positionBaseSizeChange?: BN, partial?: boolean): BN;
98
107
  /**
99
108
  * Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
100
109
  * @param targetMarket
@@ -112,6 +121,21 @@ export declare class ClearingHouseUser {
112
121
  liquidationPriceAfterClose(positionMarketIndex: BN, closeQuoteAmount: BN): BN;
113
122
  /**
114
123
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
124
+ *
125
+ * To Calculate Max Quote Available:
126
+ *
127
+ * Case 1: SameSide
128
+ * => Remaining quote to get to maxLeverage
129
+ *
130
+ * Case 2: NOT SameSide && currentLeverage <= maxLeverage
131
+ * => Current opposite position x2 + remaining to get to maxLeverage
132
+ *
133
+ * Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
134
+ * => strictly reduce current position size
135
+ *
136
+ * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
137
+ * => current position + remaining to get to maxLeverage
138
+ *
115
139
  * @param marketIndex
116
140
  * @param tradeSide
117
141
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
@@ -1 +1 @@
1
- {"version":3,"file":"clearingHouseUser.d.ts","sourceRoot":"","sources":["../src/clearingHouseUser.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,OAAO,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW1E,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAKN,iBAAiB,EACjB,MAAM,GAAG,CAAC;AAGX,qBAAa,iBAAiB;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,iBAAiB,EAAE,qBAAqB,CAAC;IACzC,oBAAoB,CAAC,EAAE,SAAS,CAAC;IACjC,YAAY,UAAS;IACrB,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;WAEpD,IAAI,CACjB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,GAClB,iBAAiB;gBASnB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,iBAAiB,EAAE,qBAAqB;IAQzC;;;OAGG;IACU,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ7B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC,cAAc,IAAI,WAAW;IAI7B,uBAAuB,IAAI,oBAAoB;IAItD;;;;OAIG;IACI,eAAe,CAAC,WAAW,EAAE,EAAE,GAAG,YAAY;IAaxC,uBAAuB,IAAI,OAAO,CAAC,SAAS,CAAC;IAY7C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IASvC;;;OAGG;IACI,cAAc,IAAI,EAAE;IAM3B;;;OAGG;IACI,iBAAiB,IAAI,EAAE;IAQ9B;;;OAGG;IACI,gBAAgB,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,EAAE;IAYlD;;;OAGG;IACI,uBAAuB,IAAI,EAAE;IAUpC;;;OAGG;IACI,kBAAkB,IAAI,EAAE;IAO/B;;;OAGG;IACH,qBAAqB,IAAI,EAAE;IAY3B;;;OAGG;IACI,gBAAgB,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE;IAMrC,eAAe,CACrB,eAAe,EAAE,IAAI,CAAC,YAAY,EAAE,iBAAiB,CAAC,GACpD,iBAAiB,GAAG,SAAS;IAUhC;;;OAGG;IACI,6BAA6B,CACnC,QAAQ,EAAE,YAAY,EACtB,aAAa,CAAC,EAAE,EAAE,GAChB,EAAE;IAyBL;;;OAGG;IACI,WAAW,IAAI,EAAE;IASxB;;;;OAIG;IACI,cAAc,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,EAAE;IAsB3E;;;OAGG;IACI,cAAc,IAAI,EAAE;IAUpB,eAAe,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;IAMvC;;;OAGG;IACI,2BAA2B,IAAI,OAAO;IAyB7C;;;;;;OAMG;IACI,gBAAgB,CACtB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,EAC/C,sBAAsB,GAAE,EAAS,EACjC,OAAO,UAAQ,GACb,EAAE;IA+HL;;;;;OAKG;IACI,0BAA0B,CAChC,mBAAmB,EAAE,EAAE,EACvB,gBAAgB,EAAE,EAAE,GAClB,EAAE;IAqBL;;;;;;OAMG;IACI,mBAAmB,CACzB,iBAAiB,EAAE,EAAE,EACrB,SAAS,EAAE,iBAAiB,EAC5B,sBAAsB,EAAE,EAAE,GACxB,EAAE;IAqDL;;;;;;OAMG;IACI,8BAA8B,CACpC,iBAAiB,EAAE,EAAE,EACrB,gBAAgB,EAAE,EAAE,EACpB,SAAS,EAAE,iBAAiB,GAC1B,EAAE;IA4BL;;;;OAIG;IACI,0BAA0B,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE;IAQtD;;;;OAIG;IACH,OAAO,CAAC,oCAAoC;CAgB5C"}
1
+ {"version":3,"file":"clearingHouseUser.d.ts","sourceRoot":"","sources":["../src/clearingHouseUser.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ClearingHouseUser = void 0;
16
16
  const bn_js_1 = __importDefault(require("bn.js"));
17
+ const position_1 = require("./math/position");
17
18
  const numericConstants_1 = require("./constants/numericConstants");
18
19
  const defaultUserAccountSubscriber_1 = require("./accounts/defaultUserAccountSubscriber");
19
20
  const _1 = require(".");
@@ -55,18 +56,20 @@ class ClearingHouseUser {
55
56
  return this.accountSubscriber.getUserPositionsAccount();
56
57
  }
57
58
  /**
58
- * Gets the user's current position for a given market
59
+ * Gets the user's current position for a given market. If the user has no position returns undefined
59
60
  * @param marketIndex
60
61
  * @returns userPosition
61
62
  */
62
63
  getUserPosition(marketIndex) {
63
- var _a;
64
- return ((_a = this.getUserPositionsAccount().positions.find((position) => position.marketIndex.eq(marketIndex))) !== null && _a !== void 0 ? _a : {
64
+ return this.getUserPositionsAccount().positions.find((position) => position.marketIndex.eq(marketIndex));
65
+ }
66
+ getEmptyPosition(marketIndex) {
67
+ return {
65
68
  baseAssetAmount: numericConstants_1.ZERO,
66
69
  lastCumulativeFundingRate: numericConstants_1.ZERO,
67
70
  marketIndex,
68
71
  quoteAssetAmount: numericConstants_1.ZERO,
69
- });
72
+ };
70
73
  }
71
74
  getUserAccountPublicKey() {
72
75
  return __awaiter(this, void 0, void 0, function* () {
@@ -106,8 +109,10 @@ class ClearingHouseUser {
106
109
  * calculates unrealized position price pnl
107
110
  * @returns : Precision QUOTE_PRECISION
108
111
  */
109
- getUnrealizedPNL(withFunding) {
110
- return this.getUserPositionsAccount().positions.reduce((pnl, marketPosition) => {
112
+ getUnrealizedPNL(withFunding, marketIndex) {
113
+ return this.getUserPositionsAccount()
114
+ .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
115
+ .reduce((pnl, marketPosition) => {
111
116
  const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
112
117
  return pnl.add(_1.calculatePositionPNL(market, marketPosition, withFunding));
113
118
  }, numericConstants_1.ZERO);
@@ -116,8 +121,10 @@ class ClearingHouseUser {
116
121
  * calculates unrealized funding payment pnl
117
122
  * @returns : Precision QUOTE_PRECISION
118
123
  */
119
- getUnrealizedFundingPNL() {
120
- return this.getUserPositionsAccount().positions.reduce((pnl, marketPosition) => {
124
+ getUnrealizedFundingPNL(marketIndex) {
125
+ return this.getUserPositionsAccount()
126
+ .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
127
+ .reduce((pnl, marketPosition) => {
121
128
  const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
122
129
  return pnl.add(_1.calculatePositionFundingPNL(market, marketPosition));
123
130
  }, numericConstants_1.ZERO);
@@ -145,7 +152,7 @@ class ClearingHouseUser {
145
152
  * @returns : Precision QUOTE_PRECISION
146
153
  */
147
154
  getPositionValue(marketIndex) {
148
- const userPosition = this.getUserPosition(marketIndex);
155
+ const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
149
156
  const market = this.clearingHouse.getMarket(userPosition.marketIndex);
150
157
  return _1.calculateBaseAssetValue(market, userPosition);
151
158
  }
@@ -164,11 +171,12 @@ class ClearingHouseUser {
164
171
  * calculates average exit price for closing 100% of position
165
172
  * @returns : Precision MARK_PRICE_PRECISION
166
173
  */
167
- getPositionEstimatedExitPrice(position, amountToClose) {
174
+ getPositionEstimatedExitPriceAndPnl(position, amountToClose) {
168
175
  const market = this.clearingHouse.getMarket(position.marketIndex);
176
+ const entryPrice = position_1.calculateEntryPrice(position);
169
177
  if (amountToClose) {
170
178
  if (amountToClose.eq(numericConstants_1.ZERO)) {
171
- return _1.calculateMarkPrice(market);
179
+ return [_1.calculateMarkPrice(market), numericConstants_1.ZERO];
172
180
  }
173
181
  position = {
174
182
  baseAssetAmount: amountToClose,
@@ -179,12 +187,18 @@ class ClearingHouseUser {
179
187
  }
180
188
  const baseAssetValue = _1.calculateBaseAssetValue(market, position);
181
189
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
182
- return numericConstants_1.ZERO;
190
+ return [numericConstants_1.ZERO, numericConstants_1.ZERO];
183
191
  }
184
- return baseAssetValue
192
+ const exitPrice = baseAssetValue
185
193
  .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
186
194
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
187
195
  .div(position.baseAssetAmount.abs());
196
+ const pnlPerBase = exitPrice.sub(entryPrice);
197
+ const pnl = pnlPerBase
198
+ .mul(position.baseAssetAmount)
199
+ .div(numericConstants_1.MARK_PRICE_PRECISION)
200
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
201
+ return [exitPrice, pnl];
188
202
  }
189
203
  /**
190
204
  * calculates current user leverage across all positions
@@ -265,7 +279,7 @@ class ClearingHouseUser {
265
279
  * @param partial
266
280
  * @returns Precision : MARK_PRICE_PRECISION
267
281
  */
268
- liquidationPrice(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
282
+ liquidationPriceOld(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
269
283
  // +/-(margin_ratio-liq_ratio) * price_now = price_liq
270
284
  // todo: margin_ratio is not symmetric on price action (both numer and denom change)
271
285
  // margin_ratio = collateral / base_asset_value
@@ -282,10 +296,9 @@ class ClearingHouseUser {
282
296
  const totalCollateralUSDC = this.getTotalCollateral();
283
297
  // calculate the total position value ignoring any value from the target market of the trade
284
298
  const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
285
- const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex);
286
- const currentMarketPositionBaseSize = currentMarketPosition
287
- ? currentMarketPosition.baseAssetAmount
288
- : numericConstants_1.ZERO;
299
+ const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
300
+ this.getEmptyPosition(targetMarket.marketIndex);
301
+ const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
289
302
  // calculate position for current market after trade
290
303
  const proposedMarketPosition = {
291
304
  marketIndex: targetMarket.marketIndex,
@@ -297,23 +310,28 @@ class ClearingHouseUser {
297
310
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
298
311
  // total position value after trade
299
312
  const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
313
+ let totalFreeCollateralUSDC = this.getTotalCollateral().sub(this.getTotalPositionValue()
314
+ .mul(numericConstants_1.TEN_THOUSAND)
315
+ .div(this.getMaxLeverage('Maintenance')));
316
+ if (partial) {
317
+ totalFreeCollateralUSDC = this.getTotalCollateral().sub(this.getTotalPositionValue()
318
+ .mul(numericConstants_1.TEN_THOUSAND)
319
+ .div(this.getMaxLeverage('Partial')));
320
+ }
300
321
  // if the position value after the trade is less than total collateral, there is no liq price
301
- if (targetTotalPositionValueUSDC.lte(totalCollateralUSDC) && proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
322
+ if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
323
+ proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
302
324
  return new bn_js_1.default(-1);
303
325
  }
304
- // proportion of proposed market position to overall position
305
- // const marketProportion = proposedMarketPositionValueUSDC
306
- // .mul(TEN_THOUSAND)
307
- // .div(targetTotalPositionValueUSDC);
308
326
  // get current margin ratio based on current collateral and proposed total position value
309
327
  let marginRatio;
310
- if (targetTotalPositionValueUSDC.eq(numericConstants_1.ZERO)) {
328
+ if (proposedMarketPositionValueUSDC.eq(numericConstants_1.ZERO)) {
311
329
  marginRatio = numericConstants_1.BN_MAX;
312
330
  }
313
331
  else {
314
332
  marginRatio = totalCollateralUSDC
315
333
  .mul(numericConstants_1.TEN_THOUSAND)
316
- .div(targetTotalPositionValueUSDC);
334
+ .div(proposedMarketPositionValueUSDC);
317
335
  }
318
336
  let liqRatio = numericConstants_1.FULL_LIQUIDATION_RATIO;
319
337
  if (partial) {
@@ -321,27 +339,6 @@ class ClearingHouseUser {
321
339
  }
322
340
  // sign of position in current market after the trade
323
341
  const baseAssetSignIsNeg = proposedMarketPosition.baseAssetAmount.isNeg();
324
- // console.log(
325
- // convertToNumber(currentPrice),
326
- // convertToNumber(liqRatio),
327
- // convertToNumber(marginRatio),
328
- // convertToNumber(marketProportion),
329
- // );
330
- // // if the user is long, then the liq price is the currentPrice multiplied by liqRatio/marginRatio (how many multiples lower does the current marginRatio have to go to reach the liqRatio), multiplied by the fraction of the proposed total position value that this market will take up
331
- // if (!baseAssetSignIsNeg) {
332
- // liqPrice = currentPrice
333
- // .mul(liqRatio)
334
- // .div(marginRatio)
335
- // .mul(marketProportion)
336
- // .div(TEN_THOUSAND);
337
- // } else {
338
- // // if the user is short, it's the reciprocal of the above
339
- // liqPrice = currentPrice
340
- // .mul(marginRatio)
341
- // .div(liqRatio)
342
- // .mul(TEN_THOUSAND)
343
- // .div(marketProportion);
344
- // }
345
342
  let pctChange = marginRatio.abs().sub(liqRatio);
346
343
  // if user is short, higher price is liq
347
344
  if (baseAssetSignIsNeg) {
@@ -358,6 +355,83 @@ class ClearingHouseUser {
358
355
  const liqPrice = currentPrice.mul(pctChange).div(numericConstants_1.TEN_THOUSAND);
359
356
  return liqPrice;
360
357
  }
358
+ /**
359
+ * Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
360
+ * @param targetMarket
361
+ * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
362
+ * @param partial
363
+ * @returns Precision : MARK_PRICE_PRECISION
364
+ */
365
+ liquidationPrice(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
366
+ // solves formula for example calc below
367
+ /* example: assume BTC price is $40k (examine 10% up/down)
368
+
369
+ if 10k deposit and levered 10x short BTC => BTC up $400 means:
370
+ 1. higher base_asset_value (+$4k)
371
+ 2. lower collateral (-$4k)
372
+ 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
373
+
374
+ for 10x long, BTC down $400:
375
+ 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
376
+ const tc = this.getTotalCollateral();
377
+ const tpv = this.getTotalPositionValue();
378
+ const partialLev = 16;
379
+ const maintLev = 20;
380
+ const thisLev = partial ? new bn_js_1.default(partialLev) : new bn_js_1.default(maintLev);
381
+ // calculate the total position value ignoring any value from the target market of the trade
382
+ const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
383
+ const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
384
+ this.getEmptyPosition(targetMarket.marketIndex);
385
+ const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
386
+ const proposedBaseAssetAmount = currentMarketPositionBaseSize.add(positionBaseSizeChange);
387
+ // calculate position for current market after trade
388
+ const proposedMarketPosition = {
389
+ marketIndex: targetMarket.marketIndex,
390
+ baseAssetAmount: proposedBaseAssetAmount,
391
+ lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
392
+ quoteAssetAmount: new bn_js_1.default(0),
393
+ };
394
+ const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
395
+ const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
396
+ // total position value after trade
397
+ const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
398
+ let totalFreeCollateralUSDC = tc.sub(totalCurrentPositionValueIgnoringTargetUSDC
399
+ .mul(numericConstants_1.TEN_THOUSAND)
400
+ .div(this.getMaxLeverage('Maintenance')));
401
+ if (partial) {
402
+ totalFreeCollateralUSDC = tc.sub(totalCurrentPositionValueIgnoringTargetUSDC
403
+ .mul(numericConstants_1.TEN_THOUSAND)
404
+ .div(this.getMaxLeverage('Partial')));
405
+ }
406
+ let priceDelt;
407
+ if (currentMarketPositionBaseSize.lt(numericConstants_1.ZERO)) {
408
+ priceDelt = tc
409
+ .mul(thisLev)
410
+ .sub(tpv)
411
+ .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
412
+ .div(thisLev.add(new bn_js_1.default(1)));
413
+ }
414
+ else {
415
+ priceDelt = tc
416
+ .mul(thisLev)
417
+ .sub(tpv)
418
+ .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
419
+ .div(thisLev.sub(new bn_js_1.default(1)));
420
+ }
421
+ const currentPrice = _1.calculateMarkPrice(this.clearingHouse.getMarket(targetMarket.marketIndex));
422
+ // if the position value after the trade is less than total collateral, there is no liq price
423
+ if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
424
+ proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
425
+ return new bn_js_1.default(-1);
426
+ }
427
+ if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
428
+ return new bn_js_1.default(-1);
429
+ const eatMargin2 = priceDelt
430
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION)
431
+ .div(proposedBaseAssetAmount);
432
+ const liqPrice = currentPrice.sub(eatMargin2);
433
+ return liqPrice;
434
+ }
361
435
  /**
362
436
  * Calculates the estimated liquidation price for a position after closing a quote amount of the position.
363
437
  * @param positionMarketIndex
@@ -365,7 +439,8 @@ class ClearingHouseUser {
365
439
  * @returns : Precision MARK_PRICE_PRECISION
366
440
  */
367
441
  liquidationPriceAfterClose(positionMarketIndex, closeQuoteAmount) {
368
- const currentPosition = this.getUserPosition(positionMarketIndex);
442
+ const currentPosition = this.getUserPosition(positionMarketIndex) ||
443
+ this.getEmptyPosition(positionMarketIndex);
369
444
  const closeBaseAmount = currentPosition.baseAssetAmount
370
445
  .mul(closeQuoteAmount)
371
446
  .div(currentPosition.quoteAssetAmount)
@@ -379,31 +454,42 @@ class ClearingHouseUser {
379
454
  }
380
455
  /**
381
456
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
457
+ *
458
+ * To Calculate Max Quote Available:
459
+ *
460
+ * Case 1: SameSide
461
+ * => Remaining quote to get to maxLeverage
462
+ *
463
+ * Case 2: NOT SameSide && currentLeverage <= maxLeverage
464
+ * => Current opposite position x2 + remaining to get to maxLeverage
465
+ *
466
+ * Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
467
+ * => strictly reduce current position size
468
+ *
469
+ * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
470
+ * => current position + remaining to get to maxLeverage
471
+ *
382
472
  * @param marketIndex
383
473
  * @param tradeSide
384
474
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
385
475
  * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
386
476
  */
387
477
  getMaxTradeSizeUSDC(targetMarketIndex, tradeSide, userMaxLeverageSetting) {
388
- // inline function which get's the current position size on the opposite side of the target trade
389
- const getOppositePositionValueUSDC = () => {
390
- if (!currentPosition)
391
- return numericConstants_1.ZERO;
392
- const side = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
393
- if (side === 'long' && (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())) {
394
- return this.getPositionValue(targetMarketIndex);
395
- }
396
- else if (side === 'short' &&
397
- !(currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())) {
398
- return this.getPositionValue(targetMarketIndex);
399
- }
400
- return numericConstants_1.ZERO;
401
- };
402
- const currentPosition = this.getUserPosition(targetMarketIndex);
478
+ const currentPosition = this.getUserPosition(targetMarketIndex) ||
479
+ this.getEmptyPosition(targetMarketIndex);
480
+ const targetSide = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
481
+ const currentPositionSide = (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())
482
+ ? 'short'
483
+ : 'long';
484
+ const targettingSameSide = !currentPosition
485
+ ? true
486
+ : targetSide === currentPositionSide;
487
+ // 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.
488
+ const oppositeSizeValueUSDC = targettingSameSide
489
+ ? numericConstants_1.ZERO
490
+ : this.getPositionValue(targetMarketIndex);
403
491
  // get current leverage
404
492
  const currentLeverage = this.getLeverage();
405
- // remaining leverage
406
- // let remainingLeverage = userMaxLeverageSetting;
407
493
  const remainingLeverage = bn_js_1.default.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
408
494
  // get total collateral
409
495
  const totalCollateral = this.getTotalCollateral();
@@ -411,9 +497,43 @@ class ClearingHouseUser {
411
497
  let maxPositionSize = remainingLeverage
412
498
  .mul(totalCollateral)
413
499
  .div(numericConstants_1.TEN_THOUSAND);
414
- // 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.
415
- const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
416
- maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC);
500
+ if (userMaxLeverageSetting.sub(currentLeverage).gte(numericConstants_1.ZERO)) {
501
+ if (oppositeSizeValueUSDC.eq(numericConstants_1.ZERO)) {
502
+ // case 1 : Regular trade where current total position less than max, and no opposite position to account for
503
+ // do nothing
504
+ }
505
+ else {
506
+ // case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
507
+ maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
508
+ }
509
+ }
510
+ else {
511
+ // current leverage is greater than max leverage - can only reduce position size
512
+ if (!targettingSameSide) {
513
+ const currentPositionQuoteSize = this.getPositionValue(targetMarketIndex);
514
+ const currentTotalQuoteSize = currentLeverage
515
+ .mul(totalCollateral)
516
+ .div(numericConstants_1.TEN_THOUSAND);
517
+ const otherPositionsTotalQuoteSize = currentTotalQuoteSize.sub(currentPositionQuoteSize);
518
+ const quoteValueOfMaxLeverage = userMaxLeverageSetting
519
+ .mul(totalCollateral)
520
+ .div(numericConstants_1.TEN_THOUSAND);
521
+ if (otherPositionsTotalQuoteSize
522
+ .sub(currentPositionQuoteSize)
523
+ .gte(quoteValueOfMaxLeverage)) {
524
+ // case 3: Can only reduce the current position because it will still be greater than max leverage
525
+ maxPositionSize = currentPositionQuoteSize;
526
+ }
527
+ else {
528
+ // case 4: Can reduce the position, and then take extra remaining quote to get to max leverage
529
+ const allowedQuoteSizeAfterClosingCurrentPosition = quoteValueOfMaxLeverage.sub(otherPositionsTotalQuoteSize);
530
+ maxPositionSize = currentPositionQuoteSize.add(allowedQuoteSizeAfterClosingCurrentPosition);
531
+ }
532
+ }
533
+ else {
534
+ // do nothing if targetting same side
535
+ }
536
+ }
417
537
  // subtract oneMillionth of maxPositionSize
418
538
  // => to avoid rounding errors when taking max leverage
419
539
  const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
@@ -428,9 +548,10 @@ class ClearingHouseUser {
428
548
  * @returns leverageRatio : Precision TEN_THOUSAND
429
549
  */
430
550
  accountLeverageRatioAfterTrade(targetMarketIndex, tradeQuoteAmount, tradeSide) {
431
- const currentPosition = this.getUserPosition(targetMarketIndex);
432
- let currentPositionQuoteAmount = currentPosition.quoteAssetAmount;
433
- const currentSide = currentPosition.baseAssetAmount.isNeg()
551
+ const currentPosition = this.getUserPosition(targetMarketIndex) ||
552
+ this.getEmptyPosition(targetMarketIndex);
553
+ let currentPositionQuoteAmount = this.getPositionValue(targetMarketIndex);
554
+ const currentSide = currentPosition && currentPosition.baseAssetAmount.isNeg()
434
555
  ? _1.PositionDirection.SHORT
435
556
  : _1.PositionDirection.LONG;
436
557
  if (currentSide === _1.PositionDirection.SHORT)
@@ -441,11 +562,18 @@ class ClearingHouseUser {
441
562
  .add(tradeQuoteAmount)
442
563
  .abs();
443
564
  const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPositionValueExcludingMarket(targetMarketIndex);
444
- return currentMarketPositionAfterTrade
445
- .add(totalPositionAfterTradeExcludingTargetMarket)
446
- .abs()
447
- .mul(numericConstants_1.TEN_THOUSAND)
448
- .div(this.getTotalCollateral());
565
+ const totalCollateral = this.getTotalCollateral();
566
+ if (totalCollateral.gt(numericConstants_1.ZERO)) {
567
+ const newLeverage = currentMarketPositionAfterTrade
568
+ .add(totalPositionAfterTradeExcludingTargetMarket)
569
+ .abs()
570
+ .mul(numericConstants_1.TEN_THOUSAND)
571
+ .div(totalCollateral);
572
+ return newLeverage;
573
+ }
574
+ else {
575
+ return new bn_js_1.default(0);
576
+ }
449
577
  }
450
578
  /**
451
579
  * Calculates how much fee will be taken for a given sized trade
@@ -464,11 +592,11 @@ class ClearingHouseUser {
464
592
  * @returns positionValue : Precision QUOTE_PRECISION
465
593
  */
466
594
  getTotalPositionValueExcludingMarket(marketToIgnore) {
467
- const currentMarketPosition = this.getUserPosition(marketToIgnore);
595
+ const currentMarketPosition = this.getUserPosition(marketToIgnore) ||
596
+ this.getEmptyPosition(marketToIgnore);
468
597
  let currentMarketPositionValueUSDC = numericConstants_1.ZERO;
469
598
  if (currentMarketPosition) {
470
- const market = this.clearingHouse.getMarket(currentMarketPosition.marketIndex);
471
- currentMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, currentMarketPosition);
599
+ currentMarketPositionValueUSDC = this.getPositionValue(marketToIgnore);
472
600
  }
473
601
  return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
474
602
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markets.d.ts","sourceRoot":"","sources":["../../src/constants/markets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,aAAK,MAAM,GAAG;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,EAAE,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,EA6B3B,CAAC"}
1
+ {"version":3,"file":"markets.d.ts","sourceRoot":"","sources":["../../src/constants/markets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,aAAK,MAAM,GAAG;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,EAAE,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,EAkD3B,CAAC"}
@@ -34,4 +34,25 @@ exports.Markets = [
34
34
  devnetPythOracle: '8PugCXTAHLM9kfLSQWe2njE5pzAgUdpPk3Nx5zSm7BD3',
35
35
  mainnetPythOracle: '5bmWuR1dgP4avtGYMNKLuxumZTVKGgoN2BCMXWDNL9nY',
36
36
  },
37
+ {
38
+ symbol: 'AVAX-PERP',
39
+ baseAssetSymbol: 'AVAX',
40
+ marketIndex: new bn_js_1.default(4),
41
+ devnetPythOracle: 'FVb5h1VmHPfVb1RfqZckchq18GxRv4iKt8T4eVTQAqdz',
42
+ mainnetPythOracle: 'Ax9ujW5B9oqcv59N8m6f1BpTBq2rGeGaBcpKjC5UYsXU',
43
+ },
44
+ {
45
+ symbol: 'BNB-PERP',
46
+ baseAssetSymbol: 'BNB',
47
+ marketIndex: new bn_js_1.default(5),
48
+ devnetPythOracle: 'GwzBgrXb4PG59zjce24SF2b9JXbLEjJJTBkmytuEZj1b',
49
+ mainnetPythOracle: '4CkQJBxhU8EZ2UjhigbtdaPbpTe6mqf811fipYBFbSYN',
50
+ },
51
+ {
52
+ symbol: 'MATIC-PERP',
53
+ baseAssetSymbol: 'MATIC',
54
+ marketIndex: new bn_js_1.default(6),
55
+ devnetPythOracle: 'FBirwuDFuRAu4iSGc7RGxN5koHB7EJM1wbCmyPuQoGur',
56
+ mainnetPythOracle: '7KVswB9vkCgeM3SHP7aGDijvdRAHK8P5wi9JXViCrtYh',
57
+ },
37
58
  ];
@@ -13,4 +13,5 @@ export declare const PEG_PRECISION: BN;
13
13
  export declare const AMM_RESERVE_PRECISION: BN;
14
14
  export declare const AMM_TO_QUOTE_PRECISION_RATIO: BN;
15
15
  export declare const PRICE_TO_QUOTE_PRECISION: BN;
16
+ export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
16
17
  //# sourceMappingURL=numericConstants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"numericConstants.d.ts","sourceRoot":"","sources":["../../src/constants/numericConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,eAAO,MAAM,IAAI,IAAY,CAAC;AAC9B,eAAO,MAAM,GAAG,IAAY,CAAC;AAC7B,eAAO,MAAM,YAAY,IAAgB,CAAC;AAC1C,eAAO,MAAM,MAAM,IAAkC,CAAC;AAEtD,eAAO,MAAM,YAAY,IAAY,CAAC;AACtC,eAAO,MAAM,sBAAsB,IAAc,CAAC;AAClD,eAAO,MAAM,yBAAyB,IAAc,CAAC;AAErD,eAAO,MAAM,eAAe,IAAkB,CAAC;AAC/C,eAAO,MAAM,oBAAoB,IAAmB,CAAC;AACrD,eAAO,MAAM,yBAAyB,IAAgB,CAAC;AACvD,eAAO,MAAM,aAAa,IAAe,CAAC;AAE1C,eAAO,MAAM,qBAAqB,IAAmB,CAAC;AACtD,eAAO,MAAM,4BAA4B,IACE,CAAC;AAC5C,eAAO,MAAM,wBAAwB,IACK,CAAC"}
1
+ {"version":3,"file":"numericConstants.d.ts","sourceRoot":"","sources":["../../src/constants/numericConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,eAAO,MAAM,IAAI,IAAY,CAAC;AAC9B,eAAO,MAAM,GAAG,IAAY,CAAC;AAC7B,eAAO,MAAM,YAAY,IAAgB,CAAC;AAC1C,eAAO,MAAM,MAAM,IAAkC,CAAC;AAEtD,eAAO,MAAM,YAAY,IAAY,CAAC;AACtC,eAAO,MAAM,sBAAsB,IAAc,CAAC;AAClD,eAAO,MAAM,yBAAyB,IAAc,CAAC;AAErD,eAAO,MAAM,eAAe,IAAkB,CAAC;AAC/C,eAAO,MAAM,oBAAoB,IAAmB,CAAC;AACrD,eAAO,MAAM,yBAAyB,IAAgB,CAAC;AACvD,eAAO,MAAM,aAAa,IAAe,CAAC;AAE1C,eAAO,MAAM,qBAAqB,IAAmB,CAAC;AACtD,eAAO,MAAM,4BAA4B,IACE,CAAC;AAC5C,eAAO,MAAM,wBAAwB,IACK,CAAC;AAC3C,eAAO,MAAM,sCAAsC,IACW,CAAC"}
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.PARTIAL_LIQUIDATION_RATIO = exports.FULL_LIQUIDATION_RATIO = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.ONE = exports.ZERO = void 0;
6
+ exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.PARTIAL_LIQUIDATION_RATIO = exports.FULL_LIQUIDATION_RATIO = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.ONE = exports.ZERO = void 0;
7
7
  const bn_js_1 = __importDefault(require("bn.js"));
8
8
  exports.ZERO = new bn_js_1.default(0);
9
9
  exports.ONE = new bn_js_1.default(1);
@@ -19,3 +19,4 @@ exports.PEG_PRECISION = new bn_js_1.default(1000);
19
19
  exports.AMM_RESERVE_PRECISION = new bn_js_1.default(Math.pow(10, 13));
20
20
  exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.div(exports.QUOTE_PRECISION); // 10^7
21
21
  exports.PRICE_TO_QUOTE_PRECISION = exports.MARK_PRICE_PRECISION.div(exports.QUOTE_PRECISION);
22
+ exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.mul(exports.PEG_PRECISION).div(exports.QUOTE_PRECISION); // 10^10
@@ -1 +1 @@
1
- {"version":3,"file":"makeTradeExample.d.ts","sourceRoot":"","sources":["../../src/examples/makeTradeExample.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAcjE,eAAO,MAAM,eAAe,gBACd,MAAM,cACP,MAAM,KAChB,QAAQ,SAAS,CAOnB,CAAC"}
1
+ {"version":3,"file":"makeTradeExample.d.ts","sourceRoot":"","sources":["../../src/examples/makeTradeExample.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAcjE,eAAO,MAAM,eAAe,gBACd,MAAM,cACP,MAAM,KAChB,QAAQ,SAAS,CAOnB,CAAC"}