@drift-labs/sdk 0.1.6 → 0.1.10

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 (78) hide show
  1. package/.eslintrc.json +36 -0
  2. package/.prettierignore +1 -0
  3. package/.prettierrc.js +9 -0
  4. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts +1 -0
  5. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +1 -0
  6. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +1 -0
  7. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts.map +1 -0
  8. package/lib/accounts/defaultUserAccountSubscriber.d.ts +1 -0
  9. package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +1 -0
  10. package/lib/accounts/types.d.ts +1 -0
  11. package/lib/accounts/types.d.ts.map +1 -0
  12. package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -0
  13. package/lib/accounts/webSocketAccountSubscriber.d.ts.map +1 -0
  14. package/lib/addresses.d.ts +1 -0
  15. package/lib/addresses.d.ts.map +1 -0
  16. package/lib/admin.d.ts +2 -1
  17. package/lib/admin.d.ts.map +1 -0
  18. package/lib/admin.js +2 -2
  19. package/lib/assert/assert.d.ts +1 -0
  20. package/lib/assert/assert.d.ts.map +1 -0
  21. package/lib/clearingHouse.d.ts +1 -0
  22. package/lib/clearingHouse.d.ts.map +1 -0
  23. package/lib/clearingHouseUser.d.ts +2 -1
  24. package/lib/clearingHouseUser.d.ts.map +1 -0
  25. package/lib/clearingHouseUser.js +20 -3
  26. package/lib/config.d.ts +1 -0
  27. package/lib/config.d.ts.map +1 -0
  28. package/lib/config.js +1 -1
  29. package/lib/constants/markets.d.ts +1 -0
  30. package/lib/constants/markets.d.ts.map +1 -0
  31. package/lib/constants/markets.js +28 -21
  32. package/lib/constants/numericConstants.d.ts +1 -0
  33. package/lib/constants/numericConstants.d.ts.map +1 -0
  34. package/lib/examples/makeTradeExample.d.ts +1 -0
  35. package/lib/examples/makeTradeExample.d.ts.map +1 -0
  36. package/lib/idl/clearing_house.json +39 -30
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.d.ts.map +1 -0
  39. package/lib/math/amm.d.ts +1 -0
  40. package/lib/math/amm.d.ts.map +1 -0
  41. package/lib/math/conversion.d.ts +1 -0
  42. package/lib/math/conversion.d.ts.map +1 -0
  43. package/lib/math/funding.d.ts +34 -1
  44. package/lib/math/funding.d.ts.map +1 -0
  45. package/lib/math/funding.js +152 -15
  46. package/lib/math/market.d.ts +1 -0
  47. package/lib/math/market.d.ts.map +1 -0
  48. package/lib/math/position.d.ts +1 -0
  49. package/lib/math/position.d.ts.map +1 -0
  50. package/lib/math/trade.d.ts +5 -3
  51. package/lib/math/trade.d.ts.map +1 -0
  52. package/lib/math/trade.js +5 -4
  53. package/lib/math/utils.d.ts +1 -0
  54. package/lib/math/utils.d.ts.map +1 -0
  55. package/lib/mockUSDCFaucet.d.ts +1 -0
  56. package/lib/mockUSDCFaucet.d.ts.map +1 -0
  57. package/lib/pythClient.d.ts +1 -0
  58. package/lib/pythClient.d.ts.map +1 -0
  59. package/lib/tx/defaultTxSender.d.ts +1 -0
  60. package/lib/tx/defaultTxSender.d.ts.map +1 -0
  61. package/lib/tx/types.d.ts +1 -0
  62. package/lib/tx/types.d.ts.map +1 -0
  63. package/lib/tx/utils.d.ts +1 -0
  64. package/lib/tx/utils.d.ts.map +1 -0
  65. package/lib/types.d.ts +11 -1
  66. package/lib/types.d.ts.map +1 -0
  67. package/package.json +12 -2
  68. package/src/admin.ts +4 -4
  69. package/src/clearingHouse.ts +12 -12
  70. package/src/clearingHouseUser.ts +27 -4
  71. package/src/config.ts +1 -2
  72. package/src/constants/markets.ts +28 -21
  73. package/src/idl/clearing_house.json +39 -30
  74. package/src/math/funding.ts +189 -29
  75. package/src/math/position.ts +3 -3
  76. package/src/math/trade.ts +14 -8
  77. package/src/types.ts +10 -1
  78. package/tsconfig.json +2 -1
