@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +6 -6
  2. package/lib/accounts/bulkAccountLoader.js +81 -95
  3. package/lib/accounts/bulkUserSubscription.js +13 -57
  4. package/lib/accounts/fetch.d.ts +4 -0
  5. package/lib/accounts/fetch.js +18 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
  8. package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
  9. package/lib/accounts/pollingOracleSubscriber.js +37 -49
  10. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  11. package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
  12. package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
  13. package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
  14. package/lib/accounts/types.d.ts +34 -41
  15. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
  16. package/lib/accounts/webSocketAccountSubscriber.js +39 -35
  17. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
  18. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
  19. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
  20. package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
  21. package/lib/addresses/marketAddresses.d.ts +4 -0
  22. package/lib/addresses/marketAddresses.js +15 -0
  23. package/lib/addresses/pda.d.ts +12 -0
  24. package/lib/addresses/pda.js +83 -0
  25. package/lib/admin.d.ts +8 -17
  26. package/lib/admin.js +366 -558
  27. package/lib/clearingHouse.d.ts +84 -109
  28. package/lib/clearingHouse.js +778 -899
  29. package/lib/clearingHouseConfig.d.ts +34 -0
  30. package/lib/clearingHouseConfig.js +2 -0
  31. package/lib/clearingHouseUser.d.ts +19 -22
  32. package/lib/clearingHouseUser.js +155 -141
  33. package/lib/clearingHouseUserConfig.d.ts +14 -0
  34. package/lib/clearingHouseUserConfig.js +2 -0
  35. package/lib/config.d.ts +12 -0
  36. package/lib/config.js +35 -4
  37. package/lib/constants/banks.d.ts +16 -0
  38. package/lib/constants/banks.js +34 -0
  39. package/lib/constants/markets.d.ts +8 -3
  40. package/lib/constants/markets.js +13 -206
  41. package/lib/constants/numericConstants.d.ts +16 -0
  42. package/lib/constants/numericConstants.js +22 -6
  43. package/lib/events/eventList.d.ts +22 -0
  44. package/lib/events/eventList.js +77 -0
  45. package/lib/events/eventSubscriber.d.ts +34 -0
  46. package/lib/events/eventSubscriber.js +126 -0
  47. package/lib/events/fetchLogs.d.ts +13 -0
  48. package/lib/events/fetchLogs.js +39 -0
  49. package/lib/events/pollingLogProvider.d.ts +15 -0
  50. package/lib/events/pollingLogProvider.js +53 -0
  51. package/lib/events/sort.d.ts +2 -0
  52. package/lib/events/sort.js +44 -0
  53. package/lib/events/txEventCache.d.ts +24 -0
  54. package/lib/events/txEventCache.js +71 -0
  55. package/lib/events/types.d.ts +49 -0
  56. package/lib/events/types.js +20 -0
  57. package/lib/events/webSocketLogProvider.d.ts +12 -0
  58. package/lib/events/webSocketLogProvider.js +30 -0
  59. package/lib/examples/makeTradeExample.js +26 -27
  60. package/lib/factory/bigNum.d.ts +112 -0
  61. package/lib/factory/bigNum.js +356 -0
  62. package/lib/factory/oracleClient.d.ts +1 -2
  63. package/lib/factory/oracleClient.js +6 -2
  64. package/lib/idl/clearing_house.json +2213 -2951
  65. package/lib/index.d.ts +12 -4
  66. package/lib/index.js +12 -4
  67. package/lib/math/amm.d.ts +19 -29
  68. package/lib/math/amm.js +129 -179
  69. package/lib/math/auction.d.ts +5 -0
  70. package/lib/math/auction.js +39 -0
  71. package/lib/math/bankBalance.d.ts +9 -0
  72. package/lib/math/bankBalance.js +75 -0
  73. package/lib/math/conversion.d.ts +0 -1
  74. package/lib/math/conversion.js +1 -5
  75. package/lib/math/funding.d.ts +6 -6
  76. package/lib/math/funding.js +158 -175
  77. package/lib/math/market.d.ts +6 -6
  78. package/lib/math/market.js +10 -9
  79. package/lib/math/orders.d.ts +5 -0
  80. package/lib/math/orders.js +31 -1
  81. package/lib/math/position.d.ts +7 -5
  82. package/lib/math/position.js +27 -27
  83. package/lib/math/repeg.d.ts +22 -0
  84. package/lib/math/repeg.js +128 -0
  85. package/lib/math/trade.d.ts +5 -4
  86. package/lib/math/trade.js +29 -21
  87. package/lib/mockUSDCFaucet.js +87 -116
  88. package/lib/oracles/oracleClientCache.d.ts +8 -0
  89. package/lib/oracles/oracleClientCache.js +19 -0
  90. package/lib/oracles/pythClient.d.ts +3 -5
  91. package/lib/oracles/pythClient.js +12 -31
  92. package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
  93. package/lib/oracles/quoteAssetOracleClient.js +21 -0
  94. package/lib/oracles/switchboardClient.d.ts +3 -5
  95. package/lib/oracles/switchboardClient.js +29 -50
  96. package/lib/oracles/types.d.ts +6 -1
  97. package/lib/orders.d.ts +6 -6
  98. package/lib/orders.js +10 -9
  99. package/lib/slot/SlotSubscriber.d.ts +12 -0
  100. package/lib/slot/SlotSubscriber.js +23 -0
  101. package/lib/tx/retryTxSender.d.ts +2 -2
  102. package/lib/tx/retryTxSender.js +108 -123
  103. package/lib/tx/types.d.ts +5 -1
  104. package/lib/tx/utils.d.ts +1 -1
  105. package/lib/tx/utils.js +11 -2
  106. package/lib/types.d.ts +105 -109
  107. package/lib/types.js +13 -1
  108. package/lib/userName.d.ts +4 -0
  109. package/lib/userName.js +20 -0
  110. package/lib/util/computeUnits.js +10 -21
  111. package/lib/util/tps.js +11 -22
  112. package/lib/wallet.js +7 -20
  113. package/package.json +10 -3
  114. package/src/accounts/bulkAccountLoader.ts +21 -15
  115. package/src/accounts/bulkUserSubscription.ts +1 -45
  116. package/src/accounts/fetch.ts +33 -0
  117. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
  118. package/src/accounts/pollingOracleSubscriber.ts +16 -8
  119. package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
  120. package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
  121. package/src/accounts/types.ts +41 -70
  122. package/src/accounts/webSocketAccountSubscriber.ts +33 -16
  123. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
  124. package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
  125. package/src/addresses/marketAddresses.ts +18 -0
  126. package/src/addresses/pda.ts +118 -0
  127. package/src/admin.ts +205 -346
  128. package/src/clearingHouse.ts +918 -961
  129. package/src/clearingHouseConfig.ts +37 -0
  130. package/src/clearingHouseUser.ts +275 -185
  131. package/src/clearingHouseUserConfig.ts +18 -0
  132. package/src/config.ts +54 -1
  133. package/src/constants/banks.ts +43 -0
  134. package/src/constants/markets.ts +16 -207
  135. package/src/constants/numericConstants.ts +33 -5
  136. package/src/events/eventList.ts +94 -0
  137. package/src/events/eventSubscriber.ts +194 -0
  138. package/src/events/fetchLogs.ts +80 -0
  139. package/src/events/pollingLogProvider.ts +79 -0
  140. package/src/events/sort.ts +65 -0
  141. package/src/events/txEventCache.ts +74 -0
  142. package/src/events/types.ts +98 -0
  143. package/src/events/webSocketLogProvider.ts +38 -0
  144. package/src/examples/makeTradeExample.ts +20 -11
  145. package/src/factory/bigNum.ts +507 -0
  146. package/src/factory/oracleClient.ts +7 -4
  147. package/src/idl/clearing_house.json +2213 -2951
  148. package/src/index.ts +12 -4
  149. package/src/math/amm.ts +229 -245
  150. package/src/math/auction.ts +39 -0
  151. package/src/math/bankBalance.ts +112 -0
  152. package/src/math/conversion.ts +1 -11
  153. package/src/math/funding.ts +12 -9
  154. package/src/math/market.ts +37 -30
  155. package/src/math/orders.ts +38 -0
  156. package/src/math/position.ts +48 -35
  157. package/src/math/repeg.ts +175 -0
  158. package/src/math/trade.ts +45 -35
  159. package/src/math/utils.js +27 -0
  160. package/src/math/utils.js.map +1 -0
  161. package/src/oracles/oracleClientCache.ts +20 -0
  162. package/src/oracles/pythClient.ts +4 -11
  163. package/src/oracles/quoteAssetOracleClient.ts +25 -0
  164. package/src/oracles/switchboardClient.ts +11 -24
  165. package/src/oracles/types.ts +7 -1
  166. package/src/orders.ts +35 -20
  167. package/src/slot/SlotSubscriber.ts +32 -0
  168. package/src/tx/retryTxSender.ts +6 -4
  169. package/src/tx/types.ts +6 -1
  170. package/src/tx/utils.ts +22 -3
  171. package/src/types.ts +108 -122
  172. package/src/userName.ts +20 -0
  173. package/src/util/computeUnits.js +17 -0
  174. package/src/util/computeUnits.js.map +1 -0
  175. package/tests/bn/test.ts +255 -0
  176. package/tsconfig.json +12 -12
  177. package/lib/addresses.d.ts +0 -10
  178. package/lib/addresses.js +0 -93
  179. package/lib/constants/accounts.d.ts +0 -15
  180. package/lib/constants/accounts.js +0 -18
  181. package/lib/factory/clearingHouse.d.ts +0 -35
  182. package/lib/factory/clearingHouse.js +0 -81
  183. package/lib/factory/clearingHouseUser.d.ts +0 -19
  184. package/lib/factory/clearingHouseUser.js +0 -34
  185. package/lib/math/insuranceFund.d.ts +0 -15
  186. package/lib/math/insuranceFund.js +0 -33
  187. package/lib/settlement.d.ts +0 -4
  188. package/lib/settlement.js +0 -10
  189. package/lib/tx/defaultTxSender.d.ts +0 -8
  190. package/lib/tx/defaultTxSender.js +0 -12
  191. package/src/addresses.ts +0 -82
  192. package/src/constants/accounts.ts +0 -26
  193. package/src/factory/clearingHouse.ts +0 -173
  194. package/src/factory/clearingHouseUser.ts +0 -73
  195. package/src/math/insuranceFund.ts +0 -29
  196. package/src/settlement.ts +0 -9
  197. package/src/tx/defaultTxSender.ts +0 -24
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
3
+ exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
4
4
  const types_1 = require("../types");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ const anchor_1 = require("@project-serum/anchor");
