@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/src/math/amm.ts CHANGED
@@ -6,8 +6,10 @@ import {
6
6
  ZERO,
7
7
  BID_ASK_SPREAD_PRECISION,
8
8
  ONE,
9
- // QUOTE_PRECISION,
10
9
  AMM_TO_QUOTE_PRECISION_RATIO,
10
+ QUOTE_PRECISION,
11
+ MARGIN_PRECISION,
12
+ PRICE_DIV_PEG,
11
13
  } from '../constants/numericConstants';
12
14
  import {
13
15
  AMM,
@@ -25,6 +27,71 @@ import {
25
27
  calculateAdjustKCost,
26
28
  calculateBudgetedPeg,
27
29
  } from './repeg';
30
+
31
+ export function calculatePegFromTargetPrice(
32
+ targetPrice: BN,
33
+ baseAssetReserve: BN,
34
+ quoteAssetReserve: BN
35
+ ): BN {
36
+ return targetPrice
37
+ .mul(baseAssetReserve)
38
+ .div(quoteAssetReserve)
39
+ .add(PRICE_DIV_PEG.div(new BN(2)))
40
+ .div(PRICE_DIV_PEG);
41
+ }
42
+
43
+ export function calculateOptimalPegAndBudget(
44
+ amm: AMM,
45
+ oraclePriceData: OraclePriceData
46
+ ): [BN, BN, BN, boolean] {
47
+ const markPriceBefore = calculatePrice(
48
+ amm.baseAssetReserve,
49
+ amm.quoteAssetReserve,
50
+ amm.pegMultiplier
51
+ );
52
+ const targetPrice = oraclePriceData.price;
53
+ const newPeg = calculatePegFromTargetPrice(
54
+ targetPrice,
55
+ amm.baseAssetReserve,
56
+ amm.quoteAssetReserve
57
+ );
58
+ const prePegCost = calculateRepegCost(amm, newPeg);
59
+
60
+ const totalFeeLB = amm.totalExchangeFee.div(new BN(2));
61
+ const budget = BN.max(ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
62
+ if (budget.lt(prePegCost)) {
63
+ const maxPriceSpread = new BN(amm.maxSpread)
64
+ .mul(targetPrice)
65
+ .div(BID_ASK_SPREAD_PRECISION);
66
+
67
+ let newTargetPrice: BN;
68
+ let newOptimalPeg: BN;
69
+ let newBudget: BN;
70
+ const targetPriceGap = markPriceBefore.sub(targetPrice);
71
+
72
+ if (targetPriceGap.abs().gt(maxPriceSpread)) {
73
+ const markAdj = targetPriceGap.abs().sub(maxPriceSpread);
74
+
75
+ if (targetPriceGap.lt(new BN(0))) {
76
+ newTargetPrice = markPriceBefore.add(markAdj);
77
+ } else {
78
+ newTargetPrice = markPriceBefore.sub(markAdj);
79
+ }
80
+
81
+ newOptimalPeg = calculatePegFromTargetPrice(
82
+ newTargetPrice,
83
+ amm.baseAssetReserve,
84
+ amm.quoteAssetReserve
85
+ );
86
+
87
+ newBudget = calculateRepegCost(amm, newOptimalPeg);
88
+ return [newTargetPrice, newOptimalPeg, newBudget, false];
89
+ }
90
+ }
91
+
92
+ return [targetPrice, newPeg, budget, true];
93
+ }
94
+
28
95
  export function calculateNewAmm(
29
96
  amm: AMM,
30
97
  oraclePriceData: OraclePriceData
@@ -32,18 +99,12 @@ export function calculateNewAmm(
32
99
  let pKNumer = new BN(1);
33
100
  let pKDenom = new BN(1);
34
101
 
35
- const targetPrice = oraclePriceData.price;
36
- let newPeg = targetPrice
37
- .mul(amm.baseAssetReserve)
38
- .div(amm.quoteAssetReserve)
39
- .add(MARK_PRICE_PRECISION.div(PEG_PRECISION).div(new BN(2)))
40
- .div(MARK_PRICE_PRECISION.div(PEG_PRECISION));
41
- let prePegCost = calculateRepegCost(amm, newPeg);
42
-
43
- const totalFeeLB = amm.totalExchangeFee.div(new BN(2));
44
- const budget = BN.max(ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
102
+ const [targetPrice, _newPeg, budget, checkLowerBound] =
103
+ calculateOptimalPegAndBudget(amm, oraclePriceData);
104
+ let prePegCost = calculateRepegCost(amm, _newPeg);
105
+ let newPeg = _newPeg;
45
106
 
46
- if (prePegCost.gt(budget)) {
107
+ if (prePegCost.gt(budget) && checkLowerBound) {
47
108
  [pKNumer, pKDenom] = [new BN(999), new BN(1000)];
48
109
  const deficitMadeup = calculateAdjustKCost(amm, pKNumer, pKDenom);
49
110
  assert(deficitMadeup.lte(new BN(0)));
@@ -136,9 +197,16 @@ export function calculateUpdatedAMMSpreadReserves(
136
197
 
137
198
  export function calculateBidAskPrice(
138
199
  amm: AMM,
139
- oraclePriceData: OraclePriceData
200
+ oraclePriceData: OraclePriceData,
201
+ withUpdate = true
140
202
  ): [BN, BN] {
141
- const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
203
+ let newAmm: AMM;
204
+ if (withUpdate) {
205
+ newAmm = calculateUpdatedAMM(amm, oraclePriceData);
206
+ } else {
207
+ newAmm = amm;
208
+ }
209
+
142
210
  const askReserves = calculateSpreadReserves(
143
211
  newAmm,
144
212
  PositionDirection.LONG,
@@ -237,15 +305,115 @@ export function calculateAmmReservesAfterSwap(
237
305
  return [newQuoteAssetReserve, newBaseAssetReserve];
238
306
  }
239
307
 
308
+ export function calculateEffectiveLeverage(
309
+ baseSpread: number,
310
+ quoteAssetReserve: BN,
311
+ terminalQuoteAssetReserve: BN,
312
+ pegMultiplier: BN,
313
+ netBaseAssetAmount: BN,
314
+ markPrice: BN,
315
+ totalFeeMinusDistributions: BN
316
+ ): number {
317
+ // inventory skew
318
+ const netBaseAssetValue = quoteAssetReserve
319
+ .sub(terminalQuoteAssetReserve)
320
+ .mul(pegMultiplier)
321
+ .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
322
+
323
+ const localBaseAssetValue = netBaseAssetAmount
324
+ .mul(markPrice)
325
+ .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
326
+
327
+ const effectiveLeverage =
328
+ localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
329
+ (Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
330
+ 1 / QUOTE_PRECISION.toNumber();
331
+
332
+ return effectiveLeverage;
333
+ }
334
+
335
+ export function calculateMaxSpread(marginRatioInitial: number): number {
336
+ const maxTargetSpread: number = new BN(marginRatioInitial)
337
+ .mul(BID_ASK_SPREAD_PRECISION.div(MARGIN_PRECISION))
338
+ .toNumber();
339
+
340
+ return maxTargetSpread;
341
+ }
342
+
343
+ export function calculateSpreadBN(
344
+ baseSpread: number,
345
+ lastOracleMarkSpreadPct: BN,
346
+ lastOracleConfPct: BN,
347
+ maxSpread: number,
348
+ quoteAssetReserve: BN,
349
+ terminalQuoteAssetReserve: BN,
350
+ pegMultiplier: BN,
351
+ netBaseAssetAmount: BN,
352
+ markPrice: BN,
353
+ totalFeeMinusDistributions: BN
354
+ ): [number, number] {
355
+ let longSpread = baseSpread / 2;
356
+ let shortSpread = baseSpread / 2;
357
+
358
+ if (lastOracleMarkSpreadPct.gt(ZERO)) {
359
+ shortSpread = Math.max(
360
+ shortSpread,
361
+ lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber()
362
+ );
363
+ } else if (lastOracleMarkSpreadPct.lt(ZERO)) {
364
+ longSpread = Math.max(
365
+ longSpread,
366
+ lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber()
367
+ );
368
+ }
369
+
370
+ const maxTargetSpread: number = maxSpread;
371
+
372
+ const MAX_INVENTORY_SKEW = 5;
373
+
374
+ const effectiveLeverage = calculateEffectiveLeverage(
375
+ baseSpread,
376
+ quoteAssetReserve,
377
+ terminalQuoteAssetReserve,
378
+ pegMultiplier,
379
+ netBaseAssetAmount,
380
+ markPrice,
381
+ totalFeeMinusDistributions
382
+ );
383
+
384
+ if (totalFeeMinusDistributions.gt(ZERO)) {
385
+ const spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
386
+ if (netBaseAssetAmount.gt(ZERO)) {
387
+ longSpread *= spreadScale;
388
+ } else {
389
+ shortSpread *= spreadScale;
390
+ }
391
+ } else {
392
+ longSpread *= MAX_INVENTORY_SKEW;
393
+ shortSpread *= MAX_INVENTORY_SKEW;
394
+ }
395
+
396
+ const totalSpread = longSpread + shortSpread;
397
+ if (totalSpread > maxTargetSpread) {
398
+ if (longSpread > shortSpread) {
399
+ longSpread = Math.min(longSpread, maxTargetSpread);
400
+ shortSpread = maxTargetSpread - longSpread;
401
+ } else {
402
+ shortSpread = Math.min(shortSpread, maxTargetSpread);
403
+ longSpread = maxTargetSpread - shortSpread;
404
+ }
405
+ }
406
+
407
+ return [longSpread, shortSpread];
408
+ }
409
+
240
410
  export function calculateSpread(
241
411
  amm: AMM,
242
412
  direction: PositionDirection,
243
413
  oraclePriceData: OraclePriceData
244
414
  ): number {
245
- let spread = amm.baseSpread / 2;
246
-
247
415
  if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
248
- return spread;
416
+ return amm.baseSpread / 2;
249
417
  }
250
418
 
251
419
  const markPrice = calculatePrice(
@@ -255,49 +423,36 @@ export function calculateSpread(
255
423
  );
256
424
 
257
425
  const targetPrice = oraclePriceData?.price || markPrice;
426
+ const confInterval = oraclePriceData.confidence || ZERO;
258
427
 
259
428
  const targetMarkSpreadPct = markPrice
260
429
  .sub(targetPrice)
261
430
  .mul(BID_ASK_SPREAD_PRECISION)
262
431
  .div(markPrice);
263
432
 
264
- // oracle retreat
265
- if (
266
- (isVariant(direction, 'long') && targetMarkSpreadPct.lt(ZERO)) ||
267
- (isVariant(direction, 'short') && targetMarkSpreadPct.gt(ZERO))
268
- ) {
269
- spread = Math.max(spread, targetMarkSpreadPct.abs().toNumber());
270
- }
433
+ const confIntervalPct = confInterval
434
+ .mul(BID_ASK_SPREAD_PRECISION)
435
+ .div(markPrice);
271
436
 
272
- // inventory skew
273
- const MAX_INVENTORY_SKEW = 5;
274
- if (
275
- (amm.netBaseAssetAmount.gt(ZERO) && isVariant(direction, 'long')) ||
276
- (amm.netBaseAssetAmount.lt(ZERO) && isVariant(direction, 'short')) ||
277
- amm.totalFeeMinusDistributions.eq(ZERO)
278
- ) {
279
- const netCostBasis = amm.quoteAssetAmountLong.sub(
280
- amm.quoteAssetAmountShort
281
- );
282
- const netBaseAssetValue = amm.quoteAssetReserve
283
- .sub(amm.terminalQuoteAssetReserve)
284
- .mul(amm.pegMultiplier)
285
- .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
286
-
287
- const localBaseAssetValue = amm.netBaseAssetAmount
288
- .mul(markPrice)
289
- .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
290
- const netPnl = netBaseAssetValue.sub(netCostBasis);
291
- const localPnl = localBaseAssetValue.sub(netCostBasis);
292
-
293
- let effectiveLeverage = MAX_INVENTORY_SKEW;
294
- if (amm.totalFeeMinusDistributions.gt(ZERO)) {
295
- effectiveLeverage =
296
- localPnl.sub(netPnl).toNumber() /
297
- amm.totalFeeMinusDistributions.toNumber();
298
- }
437
+ const [longSpread, shortSpread] = calculateSpreadBN(
438
+ amm.baseSpread,
439
+ targetMarkSpreadPct,
440
+ confIntervalPct,
441
+ amm.maxSpread,
442
+ amm.quoteAssetReserve,
443
+ amm.terminalQuoteAssetReserve,
444
+ amm.pegMultiplier,
445
+ amm.netBaseAssetAmount,
446
+ markPrice,
447
+ amm.totalFeeMinusDistributions
448
+ );
449
+
450
+ let spread: number;
299
451
 
300
- spread *= Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
452
+ if (isVariant(direction, 'long')) {
453
+ spread = longSpread;
454
+ } else {
455
+ spread = shortSpread;
301
456
  }
302
457
 
303
458
  return spread;
@@ -2,7 +2,11 @@ import { isVariant, Order } from '../types';
2
2
  import { BN, ZERO } from '../.';
3
3
 
4
4
  export function isAuctionComplete(order: Order, slot: number): boolean {
5
- return new BN(slot).sub(order.slot).gte(new BN(order.auctionDuration));
5
+ if (order.auctionDuration === 0) {
6
+ return true;
7
+ }
8
+
9
+ return new BN(slot).sub(order.slot).gt(new BN(order.auctionDuration));
6
10
  }
7
11
 
8
12
  export function getAuctionPrice(order: Order, slot: number): BN {
@@ -1,9 +1,10 @@
1
1
  import { ClearingHouseUser } from '../clearingHouseUser';
2
- import { isVariant, Order } from '../types';
2
+ import { isOneOfVariant, isVariant, MarketAccount, Order } from '../types';
3
3
  import { ZERO, TWO } from '../constants/numericConstants';
4
4
  import { BN } from '@project-serum/anchor';
5
5
  import { OraclePriceData } from '../oracles/types';
6
- import { getAuctionPrice } from './auction';
6
+ import { getAuctionPrice, isAuctionComplete } from './auction';
7
+ import { calculateAskPrice, calculateBidPrice } from './market';
7
8
 
8
9
  export function isOrderRiskIncreasing(
9
10
  user: ClearingHouseUser,
@@ -120,24 +121,27 @@ export function standardizeBaseAssetAmount(
120
121
 
121
122
  export function getLimitPrice(
122
123
  order: Order,
124
+ market: MarketAccount,
123
125
  oraclePriceData: OraclePriceData,
124
126
  slot: number
125
127
  ): BN {
126
128
  let limitPrice;
127
129
  if (!order.oraclePriceOffset.eq(ZERO)) {
128
- const floatingPrice = oraclePriceData.price.add(order.oraclePriceOffset);
129
- if (order.postOnly) {
130
- limitPrice = isVariant(order.direction, 'long')
131
- ? BN.min(order.price, floatingPrice)
132
- : BN.max(order.price, floatingPrice);
130
+ limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
131
+ } else if (isOneOfVariant(order.orderType, ['market', 'triggerMarket'])) {
132
+ if (isAuctionComplete(order, slot)) {
133
+ limitPrice = getAuctionPrice(order, slot);
134
+ } else if (!order.price.eq(ZERO)) {
135
+ limitPrice = order.price;
136
+ } else if (isVariant(order.direction, 'long')) {
137
+ const askPrice = calculateAskPrice(market, oraclePriceData);
138
+ const delta = askPrice.div(new BN(market.amm.maxSlippageRatio));
139
+ limitPrice = askPrice.add(delta);
133
140
  } else {
134
- limitPrice = floatingPrice;
141
+ const bidPrice = calculateBidPrice(market, oraclePriceData);
142
+ const delta = bidPrice.div(new BN(market.amm.maxSlippageRatio));
143
+ limitPrice = bidPrice.sub(delta);
135
144
  }
136
- } else if (
137
- isVariant(order.orderType, 'market') ||
138
- isVariant(order.orderType, 'triggerMarket')
139
- ) {
140
- limitPrice = getAuctionPrice(order, slot);
141
145
  } else {
142
146
  limitPrice = order.price;
143
147
  }
package/src/math/repeg.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  AMM_RESERVE_PRECISION,
6
6
  PEG_PRECISION,
7
7
  AMM_TO_QUOTE_PRECISION_RATIO,
8
+ PRICE_DIV_PEG,
8
9
  QUOTE_PRECISION,
9
10
  ZERO,
10
11
  } from '../constants/numericConstants';
@@ -142,7 +143,7 @@ export function calculateBudgetedPeg(amm: AMM, cost: BN, targetPrice: BN): BN {
142
143
  const targetPeg = targetPrice
143
144
  .mul(amm.baseAssetReserve)
144
145
  .div(amm.quoteAssetReserve)
145
- .div(MARK_PRICE_PRECISION.div(PEG_PRECISION));
146
+ .div(PRICE_DIV_PEG);
146
147
 
147
148
  const k = amm.sqrtK.mul(amm.sqrtK);
148
149
  const x = amm.baseAssetReserve;
package/src/math/trade.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { MarketAccount, PositionDirection, SwapDirection } from '../types';
1
+ import { MarketAccount, PositionDirection } from '../types';
2
2
  import { BN } from '@project-serum/anchor';
3
3
  import { assert } from '../assert/assert';
4
4
  import {
@@ -78,28 +78,20 @@ export function calculateTradeSlippage(
78
78
  if (amount.eq(ZERO)) {
79
79
  return [ZERO, ZERO, oldPrice, oldPrice];
80
80
  }
81
- const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(
82
- direction,
83
- amount,
84
- market,
85
- inputAssetType,
86
- oraclePriceData,
87
- useSpread
88
- );
89
-
90
- const swapDirection = isVariant(direction, 'long')
91
- ? SwapDirection.REMOVE
92
- : SwapDirection.ADD;
93
- const quoteAssetAmountAcquired = calculateQuoteAssetAmountSwapped(
94
- acquiredQuote.abs(),
95
- market.amm.pegMultiplier,
96
- swapDirection
97
- );
81
+ const [acquiredBaseReserve, acquiredQuoteReserve, acquiredQuoteAssetAmount] =
82
+ calculateTradeAcquiredAmounts(
83
+ direction,
84
+ amount,
85
+ market,
86
+ inputAssetType,
87
+ oraclePriceData,
88
+ useSpread
89
+ );
98
90
 
99
- const entryPrice = quoteAssetAmountAcquired
91
+ const entryPrice = acquiredQuoteAssetAmount
100
92
  .mul(AMM_TO_QUOTE_PRECISION_RATIO)
101
93
  .mul(MARK_PRICE_PRECISION)
102
- .div(acquiredBase.abs());
94
+ .div(acquiredBaseReserve.abs());
103
95
 
104
96
  let amm: Parameters<typeof calculateAmmReservesAfterSwap>[0];
105
97
  if (useSpread && market.amm.baseSpread > 0) {
@@ -116,8 +108,8 @@ export function calculateTradeSlippage(
116
108
  }
117
109
 
118
110
  const newPrice = calculatePrice(
119
- amm.baseAssetReserve.sub(acquiredBase),
120
- amm.quoteAssetReserve.sub(acquiredQuote),
111
+ amm.baseAssetReserve.sub(acquiredBaseReserve),
112
+ amm.quoteAssetReserve.sub(acquiredQuoteReserve),
121
113
  amm.pegMultiplier
122
114
  );
123
115
 
@@ -159,9 +151,9 @@ export function calculateTradeAcquiredAmounts(
159
151
  inputAssetType: AssetType = 'quote',
160
152
  oraclePriceData: OraclePriceData,
161
153
  useSpread = true
162
- ): [BN, BN] {
154
+ ): [BN, BN, BN] {
163
155
  if (amount.eq(ZERO)) {
164
- return [ZERO, ZERO];
156
+ return [ZERO, ZERO, ZERO];
165
157
  }
166
158
 
167
159
  const swapDirection = getSwapDirection(inputAssetType, direction);
@@ -185,7 +177,13 @@ export function calculateTradeAcquiredAmounts(
185
177
 
186
178
  const acquiredBase = amm.baseAssetReserve.sub(newBaseAssetReserve);
187
179
  const acquiredQuote = amm.quoteAssetReserve.sub(newQuoteAssetReserve);
188
- return [acquiredBase, acquiredQuote];
180
+ const acquiredQuoteAssetamount = calculateQuoteAssetAmountSwapped(
181
+ acquiredQuote.abs(),
182
+ amm.pegMultiplier,
183
+ swapDirection
184
+ );
185
+
186
+ return [acquiredBase, acquiredQuote, acquiredQuoteAssetamount];
189
187
  }
190
188
 
191
189
  /**
@@ -1,154 +1,33 @@
1
- import {
2
- OrderParams,
3
- OrderTriggerCondition,
4
- OrderType,
5
- PositionDirection,
6
- } from './types';
1
+ import { OptionalOrderParams, OrderTriggerCondition, OrderType } from './types';
7
2
  import { BN } from '@project-serum/anchor';
8
- import { ZERO } from './constants/numericConstants';
9
3
 
10
4
  export function getLimitOrderParams(
11
- marketIndex: BN,
12
- direction: PositionDirection,
13
- baseAssetAmount: BN,
14
- price: BN,
15
- reduceOnly: boolean,
16
- discountToken = false,
17
- referrer = false,
18
- userOrderId = 0,
19
- postOnly = false,
20
- oraclePriceOffset = ZERO,
21
- immediateOrCancel = false
22
- ): OrderParams {
23
- return {
24
- orderType: OrderType.LIMIT,
25
- userOrderId,
26
- marketIndex,
27
- direction,
28
- quoteAssetAmount: ZERO,
29
- baseAssetAmount,
30
- price,
31
- reduceOnly,
32
- postOnly,
33
- immediateOrCancel,
34
- positionLimit: ZERO,
35
- padding0: true,
36
- padding1: ZERO,
37
- optionalAccounts: {
38
- discountToken,
39
- referrer,
40
- },
41
- triggerCondition: OrderTriggerCondition.ABOVE,
42
- triggerPrice: ZERO,
43
- oraclePriceOffset,
44
- };
5
+ params: Omit<OptionalOrderParams, 'orderType'> & { price: BN }
6
+ ): OptionalOrderParams {
7
+ return Object.assign({}, params, { orderType: OrderType.LIMIT });
45
8
  }
46
9
 
47
10
  export function getTriggerMarketOrderParams(
48
- marketIndex: BN,
49
- direction: PositionDirection,
50
- baseAssetAmount: BN,
51
- triggerPrice: BN,
52
- triggerCondition: OrderTriggerCondition,
53
- reduceOnly: boolean,
54
- discountToken = false,
55
- referrer = false,
56
- userOrderId = 0
57
- ): OrderParams {
58
- return {
59
- orderType: OrderType.TRIGGER_MARKET,
60
- userOrderId,
61
- marketIndex,
62
- direction,
63
- quoteAssetAmount: ZERO,
64
- baseAssetAmount,
65
- price: ZERO,
66
- reduceOnly,
67
- postOnly: false,
68
- immediateOrCancel: false,
69
- positionLimit: ZERO,
70
- padding0: true,
71
- padding1: ZERO,
72
- optionalAccounts: {
73
- discountToken,
74
- referrer,
75
- },
76
- triggerCondition,
77
- triggerPrice,
78
- oraclePriceOffset: ZERO,
79
- };
11
+ params: Omit<OptionalOrderParams, 'orderType'> & {
12
+ triggerCondition: OrderTriggerCondition;
13
+ triggerPrice: BN;
14
+ }
15
+ ): OptionalOrderParams {
16
+ return Object.assign({}, params, { orderType: OrderType.TRIGGER_MARKET });
80
17
  }
81
18
 
82
19
  export function getTriggerLimitOrderParams(
83
- marketIndex: BN,
84
- direction: PositionDirection,
85
- baseAssetAmount: BN,
86
- price: BN,
87
- triggerPrice: BN,
88
- triggerCondition: OrderTriggerCondition,
89
- reduceOnly: boolean,
90
- discountToken = false,
91
- referrer = false,
92
- userOrderId = 0
93
- ): OrderParams {
94
- return {
95
- orderType: OrderType.TRIGGER_LIMIT,
96
- userOrderId,
97
- marketIndex,
98
- direction,
99
- quoteAssetAmount: ZERO,
100
- baseAssetAmount,
101
- price,
102
- reduceOnly,
103
- postOnly: false,
104
- immediateOrCancel: false,
105
- positionLimit: ZERO,
106
- padding0: true,
107
- padding1: ZERO,
108
- optionalAccounts: {
109
- discountToken,
110
- referrer,
111
- },
112
- triggerCondition,
113
- triggerPrice,
114
- oraclePriceOffset: ZERO,
115
- };
20
+ params: Omit<OptionalOrderParams, 'orderType'> & {
21
+ triggerCondition: OrderTriggerCondition;
22
+ triggerPrice: BN;
23
+ price: BN;
24
+ }
25
+ ): OptionalOrderParams {
26
+ return Object.assign({}, params, { orderType: OrderType.TRIGGER_LIMIT });
116
27
  }
117
28
 
118
29
  export function getMarketOrderParams(
119
- marketIndex: BN,
120
- direction: PositionDirection,
121
- quoteAssetAmount: BN,
122
- baseAssetAmount: BN,
123
- reduceOnly: boolean,
124
- price = ZERO,
125
- discountToken = false,
126
- referrer = false
127
- ): OrderParams {
128
- if (baseAssetAmount.eq(ZERO) && quoteAssetAmount.eq(ZERO)) {
129
- throw Error('baseAssetAmount or quoteAssetAmount must be zero');
130
- }
131
-
132
- return {
133
- orderType: OrderType.MARKET,
134
- userOrderId: 0,
135
- marketIndex,
136
- direction,
137
- quoteAssetAmount,
138
- baseAssetAmount,
139
- price,
140
- reduceOnly,
141
- postOnly: false,
142
- immediateOrCancel: false,
143
- positionLimit: ZERO,
144
- padding0: true,
145
- padding1: ZERO,
146
- optionalAccounts: {
147
- discountToken,
148
- referrer,
149
- },
150
- triggerCondition: OrderTriggerCondition.ABOVE,
151
- triggerPrice: ZERO,
152
- oraclePriceOffset: ZERO,
153
- };
30
+ params: Omit<OptionalOrderParams, 'orderType'>
31
+ ): OptionalOrderParams {
32
+ return Object.assign({}, params, { orderType: OrderType.MARKET });
154
33
  }