@@ -16,25 +16,32 @@ export const Markets: Market[] = [
16
16
  devnetPythOracle: 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix',
17
17
  mainnetPythOracle: 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG',
18
18
  },
19
- // {
20
- // symbol: 'BTC-PERP',
21
- // baseAssetSymbol: 'BTC',
22
- // marketIndex: new BN(1),
23
- // devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
24
- // mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
25
- // },
26
- // {
27
- // symbol: 'ETH-PERP',
28
- // baseAssetSymbol: 'ETH',
29
- // marketIndex: new BN(2),
30
- // devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
31
- // mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
32
- // },
33
- // {
34
- // symbol: 'COPE-PERP',
35
- // baseAssetSymbol: 'COPE',
36
- // marketIndex: new BN(3),
37
- // devnetPythOracle: 'BAXDJUXtz6P5ARhHH1aPwgv4WENzHwzyhmLYK4daFwiM',
38
- // mainnetPythOracle: '9xYBiDWYsh2fHzpsz3aaCnNHCKWBNtfEDLtU6kS4aFD9',
39
- // },
19
+ {
20
+ symbol: 'BTC-PERP',
21
+ baseAssetSymbol: 'BTC',
22
+ marketIndex: new BN(1),
23
+ devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
24
+ mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
25
+ },
26
+ {
27
+ symbol: 'ETH-PERP',
28
+ baseAssetSymbol: 'ETH',
29
+ marketIndex: new BN(2),
30
+ devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
31
+ mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
32
+ },
33
+ {
34
+ symbol: 'LUNA-PERP',
35
+ baseAssetSymbol: 'LUNA',
36
+ marketIndex: new BN(3),
37
+ devnetPythOracle: '8PugCXTAHLM9kfLSQWe2njE5pzAgUdpPk3Nx5zSm7BD3',
38
+ mainnetPythOracle: '5bmWuR1dgP4avtGYMNKLuxumZTVKGgoN2BCMXWDNL9nY',
39
+ },
40
+ {
41
+ symbol: 'AVAX-PERP',
42
+ baseAssetSymbol: 'AVAX',
43
+ marketIndex: new BN(4),
44
+ devnetPythOracle: 'FVb5h1VmHPfVb1RfqZckchq18GxRv4iKt8T4eVTQAqdz',
45
+ mainnetPythOracle: 'Ax9ujW5B9oqcv59N8m6f1BpTBq2rGeGaBcpKjC5UYsXU',
46
+ },
40
47
  ];
@@ -1724,6 +1724,34 @@
1724
1724
  }
1725
1725
  ],
1726
1726
  "types": [
1727
+ {
1728
+ "name": "InitializeUserOptionalAccounts",
1729
+ "type": {
1730
+ "kind": "struct",
1731
+ "fields": [
1732
+ {
1733
+ "name": "whitelistToken",
1734
+ "type": "bool"
1735
+ }
1736
+ ]
1737
+ }
1738
+ },
1739
+ {
1740
+ "name": "ManagePositionOptionalAccounts",
1741
+ "type": {
1742
+ "kind": "struct",
1743
+ "fields": [
1744
+ {
1745
+ "name": "discountToken",
1746
+ "type": "bool"
1747
+ },
1748
+ {
1749
+ "name": "referrer",
1750
+ "type": "bool"
1751
+ }
1752
+ ]
1753
+ }
1754
+ },
1727
1755
  {
1728
1756
  "name": "CurveRecord",
1729
1757
  "type": {
@@ -1938,34 +1966,6 @@
1938
1966
  ]
1939
1967
  }
1940
1968
  },