7
+ const auction_1 = require("./auction");
6
8
  function isOrderRiskIncreasing(user, order) {
7
9
  if ((0, types_1.isVariant)(order.status, 'init')) {
8
10
  return false;
@@ -71,3 +73,31 @@ function isOrderReduceOnly(user, order) {
71
73
  return true;
72
74
  }
73
75
  exports.isOrderReduceOnly = isOrderReduceOnly;
76
+ function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
77
+ const remainder = baseAssetAmount.mod(stepSize);
78
+ return baseAssetAmount.sub(remainder);
79
+ }
80
+ exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
81
+ function getLimitPrice(order, oraclePriceData, slot) {
82
+ let limitPrice;
83
+ if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
84
+ const floatingPrice = oraclePriceData.price.add(order.oraclePriceOffset);
85
+ if (order.postOnly) {
86
+ limitPrice = (0, types_1.isVariant)(order.direction, 'long')
87
+ ? anchor_1.BN.min(order.price, floatingPrice)
88
+ : anchor_1.BN.max(order.price, floatingPrice);
89
+ }
90
+ else {
91
+ limitPrice = floatingPrice;
92
+ }
93
+ }
94
+ else if ((0, types_1.isVariant)(order.orderType, 'market') ||
95
+ (0, types_1.isVariant)(order.orderType, 'triggerMarket')) {
96
+ limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
97
+ }
98
+ else {
99
+ limitPrice = order.price;
100
+ }
101
+ return limitPrice;
102
+ }
103
+ exports.getLimitPrice = getLimitPrice;
@@ -1,14 +1,16 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '../';
3
- import { Market, PositionDirection, UserPosition } from '../types';
3
+ import { OraclePriceData } from '../oracles/types';
4
+ import { MarketAccount, PositionDirection, UserPosition } from '../types';
4
5
  /**
5
6
  * calculateBaseAssetValue
6
7
  * = market value of closing entire position
7
8
  * @param market
8
9
  * @param userPosition
10
+ * @param oraclePriceData
9
11
  * @returns Base Asset Value. : Precision QUOTE_PRECISION
10
12
  */
