@drift-labs/sdk 0.2.0-master.3 → 0.2.0-master.30

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 (208) hide show
  1. package/README.md +13 -13
  2. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  3. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  4. package/lib/accounts/bulkUserSubscription.js +0 -1
  5. package/lib/accounts/fetch.d.ts +2 -1
  6. package/lib/accounts/fetch.js +9 -1
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +16 -16
  8. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +31 -28
  9. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  10. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  11. package/lib/accounts/types.d.ts +22 -11
  12. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +17 -17
  13. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +37 -35
  14. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  15. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  16. package/lib/addresses/marketAddresses.d.ts +1 -3
  17. package/lib/addresses/pda.d.ts +10 -4
  18. package/lib/addresses/pda.js +51 -14
  19. package/lib/admin.d.ts +34 -22
  20. package/lib/admin.js +182 -73
  21. package/lib/clearingHouse.d.ts +120 -42
  22. package/lib/clearingHouse.js +1505 -254
  23. package/lib/clearingHouseConfig.d.ts +4 -4
  24. package/lib/clearingHouseUser.d.ts +50 -38
  25. package/lib/clearingHouseUser.js +410 -190
  26. package/lib/clearingHouseUserStats.d.ts +18 -0
  27. package/lib/clearingHouseUserStats.js +49 -0
  28. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  29. package/lib/clearingHouseUserStatsConfig.js +2 -0
  30. package/lib/config.d.ts +7 -9
  31. package/lib/config.js +21 -21
  32. package/lib/constants/numericConstants.d.ts +18 -12
  33. package/lib/constants/numericConstants.js +28 -21
  34. package/lib/constants/perpMarkets.d.ts +18 -0
  35. package/lib/constants/{markets.js → perpMarkets.js} +7 -7
  36. package/lib/constants/spotMarkets.d.ts +19 -0
  37. package/lib/constants/spotMarkets.js +53 -0
  38. package/lib/dlob/DLOB.d.ts +73 -0
  39. package/lib/dlob/DLOB.js +553 -0
  40. package/lib/dlob/DLOBNode.d.ts +52 -0
  41. package/lib/dlob/DLOBNode.js +82 -0
  42. package/lib/dlob/NodeList.d.ts +26 -0
  43. package/lib/dlob/NodeList.js +138 -0
  44. package/lib/events/eventList.js +3 -0
  45. package/lib/events/eventSubscriber.d.ts +4 -2
  46. package/lib/events/eventSubscriber.js +16 -9
  47. package/lib/events/fetchLogs.d.ts +10 -1
  48. package/lib/events/fetchLogs.js +27 -7
  49. package/lib/events/pollingLogProvider.d.ts +2 -1
  50. package/lib/events/pollingLogProvider.js +6 -2
  51. package/lib/events/sort.js +8 -11
  52. package/lib/events/types.d.ts +7 -2
  53. package/lib/events/types.js +5 -0
  54. package/lib/examples/makeTradeExample.js +20 -8
  55. package/lib/factory/bigNum.d.ts +1 -0
  56. package/lib/factory/bigNum.js +34 -10
  57. package/lib/idl/clearing_house.json +4313 -1433
  58. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  59. package/lib/index.d.ts +21 -6
  60. package/lib/index.js +25 -6
  61. package/lib/math/amm.d.ts +8 -5
  62. package/lib/math/amm.js +68 -46
  63. package/lib/math/auction.js +4 -1
  64. package/lib/math/conversion.js +1 -1
  65. package/lib/math/funding.d.ts +6 -6
  66. package/lib/math/funding.js +11 -10
  67. package/lib/math/insurance.d.ts +4 -0
  68. package/lib/math/insurance.js +27 -0
  69. package/lib/math/margin.d.ts +11 -0
  70. package/lib/math/margin.js +77 -0
  71. package/lib/math/market.d.ts +14 -9
  72. package/lib/math/market.js +69 -7
  73. package/lib/math/oracles.d.ts +4 -0
  74. package/lib/math/oracles.js +36 -8
  75. package/lib/math/orders.d.ts +6 -2
  76. package/lib/math/orders.js +78 -3
  77. package/lib/math/position.d.ts +21 -13
  78. package/lib/math/position.js +76 -36
  79. package/lib/math/repeg.js +14 -5
  80. package/lib/math/spotBalance.d.ts +22 -0
  81. package/lib/math/spotBalance.js +193 -0
  82. package/lib/math/spotMarket.d.ts +4 -0
  83. package/lib/math/spotMarket.js +8 -0
  84. package/lib/math/spotPosition.d.ts +6 -0
  85. package/lib/math/spotPosition.js +23 -0
  86. package/lib/math/trade.d.ts +10 -10
  87. package/lib/math/trade.js +22 -29
  88. package/lib/oracles/pythClient.js +1 -1
  89. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  90. package/lib/oracles/switchboardClient.js +1 -1
  91. package/lib/orderParams.d.ts +14 -5
  92. package/lib/orderParams.js +12 -92
  93. package/lib/serum/serumSubscriber.d.ts +23 -0
  94. package/lib/serum/serumSubscriber.js +41 -0
  95. package/lib/serum/types.d.ts +11 -0
  96. package/lib/serum/types.js +2 -0
  97. package/lib/slot/SlotSubscriber.d.ts +7 -0
  98. package/lib/slot/SlotSubscriber.js +3 -0
  99. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  100. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  101. package/lib/tx/retryTxSender.d.ts +1 -1
  102. package/lib/tx/retryTxSender.js +13 -4
  103. package/lib/tx/types.d.ts +1 -1
  104. package/lib/tx/utils.js +1 -1
  105. package/lib/types.d.ts +474 -123
  106. package/lib/types.js +99 -5
  107. package/lib/userMap/userMap.d.ts +25 -0
  108. package/lib/userMap/userMap.js +73 -0
  109. package/lib/userMap/userStatsMap.d.ts +19 -0
  110. package/lib/userMap/userStatsMap.js +68 -0
  111. package/lib/util/computeUnits.js +1 -1
  112. package/lib/util/getTokenAddress.d.ts +2 -0
  113. package/lib/util/getTokenAddress.js +9 -0
  114. package/package.json +9 -5
  115. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  116. package/src/accounts/bulkUserSubscription.ts +0 -1
  117. package/src/accounts/fetch.ts +27 -2
  118. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +46 -42
  119. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  120. package/src/accounts/types.ts +31 -11
  121. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +64 -59
  122. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  123. package/src/addresses/marketAddresses.ts +1 -2
  124. package/src/addresses/pda.ts +88 -14
  125. package/src/admin.ts +333 -128
  126. package/src/assert/assert.js +9 -0
  127. package/src/clearingHouse.ts +2464 -458
  128. package/src/clearingHouseConfig.ts +4 -3
  129. package/src/clearingHouseUser.ts +747 -291
  130. package/src/clearingHouseUserStats.ts +75 -0
  131. package/src/clearingHouseUserStatsConfig.ts +18 -0
  132. package/src/config.ts +30 -31
  133. package/src/constants/numericConstants.ts +41 -25
  134. package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
  135. package/src/constants/spotMarkets.ts +72 -0
  136. package/src/dlob/DLOB.ts +868 -0
  137. package/src/dlob/DLOBNode.ts +162 -0
  138. package/src/dlob/NodeList.ts +185 -0
  139. package/src/events/eventList.js +77 -0
  140. package/src/events/eventList.ts +3 -0
  141. package/src/events/eventSubscriber.ts +20 -12
  142. package/src/events/fetchLogs.ts +35 -8
  143. package/src/events/pollingLogProvider.ts +10 -2
  144. package/src/events/sort.ts +11 -15
  145. package/src/events/types.ts +16 -1
  146. package/src/examples/makeTradeExample.js +157 -0
  147. package/src/examples/makeTradeExample.ts +32 -14
  148. package/src/factory/bigNum.ts +42 -13
  149. package/src/idl/clearing_house.json +4313 -1433
  150. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  151. package/src/index.ts +21 -6
  152. package/src/math/amm.ts +136 -66
  153. package/src/math/auction.ts +5 -1
  154. package/src/math/conversion.ts +2 -2
  155. package/src/math/funding.ts +20 -18
  156. package/src/math/insurance.ts +35 -0
  157. package/src/math/margin.ts +127 -0
  158. package/src/math/market.ts +138 -12
  159. package/src/math/oracles.ts +63 -9
  160. package/src/math/orders.ts +138 -4
  161. package/src/math/position.ts +119 -58
  162. package/src/math/repeg.ts +16 -6
  163. package/src/math/spotBalance.ts +316 -0
  164. package/src/math/spotMarket.ts +9 -0
  165. package/src/math/spotPosition.ts +47 -0
  166. package/src/math/trade.ts +43 -49
  167. package/src/oracles/pythClient.ts +2 -2
  168. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  169. package/src/oracles/switchboardClient.ts +2 -2
  170. package/src/orderParams.ts +24 -137
  171. package/src/serum/serumSubscriber.ts +80 -0
  172. package/src/serum/types.ts +13 -0
  173. package/src/slot/SlotSubscriber.ts +11 -1
  174. package/src/token/index.js +38 -0
  175. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  176. package/src/tx/retryTxSender.ts +16 -5
  177. package/src/tx/types.js +2 -0
  178. package/src/tx/types.ts +2 -1
  179. package/src/tx/utils.js +17 -0
  180. package/src/tx/utils.ts +1 -1
  181. package/src/types.ts +477 -125
  182. package/src/userMap/userMap.ts +100 -0
  183. package/src/userMap/userStatsMap.ts +110 -0
  184. package/src/util/computeUnits.js +21 -11
  185. package/src/util/computeUnits.ts +1 -1
  186. package/src/util/getTokenAddress.js +9 -0
  187. package/src/util/getTokenAddress.ts +18 -0
  188. package/src/util/promiseTimeout.js +14 -0
  189. package/src/util/tps.js +27 -0
  190. package/tests/bn/test.ts +12 -3
  191. package/tests/dlob/helpers.ts +374 -0
  192. package/tests/dlob/test.ts +2865 -0
  193. package/lib/constants/banks.d.ts +0 -16
  194. package/lib/constants/banks.js +0 -34
  195. package/lib/constants/markets.d.ts +0 -19
  196. package/lib/math/bankBalance.d.ts +0 -9
  197. package/lib/math/bankBalance.js +0 -75
  198. package/lib/math/state.d.ts +0 -8
  199. package/lib/math/state.js +0 -15
  200. package/lib/orders.d.ts +0 -8
  201. package/lib/orders.js +0 -134
  202. package/src/constants/banks.ts +0 -43
  203. package/src/math/bankBalance.ts +0 -112
  204. package/src/math/state.ts +0 -14
  205. package/src/math/utils.js +0 -27
  206. package/src/math/utils.js.map +0 -1
  207. package/src/orders.ts +0 -244
  208. package/src/util/computeUnits.js.map +0 -1
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.calculateFundingPool = exports.calculateLongShortFundingRateAndLiveTwaps = exports.calculateLongShortFundingRate = exports.calculateEstimatedFundingRate = exports.calculateAllEstimatedFundingRate = void 0;
4
4
  const anchor_1 = require("@project-serum/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ const types_1 = require("../types");
6
7
  const market_1 = require("./market");
7
8
  /**
8
9
  *
@@ -19,7 +20,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
19
20
  const secondsInHour = new anchor_1.BN(3600);
20
21
  const hoursInDay = new anchor_1.BN(24);
21
22
  const ONE = new anchor_1.BN(1);
22
- if (!market.initialized) {
23
+ if ((0, types_1.isVariant)(market.status, 'uninitialized')) {
23
24
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO];
24
25
  }
25
26
  const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
@@ -31,15 +32,15 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
31
32
  const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
32
33
  const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
33
34
  const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
34
- const baseAssetPriceWithMantissa = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
35
+ const baseAssetPriceWithMantissa = (0, market_1.calculateReservePrice)(market, oraclePriceData);
35
36
  const markTwapWithMantissa = markTwapTimeSinceLastUpdate
36
37
  .mul(lastMarkTwapWithMantissa)
37
38
  .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
38
39
  .div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
39
40
  // calculate real-time (predicted) oracle twap
40
41
  // note: oracle twap depends on `when the chord is struck` (market is trade)
41
- const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
42
- const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
42
+ const lastOracleTwapWithMantissa = market.amm.historicalOracleData.lastOraclePriceTwap;
43
+ const lastOraclePriceTwapTs = market.amm.historicalOracleData.lastOraclePriceTwapTs;
43
44
  const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
44
45
  const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
45
46
  const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
@@ -50,11 +51,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
50
51
  const oracleLiveVsTwap = oraclePrice
51
52
  .sub(lastOracleTwapWithMantissa)
52
53
  .abs()
53
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
54
+ .mul(numericConstants_1.PRICE_PRECISION)
54
55
  .mul(new anchor_1.BN(100))
55
56
  .div(lastOracleTwapWithMantissa);
56
57
  // verify pyth live input is within 10% of last twap for live update
57
- if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
58
+ if (oracleLiveVsTwap.lte(numericConstants_1.PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
58
59
  oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
59
60
  .mul(lastOracleTwapWithMantissa)
60
61
  .add(timeSinceLastMarkChange.mul(oraclePrice))
@@ -67,7 +68,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
67
68
  .div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
68
69
  const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
69
70
  const twapSpreadPct = twapSpread
70
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
71
+ .mul(numericConstants_1.PRICE_PRECISION)
71
72
  .mul(new anchor_1.BN(100))
72
73
  .div(shrunkLastOracleTwapwithMantissa);
73
74
  const lowerboundEst = twapSpreadPct
@@ -81,7 +82,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
81
82
  const interpRateQuote = twapSpreadPct
82
83
  .mul(periodAdjustment)
83
84
  .div(hoursInDay)
84
- .div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
85
+ .div(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
85
86
  let feePoolSize = calculateFundingPool(market);
86
87
  if (interpRateQuote.lt(new anchor_1.BN(0))) {
87
88
  feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
@@ -128,11 +129,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
128
129
  // funding smaller flow
129
130
  cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
130
131
  const feePoolTopOff = feePoolSize
131
- .mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
132
+ .mul(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
132
133
  .mul(numericConstants_1.AMM_RESERVE_PRECISION);
133
134
  cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
134
135
  cappedAltEst = cappedAltEst
135
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
136
+ .mul(numericConstants_1.PRICE_PRECISION)
136
137
  .mul(new anchor_1.BN(100))
137
138
  .div(oracleTwapWithMantissa)
138
139
  .mul(periodAdjustment);
@@ -0,0 +1,4 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '../index';
3
+ export declare function stakeAmountToShares(amount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
4
+ export declare function unstakeSharesToAmount(nShares: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unstakeSharesToAmount = exports.stakeAmountToShares = void 0;
4
+ const numericConstants_1 = require("../constants/numericConstants");
5
+ const index_1 = require("../index");
6
+ function stakeAmountToShares(amount, totalIfShares, insuranceFundVaultBalance) {
7
+ let nShares;
8
+ if (insuranceFundVaultBalance.gt(numericConstants_1.ZERO)) {
9
+ nShares = amount.mul(totalIfShares).div(insuranceFundVaultBalance);
10
+ }
11
+ else {
12
+ nShares = amount;
13
+ }
14
+ return nShares;
15
+ }
16
+ exports.stakeAmountToShares = stakeAmountToShares;
17
+ function unstakeSharesToAmount(nShares, totalIfShares, insuranceFundVaultBalance) {
18
+ let amount;
19
+ if (totalIfShares.gt(numericConstants_1.ZERO)) {
20
+ amount = index_1.BN.max(numericConstants_1.ZERO, nShares.mul(insuranceFundVaultBalance).div(totalIfShares));
21
+ }
22
+ else {
23
+ amount = numericConstants_1.ZERO;
24
+ }
25
+ return amount;
26
+ }
27
+ exports.unstakeSharesToAmount = unstakeSharesToAmount;
@@ -0,0 +1,11 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '@project-serum/anchor';
3
+ import { OraclePriceData } from '../oracles/types';
4
+ import { PerpMarketAccount, PerpPosition } from '..';
5
+ export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
6
+ imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
7
+ export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
8
+ imfFactor: BN, assetWeight: BN): BN;
9
+ export declare function calculateOraclePriceForPerpMargin(perpPosition: PerpPosition, market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
10
+ export declare function calculateBaseAssetValueWithOracle(market: PerpMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData): BN;
11
+ export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition): BN;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
4
+ const utils_1 = require("./utils");
5
+ const numericConstants_1 = require("../constants/numericConstants");
6
+ const anchor_1 = require("@project-serum/anchor");
7
+ const assert_1 = require("../assert/assert");
8
+ function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
9
+ imfFactor, liabilityWeight, precision) {
10
+ if (imfFactor.eq(numericConstants_1.ZERO)) {
11
+ return liabilityWeight;
12
+ }
13
+ const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
14
+ const denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
15
+ (0, assert_1.assert)(denom0.gt(numericConstants_1.ZERO));
16
+ const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
17
+ const denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
18
+ (0, assert_1.assert)(denom.gt(numericConstants_1.ZERO));
19
+ const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
20
+ .mul(imfFactor)
21
+ .div(denom) // 1e5
22
+ );
23
+ const maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
24
+ return maxLiabilityWeight;
25
+ }
26
+ exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
27
+ function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
28
+ imfFactor, assetWeight) {
29
+ if (imfFactor.eq(numericConstants_1.ZERO)) {
30
+ return assetWeight;
31
+ }
32
+ const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
33
+ const imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
34
+ const sizeDiscountAssetWeight = imfNumerator
35
+ .mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
36
+ .div(numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(sizeSqrt // 1e5
37
+ .mul(imfFactor)
38
+ .div(new anchor_1.BN(100000)) // 1e5
39
+ ));
40
+ const minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
41
+ return minAssetWeight;
42
+ }
43
+ exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
44
+ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData) {
45
+ const oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
46
+ .mul(oraclePriceData.price)
47
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
48
+ .mul(oraclePriceData.price)
49
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
50
+ let marginPrice;
51
+ if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
52
+ marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
53
+ }
54
+ else {
55
+ marginPrice = oraclePriceData.price.add(oraclePriceOffset);
56
+ }
57
+ return marginPrice;
58
+ }
59
+ exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
60
+ function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData) {
61
+ return perpPosition.baseAssetAmount
62
+ .abs()
63
+ .mul(oraclePriceData.price)
64
+ .div(numericConstants_1.AMM_RESERVE_PRECISION);
65
+ }
66
+ exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
67
+ function calculateWorstCaseBaseAssetAmount(perpPosition) {
68
+ const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
69
+ const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
70
+ if (allBids.abs().gt(allAsks.abs())) {
71
+ return allBids;
72
+ }
73
+ else {
74
+ return allAsks;
75
+ }
76
+ }
77
+ exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
@@ -1,28 +1,33 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@project-serum/anchor';
3
- import { MarketAccount, PositionDirection } from '../types';
3
+ import { PerpMarketAccount, PositionDirection, MarginCategory, SpotMarketAccount } from '../types';
4
4
  import { OraclePriceData } from '../oracles/types';
5
5
  /**
6
6
  * Calculates market mark price
7
7
  *
8
8
  * @param market
9
- * @return markPrice : Precision MARK_PRICE_PRECISION
9
+ * @return markPrice : Precision PRICE_PRECISION
10
10
  */
11
- export declare function calculateMarkPrice(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
11
+ export declare function calculateReservePrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
12
12
  /**
13
13
  * Calculates market bid price
14
14
  *
15
15
  * @param market
16
- * @return bidPrice : Precision MARK_PRICE_PRECISION
16
+ * @return bidPrice : Precision PRICE_PRECISION
17
17
  */
18
- export declare function calculateBidPrice(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
18
+ export declare function calculateBidPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
19
19
  /**
20
20
  * Calculates market ask price
21
21
  *
22
22
  * @param market
23
- * @return bidPrice : Precision MARK_PRICE_PRECISION
23
+ * @return askPrice : Precision PRICE_PRECISION
24
24
  */
25
- export declare function calculateAskPrice(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
26
- export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: MarketAccount): MarketAccount;
27
- export declare function calculateMarkOracleSpread(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
25
+ export declare function calculateAskPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
26
+ export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
27
+ export declare function calculateMarkOracleSpread(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
28
28
  export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
29
+ export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory): number;
30
+ export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount, quoteSpotMarket: SpotMarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory, oraclePriceData: OraclePriceData): BN;
31
+ export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
32
+ export declare function calculateNetUserPnl(perpMarket: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
33
+ export declare function calculateNetUserPnlImbalance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount, oraclePriceData: OraclePriceData): BN;
@@ -1,24 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
3
+ exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
4
+ const anchor_1 = require("@project-serum/anchor");
4
5
  const types_1 = require("../types");
5
6
  const amm_1 = require("./amm");
7
+ const margin_1 = require("./margin");
8
+ const numericConstants_1 = require("../constants/numericConstants");
9
+ const spotBalance_1 = require("./spotBalance");
6
10
  /**
7
11
  * Calculates market mark price
8
12
  *
9
13
  * @param market
10
- * @return markPrice : Precision MARK_PRICE_PRECISION
14
+ * @return markPrice : Precision PRICE_PRECISION
11
15
  */
12
- function calculateMarkPrice(market, oraclePriceData) {
16
+ function calculateReservePrice(market, oraclePriceData) {
13
17
  const newAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
14
18
  return (0, amm_1.calculatePrice)(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
15
19
  }
16
- exports.calculateMarkPrice = calculateMarkPrice;
20
+ exports.calculateReservePrice = calculateReservePrice;
17
21
  /**
18
22
  * Calculates market bid price
19
23
  *
20
24
  * @param market
21
- * @return bidPrice : Precision MARK_PRICE_PRECISION
25
+ * @return bidPrice : Precision PRICE_PRECISION
22
26
  */
23
27
  function calculateBidPrice(market, oraclePriceData) {
24
28
  const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.SHORT, oraclePriceData);
@@ -29,7 +33,7 @@ exports.calculateBidPrice = calculateBidPrice;
29
33
  * Calculates market ask price
30
34
  *
31
35
  * @param market
32
- * @return bidPrice : Precision MARK_PRICE_PRECISION
36
+ * @return askPrice : Precision PRICE_PRECISION
33
37
  */
34
38
  function calculateAskPrice(market, oraclePriceData) {
35
39
  const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.LONG, oraclePriceData);
@@ -47,7 +51,7 @@ function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
47
51
  }
48
52
  exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
49
53
  function calculateMarkOracleSpread(market, oraclePriceData) {
50
- const markPrice = calculateMarkPrice(market, oraclePriceData);
54
+ const markPrice = calculateReservePrice(market, oraclePriceData);
51
55
  return calculateOracleSpread(markPrice, oraclePriceData);
52
56
  }
53
57
  exports.calculateMarkOracleSpread = calculateMarkOracleSpread;
@@ -55,3 +59,61 @@ function calculateOracleSpread(price, oraclePriceData) {
55
59
  return price.sub(oraclePriceData.price);
56
60
  }
57
61
  exports.calculateOracleSpread = calculateOracleSpread;
62
+ function calculateMarketMarginRatio(market, size, marginCategory) {
63
+ let marginRatio;
64
+ switch (marginCategory) {
65
+ case 'Initial':
66
+ marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
67
+ break;
68
+ case 'Maintenance':
69
+ marginRatio = market.marginRatioMaintenance;
70
+ break;
71
+ }
72
+ return marginRatio;
73
+ }
74
+ exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
75
+ function calculateUnrealizedAssetWeight(market, quoteSpotMarket, unrealizedPnl, marginCategory, oraclePriceData) {
76
+ let assetWeight;
77
+ switch (marginCategory) {
78
+ case 'Initial':
79
+ assetWeight = new anchor_1.BN(market.unrealizedInitialAssetWeight);
80
+ if (market.unrealizedMaxImbalance.gt(numericConstants_1.ZERO)) {
81
+ const netUnsettledPnl = calculateNetUserPnlImbalance(market, quoteSpotMarket, oraclePriceData);
82
+ if (netUnsettledPnl.gt(market.unrealizedMaxImbalance)) {
83
+ assetWeight = assetWeight
84
+ .mul(market.unrealizedMaxImbalance)
85
+ .div(netUnsettledPnl);
86
+ }
87
+ }
88
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedImfFactor, assetWeight);
89
+ break;
90
+ case 'Maintenance':
91
+ assetWeight = new anchor_1.BN(market.unrealizedMaintenanceAssetWeight);
92
+ break;
93
+ }
94
+ return assetWeight;
95
+ }
96
+ exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
97
+ function calculateMarketAvailablePNL(perpMarket, spotMarket) {
98
+ return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.balance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
99
+ }
100
+ exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
101
+ function calculateNetUserPnl(perpMarket, oraclePriceData) {
102
+ const netUserPositionValue = perpMarket.amm.netBaseAssetAmount
103
+ .mul(oraclePriceData.price)
104
+ .div(numericConstants_1.BASE_PRECISION)
105
+ .div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
106
+ const netUserCostBasis = perpMarket.amm.quoteAssetAmountLong
107
+ .add(perpMarket.amm.quoteAssetAmountShort)
108
+ .sub(perpMarket.amm.cumulativeSocialLoss);
109
+ const netUserPnl = netUserPositionValue.add(netUserCostBasis);
110
+ return netUserPnl;
111
+ }
112
+ exports.calculateNetUserPnl = calculateNetUserPnl;
113
+ function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
114
+ const netUserPnl = calculateNetUserPnl(perpMarket, oraclePriceData);
115
+ const pnlPool = (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.balance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
116
+ const imbalance = netUserPnl.sub(pnlPool);
117
+ return imbalance;
118
+ }
119
+ exports.calculateNetUserPnlImbalance = calculateNetUserPnlImbalance;
@@ -1,3 +1,7 @@
1
+ /// <reference types="bn.js" />
1
2
  import { AMM, OracleGuardRails } from '../types';
2
3
  import { OraclePriceData } from '../oracles/types';
4
+ import { BN, PerpMarketAccount } from '../index';
5
+ export declare function oraclePriceBands(market: PerpMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
3
6
  export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
7
+ export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;
@@ -1,22 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isOracleValid = void 0;
3
+ exports.isOracleTooDivergent = exports.isOracleValid = exports.oraclePriceBands = void 0;
4
4
  const numericConstants_1 = require("../constants/numericConstants");
5
5
  const index_1 = require("../index");
6
+ const assert_1 = require("../assert/assert");
7
+ function oraclePriceBands(market, oraclePriceData) {
8
+ const maxPercentDiff = market.marginRatioInitial - market.marginRatioMaintenance;
9
+ const offset = oraclePriceData.price
10
+ .mul(new index_1.BN(maxPercentDiff))
11
+ .div(numericConstants_1.MARGIN_PRECISION);
12
+ (0, assert_1.assert)(offset.gt(numericConstants_1.ZERO));
13
+ return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
14
+ }
15
+ exports.oraclePriceBands = oraclePriceBands;
6
16
  function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
7
- const isOraclePriceNonPositive = oraclePriceData.price.lt(numericConstants_1.ZERO);
17
+ const isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
8
18
  const isOraclePriceTooVolatile = oraclePriceData.price
9
- .div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
19
+ .div(index_1.BN.max(numericConstants_1.ONE, amm.historicalOracleData.lastOraclePriceTwap))
10
20
  .gt(oracleGuardRails.validity.tooVolatileRatio) ||
11
- amm.lastOraclePriceTwap
21
+ amm.historicalOracleData.lastOraclePriceTwap
12
22
  .div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
13
23
  .gt(oracleGuardRails.validity.tooVolatileRatio);
14
- const isConfidenceTooLarge = oraclePriceData.price
15
- .div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
16
- .lt(oracleGuardRails.validity.confidenceIntervalMaxSize);
24
+ const isConfidenceTooLarge = new index_1.BN(amm.baseSpread)
25
+ .add(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
26
+ .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
27
+ .div(oraclePriceData.price)
28
+ .gt(new index_1.BN(amm.maxSpread));
17
29
  const oracleIsStale = oraclePriceData.slot
18
30
  .sub(new index_1.BN(slot))
19
- .gt(oracleGuardRails.validity.slotsBeforeStale);
31
+ .gt(oracleGuardRails.validity.slotsBeforeStaleForAmm);
20
32
  return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
21
33
  oracleIsStale ||
22
34
  isOraclePriceNonPositive ||
@@ -24,3 +36,19 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
24
36
  isConfidenceTooLarge);
25
37
  }
26
38
  exports.isOracleValid = isOracleValid;
39
+ function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
40
+ const sinceLastUpdate = now.sub(amm.historicalOracleData.lastOraclePriceTwapTs);
41
+ const sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
42
+ const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5min
43
+ .mul(sinceStart)
44
+ .add(oraclePriceData.price)
45
+ .mul(sinceLastUpdate)
46
+ .div(sinceStart.add(sinceLastUpdate));
47
+ const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
48
+ const oracleSpreadPct = oracleSpread.mul(numericConstants_1.PRICE_PRECISION).div(oracleTwap5min);
49
+ const tooDivergent = oracleSpreadPct
50
+ .abs()
51
+ .gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
52
+ return tooDivergent;
53
+ }
54
+ exports.isOracleTooDivergent = isOracleTooDivergent;
@@ -1,10 +1,14 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { ClearingHouseUser } from '../clearingHouseUser';
3
- import { Order } from '../types';
3
+ import { PerpMarketAccount, Order } from '../types';
4
4
  import { BN } from '@project-serum/anchor';
5
5
  import { OraclePriceData } from '../oracles/types';
6
6
  export declare function isOrderRiskIncreasing(user: ClearingHouseUser, order: Order): boolean;
7
7
  export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouseUser, order: Order): boolean;
8
8
  export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
9
9
  export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
10
- export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number): BN;
10
+ export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number, perpMarket?: PerpMarketAccount): BN;
11
+ export declare function isFillableByVAMM(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): boolean;
12
+ export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
13
+ export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, market: PerpMarketAccount, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
14
+ export declare function isOrderExpired(order: Order, slot: number): boolean;
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
3
+ exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = 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");
6
7
  const auction_1 = require("./auction");