1941
- {
1942
- "name": "InitializeUserOptionalAccounts",
1943
- "type": {
1944
- "kind": "struct",
1945
- "fields": [
1946
- {
1947
- "name": "whitelistToken",
1948
- "type": "bool"
1949
- }
1950
- ]
1951
- }
1952
- },
1953
- {
1954
- "name": "ManagePositionOptionalAccounts",
1955
- "type": {
1956
- "kind": "struct",
1957
- "fields": [
1958
- {
1959
- "name": "discountToken",
1960
- "type": "bool"
1961
- },
1962
- {
1963
- "name": "referrer",
1964
- "type": "bool"
1965
- }
1966
- ]
1967
- }
1968
- },
1969
1969
  {
1970
1970
  "name": "LiquidationRecord",
1971
1971
  "type": {
@@ -2140,7 +2140,7 @@
2140
2140
  "type": "i64"
2141
2141
  },
2142
2142
  {
2143
- "name": "lastOracleMarkSpreadTwap",
2143
+ "name": "lastOraclePriceTwap",
2144
2144
  "type": "i128"
2145
2145
  },
2146
2146
  {
@@ -2175,9 +2175,13 @@
2175
2175
  "name": "minimumTradeSize",
2176
2176
  "type": "u128"
2177
2177
  },
2178
+ {
2179
+ "name": "lastOraclePriceTwapTs",
2180
+ "type": "i64"
2181
+ },
2178
2182
  {
2179
2183
  "name": "padding0",
2180
- "type": "u128"
2184
+ "type": "u64"
2181
2185
  },
2182
2186
  {
2183
2187
  "name": "padding1",
@@ -2757,6 +2761,11 @@
2757
2761
  "code": 337,
2758
2762
  "name": "InvalidFundingProfitability",
2759
2763
  "msg": "AMM funding out of bounds pnl"
2764
+ },
2765
+ {
2766
+ "code": 338,
2767
+ "name": "CastingFailure",
2768
+ "msg": "Casting Failure"
2760
2769
  }
2761
2770
  ]
2762
2771
  }
@@ -1,23 +1,26 @@
1
1
  import { BN } from '@project-serum/anchor';
2
+ import {
3
+ AMM_RESERVE_PRECISION,
4
+ MARK_PRICE_PRECISION,
5
+ QUOTE_PRECISION,
6
+ ZERO,
7
+ } from '../constants/numericConstants';
2
8
  import { PythClient } from '../pythClient';
3
- import { MARK_PRICE_PRECISION } from '../constants/numericConstants';
4
9
  import { Market } from '../types';
5
10
  import { calculateMarkPrice } from './market';
6
11
 
7
12
  /**
8
- *
9
- * @param market
10
- * @param pythClient
11
- * @param periodAdjustment
12
- * @param estimationMethod
13
+ *
14
+ * @param market
15
+ * @param pythClient
16
+ * @param periodAdjustment
13
17
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
14
18
  */