11
- export declare function calculateBaseAssetValue(market: Market, userPosition: UserPosition): BN;
13
+ export declare function calculateBaseAssetValue(market: MarketAccount, userPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
12
14
  /**
13
15
  * calculatePositionPNL
14
16
  * = BaseAssetAmount * (Avg Exit Price - Avg Entry Price)
@@ -17,15 +19,15 @@ export declare function calculateBaseAssetValue(market: Market, userPosition: Us
17
19
  * @param withFunding (adds unrealized funding payment pnl to result)
18
20
  * @returns BaseAssetAmount : Precision QUOTE_PRECISION
19
21
  */
20
- export declare function calculatePositionPNL(market: Market, marketPosition: UserPosition, withFunding?: boolean): BN;
21
- export declare function calculateSettledPositionPNL(market: Market, marketPosition: UserPosition): BN;
22
+ export declare function calculatePositionPNL(market: MarketAccount, marketPosition: UserPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
22
23
  /**
23
24
  *
24
25
  * @param market
25
26
  * @param marketPosition
26
27
  * @returns // TODO-PRECISION
27
28
  */
28
- export declare function calculatePositionFundingPNL(market: Market, marketPosition: UserPosition): BN;
29
+ export declare function calculatePositionFundingPNL(market: MarketAccount, marketPosition: UserPosition): BN;
30
+ export declare function positionIsAvailable(position: UserPosition): boolean;
29
31
  /**
30
32
  *
31
33
  * @param userPosition
@@ -1,34 +1,47 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.calculatePositionFundingPNL = exports.calculateSettledPositionPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
3
+ exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
4
4
  const __1 = require("../");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const types_1 = require("../types");
7
7
  const amm_1 = require("./amm");
8
- const settlement_1 = require("../settlement");
9
8
  /**
10
9
  * calculateBaseAssetValue
11
10
  * = market value of closing entire position
12
11
  * @param market
13
12
  * @param userPosition
13
+ * @param oraclePriceData
14
14
  * @returns Base Asset Value. : Precision QUOTE_PRECISION
15
15
  */
16
- function calculateBaseAssetValue(market, userPosition) {
16
+ function calculateBaseAssetValue(market, userPosition, oraclePriceData) {
17
17
  if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
18
18
  return numericConstants_1.ZERO;
19
19
  }
20
20
  const directionToClose = findDirectionToClose(userPosition);
21
- const [newQuoteAssetReserve, _] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', userPosition.baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', directionToClose));
21
+ let prepegAmm;
22
+ if (market.amm.baseSpread > 0) {
23
+ const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, directionToClose, oraclePriceData);
24
+ prepegAmm = {
25
+ baseAssetReserve,
26
+ quoteAssetReserve,
27
+ sqrtK: sqrtK,
28
+ pegMultiplier: newPeg,
29
+ };
30
+ }
31
+ else {
32
+ prepegAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
33
+ }
34
+ const [newQuoteAssetReserve, _] = (0, amm_1.calculateAmmReservesAfterSwap)(prepegAmm, 'base', userPosition.baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', directionToClose));
22
35
  switch (directionToClose) {
23
36
  case types_1.PositionDirection.SHORT:
24
- return market.amm.quoteAssetReserve
37
+ return prepegAmm.quoteAssetReserve
25
38
  .sub(newQuoteAssetReserve)
26
- .mul(market.amm.pegMultiplier)
39
+ .mul(prepegAmm.pegMultiplier)
27
40
  .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
28
41
  case types_1.PositionDirection.LONG:
29
42
  return newQuoteAssetReserve
30
- .sub(market.amm.quoteAssetReserve)
31
- .mul(market.amm.pegMultiplier)
43
+ .sub(prepegAmm.quoteAssetReserve)
44
+ .mul(prepegAmm.pegMultiplier)
32
45
  .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
33
46
  .add(numericConstants_1.ONE);
34
47
  }
@@ -42,11 +55,11 @@ exports.calculateBaseAssetValue = calculateBaseAssetValue;
42
55
  * @param withFunding (adds unrealized funding payment pnl to result)
43
56
  * @returns BaseAssetAmount : Precision QUOTE_PRECISION
44
57
  */
45
- function calculatePositionPNL(market, marketPosition, withFunding = false) {
58
+ function calculatePositionPNL(market, marketPosition, withFunding = false, oraclePriceData) {
46
59
  if (marketPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
47
60
  return numericConstants_1.ZERO;
48
61
  }
49
- const baseAssetValue = calculateBaseAssetValue(market, marketPosition);
62
+ const baseAssetValue = calculateBaseAssetValue(market, marketPosition, oraclePriceData);
50
63
  let pnl;
51
64
  if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
52
65
  pnl = baseAssetValue.sub(marketPosition.quoteAssetAmount);
@@ -61,23 +74,6 @@ function calculatePositionPNL(market, marketPosition, withFunding = false) {
61
74
  return pnl;
62
75
  }
63
76
  exports.calculatePositionPNL = calculatePositionPNL;
64
- function calculateSettledPositionPNL(market, marketPosition) {
65
- let pnl = calculatePositionPNL(market, marketPosition);
66
- if (pnl.gt(numericConstants_1.ZERO)) {
67
- try {
68
- pnl = pnl
69
- .mul(new __1.BN(settlement_1.SETTLEMENT_RATIOS[marketPosition.marketIndex.toNumber()]))
70
- .div(settlement_1.SETTLEMENT_RATIO_PRECISION);
71
- }
72
- catch (e) {
73
- console.log(pnl.toString());
74
- console.log(marketPosition.marketIndex.toNumber());
75
- throw e;
76
- }
77
- }
78
- return pnl;
79
- }
80
- exports.calculateSettledPositionPNL = calculateSettledPositionPNL;
81
77
  /**
82
78
  *
83
79
  * @param market
@@ -104,6 +100,10 @@ function calculatePositionFundingPNL(market, marketPosition) {
104
100
  return perPositionFundingRate;
105
101
  }
106
102
  exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
103
+ function positionIsAvailable(position) {
104
+ return position.baseAssetAmount.eq(numericConstants_1.ZERO) && position.openOrders.eq(numericConstants_1.ZERO);
105
+ }
106
+ exports.positionIsAvailable = positionIsAvailable;
107
107
  /**
108
108
  *
109
109
  * @param userPosition
@@ -0,0 +1,22 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '@project-serum/anchor';
3
+ import { AMM } from '../types';
4
+ /**
5
+ * Helper function calculating adjust k cost
6
+ * @param amm
7
+ * @param numerator
8
+ * @param denomenator
9
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
10
+ */
11
+ export declare function calculateAdjustKCost(amm: AMM, numerator: BN, denomenator: BN): BN;
12
+ /**
13
+ * Helper function calculating adjust pegMultiplier (repeg) cost
14
+ *
15
+ * @param amm
16
+ * @param newPeg
17
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
18
+ */
19
+ export declare function calculateRepegCost(amm: AMM, newPeg: BN): BN;
20
+ export declare function calculateBudgetedKBN(x: BN, y: BN, budget: BN, Q: BN, d: BN): [BN, BN];
21
+ export declare function calculateBudgetedK(amm: AMM, cost: BN): [BN, BN];
22
+ export declare function calculateBudgetedPeg(amm: AMM, cost: BN, targetPrice: BN): BN;
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateBudgetedKBN = exports.calculateRepegCost = exports.calculateAdjustKCost = void 0;
4
+ const anchor_1 = require("@project-serum/anchor");
5
+ const assert_1 = require("../assert/assert");
6
+ const numericConstants_1 = require("../constants/numericConstants");
7
+ /**
8
+ * Helper function calculating adjust k cost
9
+ * @param amm
10
+ * @param numerator
11
+ * @param denomenator
12
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
13
+ */
14
+ function calculateAdjustKCost(amm, numerator, denomenator) {
15
+ // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
16
+ const x = amm.baseAssetReserve;
17
+ const y = amm.quoteAssetReserve;
18
+ const d = amm.netBaseAssetAmount;
19
+ const Q = amm.pegMultiplier;
20
+ const quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
21
+ const p = numerator.mul(numericConstants_1.MARK_PRICE_PRECISION).div(denomenator);
22
+ const cost = quoteScale
23
+ .div(x.add(d))
24
+ .sub(quoteScale
25
+ .mul(p)
26
+ .div(numericConstants_1.MARK_PRICE_PRECISION)
27
+ .div(x.mul(p).div(numericConstants_1.MARK_PRICE_PRECISION).add(d)))
28
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
29
+ .div(numericConstants_1.PEG_PRECISION);
30
+ return cost.mul(new anchor_1.BN(-1));
31
+ }
32
+ exports.calculateAdjustKCost = calculateAdjustKCost;
33
+ /**
34
+ * Helper function calculating adjust pegMultiplier (repeg) cost
35
+ *
36
+ * @param amm
37
+ * @param newPeg
38
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
39
+ */
40
+ function calculateRepegCost(amm, newPeg) {
41
+ const dqar = amm.quoteAssetReserve.sub(amm.terminalQuoteAssetReserve);
42
+ const cost = dqar
43
+ .mul(newPeg.sub(amm.pegMultiplier))
44
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
45
+ .div(numericConstants_1.PEG_PRECISION);
46
+ return cost;
47
+ }
48
+ exports.calculateRepegCost = calculateRepegCost;
49
+ function calculateBudgetedKBN(x, y, budget, Q, d) {
50
+ (0, assert_1.assert)(Q.gt(new anchor_1.BN(0)));
51
+ const C = budget.mul(new anchor_1.BN(-1));
52
+ let dSign = new anchor_1.BN(1);
53
+ if (d.lt(new anchor_1.BN(0))) {
54
+ dSign = new anchor_1.BN(-1);
55
+ }
56
+ const pegged_y_d_d = y
57
+ .mul(d)
58
+ .mul(d)
59
+ .mul(Q)
60
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
61
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
62
+ .div(numericConstants_1.PEG_PRECISION);
63
+ const numer1 = pegged_y_d_d;
64
+ const numer2 = C.mul(d)
65
+ .div(numericConstants_1.QUOTE_PRECISION)
66
+ .mul(x.add(d))
67
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
68
+ .mul(dSign);
69
+ const denom1 = C.mul(x)
70
+ .mul(x.add(d))
71
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
72
+ .div(numericConstants_1.QUOTE_PRECISION);
73
+ const denom2 = pegged_y_d_d;
74
+ const numerator = numer1.sub(numer2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
75
+ const denominator = denom1.add(denom2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
76
+ return [numerator, denominator];
77
+ }
78
+ exports.calculateBudgetedKBN = calculateBudgetedKBN;
79
+ function calculateBudgetedK(amm, cost) {
80
+ // wolframalpha.com
81
+ // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
82
+ // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*d*d*Q)
83
+ // numer
84
+ // = y*d*d*Q - Cxd - Cdd
85
+ // = y/x*Q*d*d - Cd - Cd/x
86
+ // = mark - C/d - C/(x)
87
+ // = mark/C - 1/d - 1/x
88
+ // denom
89
+ // = C*x*x + C*x*d + y*d*d*Q
90
+ // = x/d**2 + 1 / d + mark/C
91
+ // todo: assumes k = x * y
92
+ // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
93
+ const x = amm.baseAssetReserve;
94
+ const y = amm.quoteAssetReserve;
95
+ const d = amm.netBaseAssetAmount;
96
+ const Q = amm.pegMultiplier;
97
+ const [numerator, denominator] = calculateBudgetedKBN(x, y, cost, Q, d);
98
+ return [numerator, denominator];
99
+ }
100
+ exports.calculateBudgetedK = calculateBudgetedK;
101
+ function calculateBudgetedPeg(amm, cost, targetPrice) {
102
+ // wolframalpha.com
103
+ // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
104
+ // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
105
+ // todo: assumes k = x * y
106
+ // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
107
+ const targetPeg = targetPrice
108
+ .mul(amm.baseAssetReserve)
109
+ .div(amm.quoteAssetReserve)
110
+ .div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.PEG_PRECISION));
111
+ const k = amm.sqrtK.mul(amm.sqrtK);
112
+ const x = amm.baseAssetReserve;
113
+ const y = amm.quoteAssetReserve;
114
+ const d = amm.netBaseAssetAmount;
115
+ const Q = amm.pegMultiplier;
116
+ const C = cost.mul(new anchor_1.BN(-1));
117
+ const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
118
+ const pegChangeDirection = targetPeg.sub(Q);
119
+ const useTargetPeg = (deltaQuoteAssetReserves.lt(numericConstants_1.ZERO) && pegChangeDirection.gt(numericConstants_1.ZERO)) ||
120
+ (deltaQuoteAssetReserves.gt(numericConstants_1.ZERO) && pegChangeDirection.lt(numericConstants_1.ZERO));
121
+ if (deltaQuoteAssetReserves.eq(numericConstants_1.ZERO) || useTargetPeg) {
122
+ return targetPeg;
123
+ }
124
+ const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
125
+ const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
126
+ return newPeg;
127
+ }
128
+ exports.calculateBudgetedPeg = calculateBudgetedPeg;
@@ -1,7 +1,8 @@
1
1
  /// <reference types="bn.js" />
2
- import { Market, PositionDirection } from '../types';
2
+ import { MarketAccount, PositionDirection } from '../types';
3
3
  import { BN } from '@project-serum/anchor';
4
4
  import { AssetType } from './amm';
5
+ import { OraclePriceData } from '../oracles/types';
5
6
  export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' | 'priceDeltaAsNumber' | 'pctAvg' | 'pctMax' | 'quoteAssetAmount' | 'quoteAssetAmountPeg' | 'acquiredBaseAssetAmount' | 'acquiredQuoteAssetAmount' | 'all';
6
7
  /**
7
8
  * Calculates avg/max slippage (price impact) for candidate trade
@@ -20,7 +21,7 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
20
21
  *
21
22
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
22
23
  */
23
- export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN, BN, BN];
24
+ export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: MarketAccount, inputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [BN, BN, BN, BN];
24
25
  /**
25
26
  * Calculates acquired amounts for trade executed
26
27
  * @param direction
@@ -32,7 +33,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
32
33
  * | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
33
34
  * | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
34
35
  */
35
- export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN];
36
+ export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: MarketAccount, inputAssetType: AssetType, oraclePriceData: OraclePriceData, useSpread?: boolean): [BN, BN];
36
37
  /**
37
38
  * calculateTargetPriceTrade
38
39
  * simple function for finding arbitraging trades
@@ -50,4 +51,4 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
50
51
  * targetPrice => the target price MARK_PRICE_PRECISION
51
52
  * ]
52
53
  */