8
+ const market_1 = require("./market");
9
+ const amm_1 = require("./amm");
7
10
  function isOrderRiskIncreasing(user, order) {
8
11
  if ((0, types_1.isVariant)(order.status, 'init')) {
9
12
  return false;
@@ -77,13 +80,42 @@ function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
77
80
  return baseAssetAmount.sub(remainder);
78
81
  }
79
82
  exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
80
- function getLimitPrice(order, oraclePriceData, slot) {
83
+ function getLimitPrice(order, oraclePriceData, slot, perpMarket) {
81
84
  let limitPrice;
82
85
  if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
83
86
  limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
84
87
  }
85
88
  else if ((0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
86
- limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
89
+ if (!(0, auction_1.isAuctionComplete)(order, slot)) {
90
+ limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
91
+ }
92
+ else if (!order.price.eq(numericConstants_1.ZERO)) {
93
+ limitPrice = order.price;
94
+ }
95
+ else {
96
+ if (perpMarket) {
97
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
98
+ const askPrice = (0, market_1.calculateAskPrice)(perpMarket, oraclePriceData);
99
+ const delta = askPrice.div(new anchor_1.BN(perpMarket.amm.maxSlippageRatio));
100
+ limitPrice = askPrice.add(delta);
101
+ }
102
+ else {
103
+ const bidPrice = (0, market_1.calculateBidPrice)(perpMarket, oraclePriceData);
104
+ const delta = bidPrice.div(new anchor_1.BN(perpMarket.amm.maxSlippageRatio));
105
+ limitPrice = bidPrice.sub(delta);
106
+ }
107
+ }
108
+ else {
109
+ // check oracle validity?
110
+ const oraclePrice1Pct = oraclePriceData.price.div(new anchor_1.BN(100));
111
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
112
+ limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
113
+ }
114
+ else {
115
+ limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
116
+ }
117
+ }
118
+ }
87
119
  }
88
120
  else {
89
121
  limitPrice = order.price;
@@ -91,3 +123,46 @@ function getLimitPrice(order, oraclePriceData, slot) {
91
123
  return limitPrice;
92
124
  }
93
125
  exports.getLimitPrice = getLimitPrice;
126
+ function isFillableByVAMM(order, market, oraclePriceData, slot) {
127
+ return (((0, auction_1.isAuctionComplete)(order, slot) &&
128
+ !calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
129
+ isOrderExpired(order, slot));
130
+ }
131
+ exports.isFillableByVAMM = isFillableByVAMM;
132
+ function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot) {
133
+ if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) &&
134
+ order.triggered === false) {
135
+ return numericConstants_1.ZERO;
136
+ }
137
+ const limitPrice = getLimitPrice(order, oraclePriceData, slot, market);
138
+ const baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData);
139
+ const maxBaseAssetAmount = (0, amm_1.calculateMaxBaseAssetAmountFillable)(market.amm, order.direction);
140
+ return anchor_1.BN.min(maxBaseAssetAmount, baseAssetAmount);
141
+ }
142
+ exports.calculateBaseAssetAmountForAmmToFulfill = calculateBaseAssetAmountForAmmToFulfill;
143
+ function calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData) {
144
+ const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
145
+ const baseAssetAmount = standardizeBaseAssetAmount(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
146
+ // Check that directions are the same
147
+ const sameDirection = isSameDirection(direction, order.direction);
148
+ if (!sameDirection) {
149
+ return numericConstants_1.ZERO;
150
+ }
151
+ return baseAssetAmount.gt(order.baseAssetAmount)
152
+ ? order.baseAssetAmount
153
+ : baseAssetAmount;
154
+ }
155
+ exports.calculateBaseAssetAmountToFillUpToLimitPrice = calculateBaseAssetAmountToFillUpToLimitPrice;
156
+ function isSameDirection(firstDirection, secondDirection) {
157
+ return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
158
+ ((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
159
+ }
160
+ function isOrderExpired(order, slot) {
161
+ if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) ||
162
+ !(0, types_1.isVariant)(order.status, 'open') ||
163
+ order.timeInForce === 0) {
164
+ return false;
165
+ }
166
+ return new anchor_1.BN(slot).sub(order.slot).gt(new anchor_1.BN(order.timeInForce));
167
+ }
168
+ exports.isOrderExpired = isOrderExpired;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
- import { BN } from '../';
2
+ import { BN, SpotMarketAccount } from '../';
3
3
  import { OraclePriceData } from '../oracles/types';
4
- import { MarketAccount, PositionDirection, UserPosition } from '../types';
4
+ import { PerpMarketAccount, PositionDirection, PerpPosition } from '../types';
5
5
  /**
6
6
  * calculateBaseAssetValue
7
7
  * = market value of closing entire position
@@ -10,30 +10,38 @@ import { MarketAccount, PositionDirection, UserPosition } from '../types';
10
10
  * @param oraclePriceData
11
11
  * @returns Base Asset Value. : Precision QUOTE_PRECISION
12
12
  */
13
- export declare function calculateBaseAssetValue(market: MarketAccount, userPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
13
+ export declare function calculateBaseAssetValue(market: PerpMarketAccount, userPosition: PerpPosition, oraclePriceData: OraclePriceData, useSpread?: boolean, skipUpdate?: boolean): BN;
14
14
  /**
15
15
  * calculatePositionPNL
16
16
  * = BaseAssetAmount * (Avg Exit Price - Avg Entry Price)
17
17
  * @param market
18
- * @param marketPosition
18
+ * @param PerpPosition
19
19
  * @param withFunding (adds unrealized funding payment pnl to result)
20
+ * @param oraclePriceData
20
21
  * @returns BaseAssetAmount : Precision QUOTE_PRECISION
21
22
  */
22
- export declare function calculatePositionPNL(market: MarketAccount, marketPosition: UserPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
23
+ export declare function calculatePositionPNL(market: PerpMarketAccount, perpPosition: PerpPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
24
+ export declare function calculateClaimablePnl(market: PerpMarketAccount, spotMarket: SpotMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData): BN;
23
25
  /**
24
26
  *
25
27
  * @param market
26
- * @param marketPosition
28
+ * @param PerpPosition
27
29
  * @returns // TODO-PRECISION
28
30
  */
29
- export declare function calculatePositionFundingPNL(market: MarketAccount, marketPosition: UserPosition): BN;
30
- export declare function positionIsAvailable(position: UserPosition): boolean;
31
+ export declare function calculatePositionFundingPNL(market: PerpMarketAccount, perpPosition: PerpPosition): BN;
32
+ export declare function positionIsAvailable(position: PerpPosition): boolean;
33
+ /**
34
+ *
35
+ * @param userPosition
36
+ * @returns Precision: PRICE_PRECISION (10^10)
37
+ */
38
+ export declare function calculateEntryPrice(userPosition: PerpPosition): BN;
31
39
  /**
32
40
  *
33
41
  * @param userPosition
34
- * @returns Precision: MARK_PRICE_PRECISION (10^10)
42
+ * @returns Precision: PRICE_PRECISION (10^10)
35
43
  */
36
- export declare function calculateEntryPrice(userPosition: UserPosition): BN;
37
- export declare function findDirectionToClose(userPosition: UserPosition): PositionDirection;
38
- export declare function positionCurrentDirection(userPosition: UserPosition): PositionDirection;
39
- export declare function isEmptyPosition(userPosition: UserPosition): boolean;
44
+ export declare function calculateCostBasis(userPosition: PerpPosition): BN;
45
+ export declare function findDirectionToClose(userPosition: PerpPosition): PositionDirection;
46
+ export declare function positionCurrentDirection(userPosition: PerpPosition): PositionDirection;
47
+ export declare function isEmptyPosition(userPosition: PerpPosition): boolean;