15
- export async function calculateEstimatedFundingRate(
19
+ export async function calculateAllEstimatedFundingRate(
16
20
  market: Market,
17
21
  pythClient: PythClient,
18
- periodAdjustment: BN = new BN(1),
19
- estimationMethod: 'interpolated' | 'lowerbound'
20
- ): Promise<BN> {
22
+ periodAdjustment: BN = new BN(1)
23
+ ): Promise<[BN, BN, BN, BN, BN]> {
21
24
  // periodAdjustment
22
25
  // 1: hourly
23
26
  // 24: daily
@@ -26,34 +29,43 @@ export async function calculateEstimatedFundingRate(
26
29
  const hoursInDay = new BN(24);
27
30
 
28
31
  if (!market.initialized) {
29
- return new BN(0);
32
+ return [ZERO, ZERO, ZERO, ZERO, ZERO];
30
33
  }
31
34
 
32
35
  const payFreq = new BN(market.amm.fundingPeriod);
33
36
 
34
- const oraclePriceData = await pythClient.getPriceData(market.amm.oracle);
35
- const oracleTwapWithMantissa = new BN(
36
- oraclePriceData.twap.value * MARK_PRICE_PRECISION.toNumber()
37
- );
38
-
37
+ // todo: sufficiently differs from blockchain timestamp?
39
38
  const now = new BN((Date.now() / 1000).toFixed(0));
40
39
  const timeSinceLastUpdate = now.sub(market.amm.lastFundingRateTs);
41
40
 
41
+ // calculate real-time mark twap
42
42
  const lastMarkTwapWithMantissa = market.amm.lastMarkPriceTwap;
43
43
  const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
44
44
 
45
45
  const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
46
- const markTwapTimeSinceLastUpdate = lastMarkPriceTwapTs.sub(
47
- market.amm.lastFundingRateTs
48
- );
49
-
46
+ const markTwapTimeSinceLastUpdate = BN.max(secondsInHour, secondsInHour.sub(timeSinceLastMarkChange));
50
47
  const baseAssetPriceWithMantissa = calculateMarkPrice(market);
51
-
48
+
52
49
  const markTwapWithMantissa = markTwapTimeSinceLastUpdate
53
50
  .mul(lastMarkTwapWithMantissa)
54
51
  .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
55
52
  .div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
56
53
 
54
+ // calculate real-time (predicted) oracle twap
55
+ // note: oracle twap depends on `when the chord is struck` (market is trade)
56
+ const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
57
+ const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
58
+
59
+ const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
60
+ const oracleTwapTimeSinceLastUpdate = BN.max(secondsInHour, secondsInHour.sub(timeSinceLastOracleTwapUpdate));
61
+ const oraclePriceData = await pythClient.getPriceData(market.amm.oracle);
62
+ const oraclePriceStableWithMantissa = new BN(((oraclePriceData.price + oraclePriceData.previousPrice)/2) * MARK_PRICE_PRECISION.toNumber());
63
+
64
+ const oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
65
+ .mul(lastOracleTwapWithMantissa)
66
+ .add(timeSinceLastMarkChange.mul(oraclePriceStableWithMantissa))
67
+ .div(timeSinceLastOracleTwapUpdate.add(oracleTwapTimeSinceLastUpdate));
68
+
57
69
  const twapSpread = markTwapWithMantissa.sub(oracleTwapWithMantissa);
58
70
 
59
71
  const twapSpreadPct = twapSpread
@@ -61,16 +73,164 @@ export async function calculateEstimatedFundingRate(
61
73
  .mul(new BN(100))
62
74
  .div(oracleTwapWithMantissa);
63
75
 
64
- if (estimationMethod == 'lowerbound') {
65
- //assuming remaining funding period has no gap
66
- return twapSpreadPct
67
- .mul(payFreq)
68
- .mul(BN.min(secondsInHour, timeSinceLastUpdate))
76
+ const lowerboundEst = twapSpreadPct
77
+ .mul(payFreq)
78
+ .mul(BN.min(secondsInHour, timeSinceLastUpdate))
79
+ .mul(periodAdjustment)
80
+ .div(secondsInHour)
81
+ .div(secondsInHour)
82
+ .div(hoursInDay);
83
+
84
+ const interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
85
+
86
+ const interpRateQuote = twapSpreadPct
87
+ .mul(periodAdjustment)
88
+ .div(hoursInDay)
89
+ .div(MARK_PRICE_PRECISION.div(QUOTE_PRECISION));
90
+ let feePoolSize = calculateFundingPool(market);
91
+ if (interpRateQuote.lt(new BN(0))) {
92
+ feePoolSize = feePoolSize.mul(new BN(-1));
93
+ }
94
+
95
+ let cappedAltEst: BN;
96
+ let largerSide: BN;
97
+ let smallerSide: BN;
98
+ if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
99
+ largerSide = market.baseAssetAmountLong.abs();
100
+ smallerSide = market.baseAssetAmountShort.abs();
101
+ if(twapSpread.gt(new BN(0))) {
102
+ return [markTwapWithMantissa, oracleTwapWithMantissa, lowerboundEst, interpEst, interpEst];
103
+ }
104
+ } else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
105
+ largerSide = market.baseAssetAmountShort.abs();
106
+ smallerSide = market.baseAssetAmountLong.abs();
107
+ if(twapSpread.lt(new BN(0))){
108
+ return [markTwapWithMantissa, oracleTwapWithMantissa, lowerboundEst, interpEst, interpEst];
109
+ }
110
+ } else{
111
+ return [markTwapWithMantissa, oracleTwapWithMantissa, lowerboundEst, interpEst, interpEst];
112
+ }
113
+
114
+ if (largerSide.gt(ZERO)) {
115
+ cappedAltEst = smallerSide.mul(twapSpread).div(largerSide);
116
+
117
+ const feePoolTopOff = feePoolSize
118
+ .mul(MARK_PRICE_PRECISION.div(QUOTE_PRECISION))
119
+ .mul(AMM_RESERVE_PRECISION)
120
+ .div(largerSide);
121
+
122
+ cappedAltEst = cappedAltEst.add(feePoolTopOff);
123
+
124
+ cappedAltEst = cappedAltEst
125
+ .mul(MARK_PRICE_PRECISION)
126
+ .mul(new BN(100))
127
+ .div(oracleTwapWithMantissa)
69
128
  .mul(periodAdjustment)
70
- .div(secondsInHour)
71
- .div(secondsInHour)
72
129
  .div(hoursInDay);
130
+ if (cappedAltEst.abs().gt(interpEst.abs())) {
131
+ cappedAltEst = interpEst;
132
+ }
73
133
  } else {
74
- return twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
134
+ cappedAltEst = interpEst;
75
135
  }
136
+
137
+
138
+ return [markTwapWithMantissa, oracleTwapWithMantissa, lowerboundEst, cappedAltEst, interpEst];
139
+ }
140
+
141
+ /**
142
+ *
143
+ * @param market
144
+ * @param pythClient
145
+ * @param periodAdjustment
146
+ * @param estimationMethod
147
+ * @returns Estimated funding rate. : Precision //TODO-PRECISION
148
+ */
149
+ export async function calculateEstimatedFundingRate(
150
+ market: Market,
151
+ pythClient: PythClient,
152
+ periodAdjustment: BN = new BN(1),
153
+ estimationMethod: 'interpolated' | 'lowerbound' | 'capped'
154
+ ): Promise<BN> {
155
+ const [_1, _2, lowerboundEst, cappedAltEst, interpEst] =
156
+ await calculateAllEstimatedFundingRate(
157
+ market,
158
+ pythClient,
159
+ periodAdjustment
160
+ );
161
+
162
+ if (estimationMethod == 'lowerbound') {
163
+ //assuming remaining funding period has no gap
164
+ return lowerboundEst;
165
+ } else if (estimationMethod == 'capped') {
166
+ return cappedAltEst;
167
+ } else {
168
+ return interpEst;
169
+ }
170
+ }
171
+
172
+ /**
173
+ *
174
+ * @param market
175
+ * @param pythClient
176
+ * @param periodAdjustment
177
+ * @param estimationMethod
178
+ * @returns Estimated funding rate. : Precision //TODO-PRECISION
179
+ */
180
+ export async function calculateLongShortFundingRate(
181
+ market: Market,
182
+ pythClient: PythClient,
183
+ periodAdjustment: BN = new BN(1)
184
+ ): Promise<[BN, BN]> {
185
+ const [_1, _2, _, cappedAltEst, interpEst] = await calculateAllEstimatedFundingRate(
186
+ market,
187
+ pythClient,
188
+ periodAdjustment
189
+ );
190
+
191
+ if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
192
+ return [cappedAltEst, interpEst];
193
+ } else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
194
+ return [interpEst, cappedAltEst];
195
+ } else {
196
+ return [interpEst, interpEst];
197
+ }
198
+ }
199
+
200
+ /**
201
+ *
202
+ * @param market
203
+ * @param pythClient
204
+ * @param periodAdjustment
205
+ * @param estimationMethod
206
+ * @returns Estimated funding rate. : Precision //TODO-PRECISION
207
+ */
208
+ export async function calculateLongShortFundingRateAndLiveTwaps(
209
+ market: Market,
210
+ pythClient: PythClient,
211
+ periodAdjustment: BN = new BN(1),
212
+ ): Promise<[BN, BN, BN, BN]> {
213
+ const [markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst] =
214
+ await calculateAllEstimatedFundingRate(market, pythClient, periodAdjustment);
215
+
216
+ if(market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())){
217
+ return [markTwapLive, oracleTwapLive, cappedAltEst, interpEst];
218
+ } else if(market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())){
219
+ return [markTwapLive, oracleTwapLive, interpEst, cappedAltEst];
220
+ } else{
221
+ return [markTwapLive, oracleTwapLive, interpEst, interpEst];
222
+ }
223
+
224
+ }
225
+
226
+ /**
227
+ *
228
+ * @param market
229
+ * @returns Estimated fee pool size
230
+ */
231
+ export function calculateFundingPool(market: Market): BN {
232
+ // todo
233
+ const totalFeeLB = market.amm.totalFee.div(new BN(2));
234
+ const feePool = market.amm.totalFeeMinusDistributions.sub(totalFeeLB);
235
+ return feePool;
76
236
  }