53
- export declare function calculateTargetPriceTrade(market: Market, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, useSpread?: boolean): [PositionDirection, BN, BN, BN];
54
+ export declare function calculateTargetPriceTrade(market: MarketAccount, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [PositionDirection, BN, BN, BN];
package/lib/math/trade.js CHANGED
@@ -27,32 +27,39 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
27
27
  *
28
28
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
29
29
  */
30
- function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
30
+ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', oraclePriceData, useSpread = true) {
31
31
  let oldPrice;
32
32
  if (useSpread && market.amm.baseSpread > 0) {
33
33
  if ((0, types_2.isVariant)(direction, 'long')) {
34
- oldPrice = (0, market_1.calculateAskPrice)(market);
34
+ oldPrice = (0, market_1.calculateAskPrice)(market, oraclePriceData);
35
35
  }
36
36
  else {
37
- oldPrice = (0, market_1.calculateBidPrice)(market);
37
+ oldPrice = (0, market_1.calculateBidPrice)(market, oraclePriceData);
38
38
  }
39
39
  }
40
40
  else {
41
- oldPrice = (0, market_1.calculateMarkPrice)(market);
41
+ oldPrice = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
42
42
  }
43
43
  if (amount.eq(numericConstants_1.ZERO)) {
44
44
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
45
45
  }
46
- const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, useSpread);
47
- const entryPrice = (0, amm_1.calculatePrice)(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
46
+ const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, oraclePriceData, useSpread);
47
+ const swapDirection = (0, types_2.isVariant)(direction, 'long')
48
+ ? types_1.SwapDirection.REMOVE
49
+ : types_1.SwapDirection.ADD;
50
+ const quoteAssetAmountAcquired = (0, amm_1.calculateQuoteAssetAmountSwapped)(acquiredQuote.abs(), market.amm.pegMultiplier, swapDirection);
51
+ const entryPrice = quoteAssetAmountAcquired
52
+ .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
53
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
54
+ .div(acquiredBase.abs());
48
55
  let amm;
