@drift-labs/sdk 0.2.0-master.1 → 0.2.0-master.4
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.
- package/lib/accounts/types.d.ts +1 -0
- package/lib/admin.d.ts +4 -1
- package/lib/admin.js +29 -2
- package/lib/clearingHouse.d.ts +11 -14
- package/lib/clearingHouse.js +73 -73
- package/lib/config.js +1 -1
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +2 -1
- package/lib/factory/bigNum.d.ts +8 -2
- package/lib/factory/bigNum.js +14 -6
- package/lib/idl/clearing_house.json +189 -52
- package/lib/index.d.ts +2 -1
- package/lib/index.js +6 -1
- package/lib/math/amm.d.ts +6 -1
- package/lib/math/amm.js +124 -41
- package/lib/math/auction.js +4 -1
- package/lib/math/orders.d.ts +2 -2
- package/lib/math/orders.js +18 -11
- package/lib/math/repeg.js +1 -1
- package/lib/math/trade.d.ts +1 -1
- package/lib/math/trade.js +7 -10
- package/lib/orderParams.d.ts +14 -5
- package/lib/orderParams.js +8 -96
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +6 -85
- package/lib/types.d.ts +62 -1
- package/lib/types.js +37 -1
- package/package.json +3 -3
- package/src/admin.ts +48 -4
- package/src/clearingHouse.ts +102 -151
- package/src/config.ts +1 -1
- package/src/constants/numericConstants.ts +1 -0
- package/src/factory/bigNum.ts +26 -9
- package/src/idl/clearing_house.json +189 -52
- package/src/index.ts +2 -1
- package/src/math/amm.ts +207 -52
- package/src/math/auction.ts +5 -1
- package/src/math/orders.ts +17 -13
- package/src/math/repeg.ts +2 -1
- package/src/math/trade.ts +23 -25
- package/src/orderParams.ts +20 -141
- package/src/orders.ts +7 -131
- package/src/types.ts +58 -3
package/src/orders.ts
CHANGED
|
@@ -3,27 +3,13 @@ import {
|
|
|
3
3
|
MarketAccount,
|
|
4
4
|
Order,
|
|
5
5
|
PositionDirection,
|
|
6
|
-
SwapDirection,
|
|
7
6
|
UserAccount,
|
|
8
7
|
UserPosition,
|
|
9
8
|
} from './types';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
calculateAmmReservesAfterSwap,
|
|
13
|
-
calculateBaseAssetValue,
|
|
14
|
-
calculateSpreadReserves,
|
|
15
|
-
ClearingHouseUser,
|
|
16
|
-
isOrderRiskIncreasingInSameDirection,
|
|
17
|
-
standardizeBaseAssetAmount,
|
|
18
|
-
TEN_THOUSAND,
|
|
19
|
-
} from '.';
|
|
20
|
-
import {
|
|
21
|
-
calculateMarkPrice,
|
|
22
|
-
calculateNewMarketAfterTrade,
|
|
23
|
-
} from './math/market';
|
|
9
|
+
import { BN, standardizeBaseAssetAmount } from '.';
|
|
10
|
+
import { calculateNewMarketAfterTrade } from './math/market';
|
|
24
11
|
import {
|
|
25
12
|
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
26
|
-
TWO,
|
|
27
13
|
PEG_PRECISION,
|
|
28
14
|
ZERO,
|
|
29
15
|
} from './constants/numericConstants';
|
|
@@ -182,7 +168,6 @@ export function calculateBaseAssetAmountMarketCanExecute(
|
|
|
182
168
|
} else if (isVariant(order.orderType, 'triggerLimit')) {
|
|
183
169
|
return calculateAmountToTradeForTriggerLimit(market, order);
|
|
184
170
|
} else if (isVariant(order.orderType, 'market')) {
|
|
185
|
-
// should never be a market order queued
|
|
186
171
|
return ZERO;
|
|
187
172
|
} else {
|
|
188
173
|
return calculateAmountToTradeForTriggerMarket(market, order);
|
|
@@ -201,14 +186,7 @@ export function calculateAmountToTradeForLimit(
|
|
|
201
186
|
'Cant calculate limit price for oracle offset oracle without OraclePriceData'
|
|
202
187
|
);
|
|
203
188
|
}
|
|
204
|
-
|
|
205
|
-
if (order.postOnly) {
|
|
206
|
-
limitPrice = isVariant(order.direction, 'long')
|
|
207
|
-
? BN.min(order.price, floatingPrice)
|
|
208
|
-
: BN.max(order.price, floatingPrice);
|
|
209
|
-
} else {
|
|
210
|
-
limitPrice = floatingPrice;
|
|
211
|
-
}
|
|
189
|
+
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
212
190
|
}
|
|
213
191
|
|
|
214
192
|
const [maxAmountToTrade, direction] = calculateMaxBaseAssetAmountToTrade(
|
|
@@ -237,14 +215,8 @@ export function calculateAmountToTradeForTriggerLimit(
|
|
|
237
215
|
market: MarketAccount,
|
|
238
216
|
order: Order
|
|
239
217
|
): BN {
|
|
240
|
-
if (order.
|
|
241
|
-
|
|
242
|
-
market,
|
|
243
|
-
order
|
|
244
|
-
);
|
|
245
|
-
if (baseAssetAmount.eq(ZERO)) {
|
|
246
|
-
return ZERO;
|
|
247
|
-
}
|
|
218
|
+
if (!order.triggered) {
|
|
219
|
+
return ZERO;
|
|
248
220
|
}
|
|
249
221
|
|
|
250
222
|
return calculateAmountToTradeForLimit(market, order);
|
|
@@ -264,105 +236,9 @@ function calculateAmountToTradeForTriggerMarket(
|
|
|
264
236
|
market: MarketAccount,
|
|
265
237
|
order: Order
|
|
266
238
|
): BN {
|
|
267
|
-
|
|
268
|
-
? order.baseAssetAmount
|
|
269
|
-
: ZERO;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function isTriggerConditionSatisfied(
|
|
273
|
-
market: MarketAccount,
|
|
274
|
-
order: Order,
|
|
275
|
-
oraclePriceData?: OraclePriceData
|
|
276
|
-
): boolean {
|
|
277
|
-
const markPrice = calculateMarkPrice(market, oraclePriceData);
|
|
278
|
-
if (isVariant(order.triggerCondition, 'above')) {
|
|
279
|
-
return markPrice.gt(order.triggerPrice);
|
|
280
|
-
} else {
|
|
281
|
-
return markPrice.lt(order.triggerPrice);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export function calculateBaseAssetAmountUserCanExecute(
|
|
286
|
-
market: MarketAccount,
|
|
287
|
-
order: Order,
|
|
288
|
-
user: ClearingHouseUser,
|
|
289
|
-
oraclePriceData?: OraclePriceData
|
|
290
|
-
): BN {
|
|
291
|
-
const maxLeverage = user.getMaxLeverage(order.marketIndex, 'Initial');
|
|
292
|
-
const freeCollateral = user.getFreeCollateral();
|
|
293
|
-
let quoteAssetAmount: BN;
|
|
294
|
-
if (isOrderRiskIncreasingInSameDirection(user, order)) {
|
|
295
|
-
quoteAssetAmount = freeCollateral.mul(maxLeverage).div(TEN_THOUSAND);
|
|
296
|
-
} else {
|
|
297
|
-
const position =
|
|
298
|
-
user.getUserPosition(order.marketIndex) ||
|
|
299
|
-
user.getEmptyPosition(order.marketIndex);
|
|
300
|
-
const positionValue = calculateBaseAssetValue(
|
|
301
|
-
market,
|
|
302
|
-
position,
|
|
303
|
-
oraclePriceData
|
|
304
|
-
);
|
|
305
|
-
quoteAssetAmount = freeCollateral
|
|
306
|
-
.mul(maxLeverage)
|
|
307
|
-
.div(TEN_THOUSAND)
|
|
308
|
-
.add(positionValue.mul(TWO));
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (quoteAssetAmount.lte(ZERO)) {
|
|
239
|
+
if (!order.triggered) {
|
|
312
240
|
return ZERO;
|
|
313
241
|
}
|
|
314
242
|
|
|
315
|
-
|
|
316
|
-
? SwapDirection.ADD
|
|
317
|
-
: SwapDirection.REMOVE;
|
|
318
|
-
|
|
319
|
-
const useSpread = !order.postOnly;
|
|
320
|
-
let amm: Parameters<typeof calculateAmmReservesAfterSwap>[0];
|
|
321
|
-
if (useSpread) {
|
|
322
|
-
const { baseAssetReserve, quoteAssetReserve } = calculateSpreadReserves(
|
|
323
|
-
market.amm,
|
|
324
|
-
order.direction,
|
|
325
|
-
oraclePriceData
|
|
326
|
-
);
|
|
327
|
-
amm = {
|
|
328
|
-
baseAssetReserve,
|
|
329
|
-
quoteAssetReserve,
|
|
330
|
-
sqrtK: market.amm.sqrtK,
|
|
331
|
-
pegMultiplier: market.amm.pegMultiplier,
|
|
332
|
-
};
|
|
333
|
-
} else {
|
|
334
|
-
amm = market.amm;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const baseAssetReservesBefore = amm.baseAssetReserve;
|
|
338
|
-
const [_, baseAssetReservesAfter] = calculateAmmReservesAfterSwap(
|
|
339
|
-
amm,
|
|
340
|
-
'quote',
|
|
341
|
-
quoteAssetAmount,
|
|
342
|
-
swapDirection
|
|
343
|
-
);
|
|
344
|
-
|
|
345
|
-
let baseAssetAmount = baseAssetReservesBefore
|
|
346
|
-
.sub(baseAssetReservesAfter)
|
|
347
|
-
.abs();
|
|
348
|
-
if (order.reduceOnly) {
|
|
349
|
-
const position =
|
|
350
|
-
user.getUserPosition(order.marketIndex) ||
|
|
351
|
-
user.getEmptyPosition(order.marketIndex);
|
|
352
|
-
if (
|
|
353
|
-
isVariant(order.direction, 'long') &&
|
|
354
|
-
position.baseAssetAmount.gte(ZERO)
|
|
355
|
-
) {
|
|
356
|
-
baseAssetAmount = ZERO;
|
|
357
|
-
} else if (
|
|
358
|
-
isVariant(order.direction, 'short') &&
|
|
359
|
-
position.baseAssetAmount.lte(ZERO)
|
|
360
|
-
) {
|
|
361
|
-
baseAssetAmount = ZERO;
|
|
362
|
-
} else {
|
|
363
|
-
BN.min(baseAssetAmount, position.baseAssetAmount.abs());
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return baseAssetAmount;
|
|
243
|
+
return order.baseAssetAmount;
|
|
368
244
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PublicKey, Transaction } from '@solana/web3.js';
|
|
2
|
-
import { BN } from '.';
|
|
2
|
+
import { BN, ZERO } from '.';
|
|
3
3
|
|
|
4
4
|
// # Utility Types / Enums / Constants
|
|
5
5
|
export class SwapDirection {
|
|
@@ -48,6 +48,20 @@ export class OrderAction {
|
|
|
48
48
|
static readonly CANCEL = { cancel: {} };
|
|
49
49
|
static readonly EXPIRE = { expire: {} };
|
|
50
50
|
static readonly FILL = { fill: {} };
|
|
51
|
+
static readonly TRIGGER = { trigger: {} };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class OrderActionExplanation {
|
|
55
|
+
static readonly NONE = { none: {} };
|
|
56
|
+
static readonly BREACHED_MARGIN_REQUIREMENT = {
|
|
57
|
+
breachedMarginRequirement: {},
|
|
58
|
+
};
|
|
59
|
+
static readonly ORACLE_PRICE_BREACHED_LIMIT_PRICE = {
|
|
60
|
+
oraclePriceBreachedLimitPrice: {},
|
|
61
|
+
};
|
|
62
|
+
static readonly MARKET_ORDER_FILLED_TO_LIMIT_PRICE = {
|
|
63
|
+
marketOrderFilledToLimitPrice: {},
|
|
64
|
+
};
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
export class OrderTriggerCondition {
|
|
@@ -163,7 +177,10 @@ export type OrderRecord = {
|
|
|
163
177
|
maker: PublicKey;
|
|
164
178
|
takerOrder: Order;
|
|
165
179
|
makerOrder: Order;
|
|
180
|
+
takerUnsettledPnl: BN;
|
|
181
|
+
makerUnsettledPnl: BN;
|
|
166
182
|
action: OrderAction;
|
|
183
|
+
actionExplanation: OrderActionExplanation;
|
|
167
184
|
filler: PublicKey;
|
|
168
185
|
fillRecordId: BN;
|
|
169
186
|
marketIndex: BN;
|
|
@@ -260,6 +277,8 @@ export type AMM = {
|
|
|
260
277
|
lastMarkPriceTwapTs: BN;
|
|
261
278
|
lastOraclePriceTwap: BN;
|
|
262
279
|
lastOraclePriceTwapTs: BN;
|
|
280
|
+
lastOracleMarkSpreadPct: BN;
|
|
281
|
+
lastOracleConfPct: BN;
|
|
263
282
|
oracle: PublicKey;
|
|
264
283
|
oracleSource: OracleSource;
|
|
265
284
|
fundingPeriod: BN;
|
|
@@ -274,6 +293,8 @@ export type AMM = {
|
|
|
274
293
|
totalFee: BN;
|
|
275
294
|
minimumQuoteAssetTradeSize: BN;
|
|
276
295
|
baseAssetAmountStepSize: BN;
|
|
296
|
+
maxBaseAssetAmountRatio: number;
|
|
297
|
+
maxSlippageRatio: number;
|
|
277
298
|
lastOraclePrice: BN;
|
|
278
299
|
baseSpread: number;
|
|
279
300
|
curveUpdateIntensity: number;
|
|
@@ -290,6 +311,7 @@ export type AMM = {
|
|
|
290
311
|
lastAskPriceTwap: BN;
|
|
291
312
|
longSpread: BN;
|
|
292
313
|
shortSpread: BN;
|
|
314
|
+
maxSpread: number;
|
|
293
315
|
};
|
|
294
316
|
|
|
295
317
|
// # User Account Types
|
|
@@ -347,8 +369,9 @@ export type Order = {
|
|
|
347
369
|
reduceOnly: boolean;
|
|
348
370
|
triggerPrice: BN;
|
|
349
371
|
triggerCondition: OrderTriggerCondition;
|
|
372
|
+
triggered: boolean;
|
|
350
373
|
discountTier: OrderDiscountTier;
|
|
351
|
-
existingPositionDirection: PositionDirection
|
|
374
|
+
existingPositionDirection: PositionDirection;
|
|
352
375
|
referrer: PublicKey;
|
|
353
376
|
postOnly: boolean;
|
|
354
377
|
immediateOrCancel: boolean;
|
|
@@ -362,7 +385,6 @@ export type OrderParams = {
|
|
|
362
385
|
orderType: OrderType;
|
|
363
386
|
userOrderId: number;
|
|
364
387
|
direction: PositionDirection;
|
|
365
|
-
quoteAssetAmount: BN;
|
|
366
388
|
baseAssetAmount: BN;
|
|
367
389
|
price: BN;
|
|
368
390
|
marketIndex: BN;
|
|
@@ -381,6 +403,39 @@ export type OrderParams = {
|
|
|
381
403
|
};
|
|
382
404
|
};
|
|
383
405
|
|
|
406
|
+
export type NecessaryOrderParams = {
|
|
407
|
+
orderType: OrderType;
|
|
408
|
+
marketIndex: BN;
|
|
409
|
+
baseAssetAmount: BN;
|
|
410
|
+
direction: PositionDirection;
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
export type OptionalOrderParams = {
|
|
414
|
+
[Property in keyof OrderParams]?: OrderParams[Property];
|
|
415
|
+
} & NecessaryOrderParams;
|
|
416
|
+
|
|
417
|
+
export const DefaultOrderParams = {
|
|
418
|
+
orderType: OrderType.MARKET,
|
|
419
|
+
userOrderId: 0,
|
|
420
|
+
direction: PositionDirection.LONG,
|
|
421
|
+
baseAssetAmount: ZERO,
|
|
422
|
+
price: ZERO,
|
|
423
|
+
marketIndex: ZERO,
|
|
424
|
+
reduceOnly: false,
|
|
425
|
+
postOnly: false,
|
|
426
|
+
immediateOrCancel: false,
|
|
427
|
+
triggerPrice: ZERO,
|
|
428
|
+
triggerCondition: OrderTriggerCondition.ABOVE,
|
|
429
|
+
positionLimit: ZERO,
|
|
430
|
+
oraclePriceOffset: ZERO,
|
|
431
|
+
padding0: ZERO,
|
|
432
|
+
padding1: ZERO,
|
|
433
|
+
optionalAccounts: {
|
|
434
|
+
discountToken: false,
|
|
435
|
+
referrer: false,
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
|
|
384
439
|
export type MakerInfo = {
|
|
385
440
|
maker: PublicKey;
|
|
386
441
|
order: Order;
|