@@ -102,9 +102,9 @@ export function calculatePositionPNL(
102
102
  }
103
103
 
104
104
  /**
105
- *
106
- * @param market
107
- * @param marketPosition
105
+ *
106
+ * @param market
107
+ * @param marketPosition
108
108
  * @returns // TODO-PRECISION
109
109
  */
110
110
  export function calculatePositionFundingPNL(
package/src/math/trade.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  calculateAmmReservesAfterSwap,
13
13
  calculatePrice,
14
14
  getSwapDirection,
15
+ AssetType,
15
16
  } from './amm';
16
17
  import { squareRootBN } from './utils';
17
18
 
@@ -27,7 +28,8 @@ export type PriceImpactUnit =
27
28
  | 'quoteAssetAmount'
28
29
  | 'quoteAssetAmountPeg'
29
30
  | 'acquiredBaseAssetAmount'
30
- | 'acquiredQuoteAssetAmount';
31
+ | 'acquiredQuoteAssetAmount'
32
+ | 'all';
31
33
 
32
34
  /**
33
35
  * Calculates avg/max slippage (price impact) for candidate trade
@@ -47,7 +49,8 @@ export type PriceImpactUnit =
47
49
  export function calculateTradeSlippage(
48
50
  direction: PositionDirection,
49
51
  amount: BN,
50
- market: Market
52
+ market: Market,
53
+ inputAssetType: AssetType = 'quote'
51
54
  ): [BN, BN, BN, BN] {
52
55
  const oldPrice = calculateMarkPrice(market);
53
56
  if (amount.eq(ZERO)) {
@@ -56,7 +59,8 @@ export function calculateTradeSlippage(
56
59
  const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(
57
60
  direction,
58
61
  amount,
59
- market
62
+ market,
63
+ inputAssetType
60
64
  );
61
65
 
62
66
  const entryPrice = calculatePrice(
@@ -103,7 +107,8 @@ export function calculateTradeSlippage(
103
107
  export function calculateTradeAcquiredAmounts(
104
108
  direction: PositionDirection,
105
109
  amount: BN,
106
- market: Market
110
+ market: Market,
111
+ inputAssetType: AssetType = 'quote'
107
112
  ): [BN, BN] {
108
113
  if (amount.eq(ZERO)) {
109
114
  return [ZERO, ZERO];
@@ -112,9 +117,9 @@ export function calculateTradeAcquiredAmounts(
112
117
  const [newQuoteAssetReserve, newBaseAssetReserve] =
113
118
  calculateAmmReservesAfterSwap(
114
119
  market.amm,
115
- 'quote',
120
+ inputAssetType,
116
121
  amount,
117
- getSwapDirection('quote', direction)
122
+ getSwapDirection(inputAssetType, direction)
118
123
  );
119
124
 
120
125
  const acquiredBase = market.amm.baseAssetReserve.sub(newBaseAssetReserve);
@@ -129,8 +134,8 @@ export function calculateTradeAcquiredAmounts(
129
134
  * @param market
130
135
  * @param targetPrice
131
136
  * @param pct optional default is 100% gap filling, can set smaller.
132
- * @returns trade direction/size in order to push price to a targetPrice,
133
- *
137
+ * @returns trade direction/size in order to push price to a targetPrice,
138
+ *
134
139
  * [
135
140
  * direction => direction of trade required, TODO-PRECISION
136
141
  * tradeSize => size of trade required, TODO-PRECISION
@@ -236,6 +241,7 @@ export function calculateTargetPriceTrade(
236
241
 
237
242
  const entryPrice = tradeSize
238
243
  .mul(AMM_TO_QUOTE_PRECISION_RATIO)
244
+ .mul(MARK_PRICE_PRECISION)
239
245
  .div(baseSize.abs());
240
246
 
241
247
  assert(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
package/src/types.ts CHANGED
@@ -221,6 +221,8 @@ export type AMM = {
221
221
  lastFundingRateTs: BN;
222
222
  lastMarkPriceTwap: BN;
223
223
  lastMarkPriceTwapTs: BN;
224
+ lastOraclePriceTwap: BN;
225
+ lastOraclePriceTwapTs: BN;
224
226
  oracle: PublicKey;
225
227
  oracleSource: OracleSource;
226
228
  fundingPeriod: BN;
@@ -264,7 +266,9 @@ export interface Trade {
264
266
  afterPrice: number;
265
267
  side: TradeSide;
266
268
  size: number;
269
+ quoteSize: number;
267
270
  ts: number;
271
+ fee: number;
268
272
  marketIndex: number;
269
273
  chainTs: number;
270
274
  }
@@ -299,9 +303,14 @@ export type Candle = {
299
303
  };
300
304
  export interface FundingPayment {
301
305
  userPublicKey: string;
302
- ts: number;
306
+ serverTs: number;
303
307
  marketIndex: number;
304
308
  amount: string;
309
+ blockchainTs: number;
310
+ baseAssetAmount: string;
311
+ userLastCumulativeFunding: string;
312
+ userLastFundingRateTs: string;
313
+ rate: number;
305
314
  }
306
315
 
307
316
  // # Misc Types
package/tsconfig.json CHANGED
@@ -6,7 +6,8 @@
6
6
  "declaration": true,
7
7
  "outDir": "./lib",
8
8
  "resolveJsonModule": true,
9
- "skipLibCheck": true
9
+ "skipLibCheck": true,
10
+ "declarationMap": true
10
11
  },
11
12
  "include": ["src"],
12
13
  "exclude": ["node_modules"]