49
56
  if (useSpread && market.amm.baseSpread > 0) {
50
- const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
57
+ const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
51
58
  amm = {
52
59
  baseAssetReserve,
53
60
  quoteAssetReserve,
54
- sqrtK: market.amm.sqrtK,
55
- pegMultiplier: market.amm.pegMultiplier,
61
+ sqrtK: sqrtK,
62
+ pegMultiplier: newPeg,
56
63
  };
57
64
  }
58
65
  else {
@@ -60,10 +67,10 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
60
67
  }
61
68
  const newPrice = (0, amm_1.calculatePrice)(amm.baseAssetReserve.sub(acquiredBase), amm.quoteAssetReserve.sub(acquiredQuote), amm.pegMultiplier);
62
69
  if (direction == types_1.PositionDirection.SHORT) {
63
- (0, assert_1.assert)(newPrice.lt(oldPrice));
70
+ (0, assert_1.assert)(newPrice.lte(oldPrice));
64
71
  }
65
72
  else {
66
- (0, assert_1.assert)(oldPrice.lt(newPrice));
73
+ (0, assert_1.assert)(oldPrice.lte(newPrice));
67
74
  }
68
75
  const pctMaxSlippage = newPrice
69
76
  .sub(oldPrice)
@@ -89,19 +96,19 @@ exports.calculateTradeSlippage = calculateTradeSlippage;
89
96
  * | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
90
97
  * | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
91
98
  */
92
- function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
99
+ function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', oraclePriceData, useSpread = true) {
93
100
  if (amount.eq(numericConstants_1.ZERO)) {
94
101
  return [numericConstants_1.ZERO, numericConstants_1.ZERO];
95
102
  }
96
103
  const swapDirection = (0, amm_1.getSwapDirection)(inputAssetType, direction);
97
104
  let amm;
98
105
  if (useSpread && market.amm.baseSpread > 0) {
99
- const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
106
+ const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
100
107
  amm = {
101
108
  baseAssetReserve,
102
109
  quoteAssetReserve,
103
- sqrtK: market.amm.sqrtK,
104
- pegMultiplier: market.amm.pegMultiplier,
110
+ sqrtK: sqrtK,
111
+ pegMultiplier: newPeg,
105
112
  };
106
113
  }
107
114
  else {
@@ -130,13 +137,13 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
130
137
  * targetPrice => the target price MARK_PRICE_PRECISION
131
138
  * ]
132
139
  */
133
- function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', useSpread = true) {
140
+ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', oraclePriceData, useSpread = true) {
134
141
  (0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
135
142
  (0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
136
143
  (0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
137
- const markPriceBefore = (0, market_1.calculateMarkPrice)(market);
138
- const bidPriceBefore = (0, market_1.calculateBidPrice)(market);
139
- const askPriceBefore = (0, market_1.calculateAskPrice)(market);
144
+ const markPriceBefore = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
145
+ const bidPriceBefore = (0, market_1.calculateBidPrice)(market, oraclePriceData);
146
+ const askPriceBefore = (0, market_1.calculateAskPrice)(market, oraclePriceData);
140
147
  let direction;
141
148
  if (targetPrice.gt(markPriceBefore)) {
142
149
  const priceGap = targetPrice.sub(markPriceBefore);
@@ -154,16 +161,17 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
154
161
  let baseSize;
155
162
  let baseAssetReserveBefore;
156
163
  let quoteAssetReserveBefore;
164
+ let peg = market.amm.pegMultiplier;
157
165
  if (useSpread && market.amm.baseSpread > 0) {
158
- const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
166
+ const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
159
167
  baseAssetReserveBefore = baseAssetReserve;
160
168
  quoteAssetReserveBefore = quoteAssetReserve;
169
+ peg = newPeg;
161
170
  }
162
171
  else {
163
172
  baseAssetReserveBefore = market.amm.baseAssetReserve;
164
173
  quoteAssetReserveBefore = market.amm.quoteAssetReserve;
165
174
  }
166
- const peg = market.amm.pegMultiplier;
167
175
  const invariant = market.amm.sqrtK.mul(market.amm.sqrtK);
168
176
  const k = invariant.mul(numericConstants_1.MARK_PRICE_PRECISION);
169
177
  let baseAssetReserveAfter;