@drift-labs/sdk 0.1.21-master.0 → 0.1.22
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/bulkAccountLoader.d.ts +0 -1
- package/lib/accounts/bulkAccountLoader.js +4 -2
- package/lib/accounts/bulkUserSubscription.d.ts +0 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +5 -2
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +23 -1
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +0 -1
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/pollingUserAccountSubscriber.js +13 -0
- package/lib/accounts/types.d.ts +8 -3
- package/lib/accounts/utils.d.ts +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +5 -2
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +25 -0
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/webSocketUserAccountSubscriber.js +11 -0
- package/lib/addresses.d.ts +4 -1
- package/lib/addresses.js +28 -1
- package/lib/admin.d.ts +10 -4
- package/lib/admin.js +48 -3
- package/lib/assert/assert.d.ts +0 -1
- package/lib/clearingHouse.d.ts +27 -2
- package/lib/clearingHouse.js +307 -7
- package/lib/clearingHouseUser.d.ts +16 -3
- package/lib/clearingHouseUser.js +79 -9
- package/lib/config.d.ts +0 -1
- package/lib/constants/markets.d.ts +0 -1
- package/lib/constants/markets.js +8 -0
- package/lib/constants/numericConstants.d.ts +1 -1
- package/lib/constants/numericConstants.js +2 -1
- package/lib/examples/makeTradeExample.d.ts +0 -1
- package/lib/factory/clearingHouse.d.ts +0 -1
- package/lib/factory/clearingHouseUser.d.ts +0 -1
- package/lib/idl/clearing_house.json +1077 -50
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -0
- package/lib/math/amm.d.ts +3 -1
- package/lib/math/amm.js +121 -8
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/funding.d.ts +0 -1
- package/lib/math/insuranceFund.d.ts +0 -1
- package/lib/math/market.d.ts +2 -2
- package/lib/math/market.js +11 -1
- package/lib/math/orders.d.ts +3 -0
- package/lib/math/orders.js +32 -0
- package/lib/math/position.d.ts +4 -2
- package/lib/math/position.js +18 -4
- package/lib/math/trade.d.ts +0 -1
- package/lib/math/utils.d.ts +0 -1
- package/lib/mockUSDCFaucet.d.ts +0 -1
- package/lib/orderParams.d.ts +7 -0
- package/lib/orderParams.js +108 -0
- package/lib/orders.d.ts +6 -0
- package/lib/orders.js +136 -0
- package/lib/pythClient.d.ts +0 -1
- package/lib/token/index.d.ts +0 -1
- package/lib/tx/defaultTxSender.d.ts +0 -1
- package/lib/tx/types.d.ts +0 -1
- package/lib/tx/utils.d.ts +0 -1
- package/lib/types.d.ts +145 -2
- package/lib/types.js +36 -1
- package/lib/util/computeUnits.d.ts +0 -1
- package/lib/util/tps.d.ts +0 -1
- package/lib/wallet.d.ts +0 -1
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +3 -3
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +33 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +30 -2
- package/src/accounts/types.ts +11 -2
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +47 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +29 -2
- package/src/addresses.ts +37 -0
- package/src/admin.ts +84 -6
- package/src/clearingHouse.ts +430 -5
- package/src/clearingHouseUser.ts +129 -12
- package/src/constants/markets.ts +8 -0
- package/src/constants/numericConstants.ts +1 -0
- package/src/idl/clearing_house.json +1077 -50
- package/src/index.ts +3 -0
- package/src/math/amm.ts +169 -14
- package/src/math/market.ts +28 -2
- package/src/math/orders.ts +44 -0
- package/src/math/position.ts +23 -3
- package/src/orderParams.ts +151 -0
- package/src/orders.ts +236 -0
- package/src/types.ts +129 -1
- package/tsconfig.json +0 -1
- package/lib/accounts/bulkAccountLoader.d.ts.map +0 -1
- package/lib/accounts/bulkUserSubscription.d.ts.map +0 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/pollingUserAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/types.d.ts.map +0 -1
- package/lib/accounts/utils.d.ts.map +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts.map +0 -1
- package/lib/addresses.d.ts.map +0 -1
- package/lib/admin.d.ts.map +0 -1
- package/lib/assert/assert.d.ts.map +0 -1
- package/lib/clearingHouse.d.ts.map +0 -1
- package/lib/clearingHouseUser.d.ts.map +0 -1
- package/lib/config.d.ts.map +0 -1
- package/lib/constants/markets.d.ts.map +0 -1
- package/lib/constants/numericConstants.d.ts.map +0 -1
- package/lib/examples/makeTradeExample.d.ts.map +0 -1
- package/lib/factory/clearingHouse.d.ts.map +0 -1
- package/lib/factory/clearingHouseUser.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/math/amm.d.ts.map +0 -1
- package/lib/math/conversion.d.ts.map +0 -1
- package/lib/math/funding.d.ts.map +0 -1
- package/lib/math/insuranceFund.d.ts.map +0 -1
- package/lib/math/market.d.ts.map +0 -1
- package/lib/math/position.d.ts.map +0 -1
- package/lib/math/trade.d.ts.map +0 -1
- package/lib/math/utils.d.ts.map +0 -1
- package/lib/mockUSDCFaucet.d.ts.map +0 -1
- package/lib/pythClient.d.ts.map +0 -1
- package/lib/token/index.d.ts.map +0 -1
- package/lib/tx/defaultTxSender.d.ts.map +0 -1
- package/lib/tx/types.d.ts.map +0 -1
- package/lib/tx/utils.d.ts.map +0 -1
- package/lib/types.d.ts.map +0 -1
- package/lib/util/computeUnits.d.ts.map +0 -1
- package/lib/util/tps.d.ts.map +0 -1
- package/lib/wallet.d.ts.map +0 -1
package/src/index.ts
CHANGED
|
@@ -23,6 +23,9 @@ export * from './math/market';
|
|
|
23
23
|
export * from './math/position';
|
|
24
24
|
export * from './math/amm';
|
|
25
25
|
export * from './math/trade';
|
|
26
|
+
export * from './math/orders';
|
|
27
|
+
export * from './orders';
|
|
28
|
+
export * from './orderParams';
|
|
26
29
|
export * from './wallet';
|
|
27
30
|
export * from './types';
|
|
28
31
|
export * from './math/utils';
|
package/src/math/amm.ts
CHANGED
|
@@ -4,11 +4,25 @@ import {
|
|
|
4
4
|
MARK_PRICE_PRECISION,
|
|
5
5
|
PEG_PRECISION,
|
|
6
6
|
ZERO,
|
|
7
|
+
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
8
|
+
QUOTE_PRECISION,
|
|
9
|
+
AMM_RESERVE_PRECISION,
|
|
7
10
|
} from '../constants/numericConstants';
|
|
8
11
|
import { calculateBaseAssetValue } from './position';
|
|
9
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
AMM,
|
|
14
|
+
PositionDirection,
|
|
15
|
+
SwapDirection,
|
|
16
|
+
Market,
|
|
17
|
+
isVariant,
|
|
18
|
+
} from '../types';
|
|
10
19
|
import { assert } from '../assert/assert';
|
|
11
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
calculatePositionPNL,
|
|
22
|
+
calculateMarkPrice,
|
|
23
|
+
convertToNumber,
|
|
24
|
+
squareRootBN,
|
|
25
|
+
} from '..';
|
|
12
26
|
|
|
13
27
|
/**
|
|
14
28
|
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
@@ -114,17 +128,11 @@ export function getSwapDirection(
|
|
|
114
128
|
inputAssetType: AssetType,
|
|
115
129
|
positionDirection: PositionDirection
|
|
116
130
|
): SwapDirection {
|
|
117
|
-
if (
|
|
118
|
-
positionDirection === PositionDirection.LONG &&
|
|
119
|
-
inputAssetType === 'base'
|
|
120
|
-
) {
|
|
131
|
+
if (isVariant(positionDirection, 'long') && inputAssetType === 'base') {
|
|
121
132
|
return SwapDirection.REMOVE;
|
|
122
133
|
}
|
|
123
134
|
|
|
124
|
-
if (
|
|
125
|
-
positionDirection === PositionDirection.SHORT &&
|
|
126
|
-
inputAssetType === 'quote'
|
|
127
|
-
) {
|
|
135
|
+
if (isVariant(positionDirection, 'short') && inputAssetType === 'quote') {
|
|
128
136
|
return SwapDirection.REMOVE;
|
|
129
137
|
}
|
|
130
138
|
|
|
@@ -150,6 +158,7 @@ export function calculateAdjustKCost(
|
|
|
150
158
|
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
151
159
|
marketIndex: new BN(marketIndex),
|
|
152
160
|
quoteAssetAmount: new BN(0),
|
|
161
|
+
openOrders: new BN(0),
|
|
153
162
|
};
|
|
154
163
|
|
|
155
164
|
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
@@ -169,6 +178,30 @@ export function calculateAdjustKCost(
|
|
|
169
178
|
|
|
170
179
|
const cost = calculatePositionPNL(marketNewK, netUserPosition);
|
|
171
180
|
|
|
181
|
+
const p = PEG_PRECISION.mul(numerator).div(denomenator);
|
|
182
|
+
const x = market.amm.baseAssetReserve;
|
|
183
|
+
const y = market.amm.quoteAssetReserve;
|
|
184
|
+
const delta = market.baseAssetAmount;
|
|
185
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
186
|
+
|
|
187
|
+
const numer1 = PEG_PRECISION.sub(p).mul(y).div(PEG_PRECISION);
|
|
188
|
+
const numer20 = k
|
|
189
|
+
.mul(p)
|
|
190
|
+
.mul(p)
|
|
191
|
+
.div(PEG_PRECISION)
|
|
192
|
+
.div(PEG_PRECISION)
|
|
193
|
+
.div(x.mul(p).div(PEG_PRECISION).add(delta));
|
|
194
|
+
const numer21 = k.div(x.add(delta));
|
|
195
|
+
|
|
196
|
+
const formulaCost = numer21
|
|
197
|
+
.sub(numer20)
|
|
198
|
+
.sub(numer1)
|
|
199
|
+
.mul(market.amm.pegMultiplier)
|
|
200
|
+
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
201
|
+
console.log(convertToNumber(formulaCost, QUOTE_PRECISION));
|
|
202
|
+
|
|
203
|
+
// p.div(p.mul(x).add(delta)).sub()
|
|
204
|
+
|
|
172
205
|
return cost;
|
|
173
206
|
}
|
|
174
207
|
|
|
@@ -190,6 +223,7 @@ export function calculateRepegCost(
|
|
|
190
223
|
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
191
224
|
marketIndex: new BN(marketIndex),
|
|
192
225
|
quoteAssetAmount: new BN(0),
|
|
226
|
+
openOrders: new BN(0),
|
|
193
227
|
};
|
|
194
228
|
|
|
195
229
|
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
@@ -210,6 +244,17 @@ export function calculateRepegCost(
|
|
|
210
244
|
|
|
211
245
|
const cost = calculatePositionPNL(marketNewPeg, netUserPosition);
|
|
212
246
|
|
|
247
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
248
|
+
const newQuoteAssetReserve = k.div(
|
|
249
|
+
market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount)
|
|
250
|
+
);
|
|
251
|
+
const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(
|
|
252
|
+
market.amm.quoteAssetReserve
|
|
253
|
+
);
|
|
254
|
+
const cost2 = deltaQuoteAssetReserves
|
|
255
|
+
.mul(market.amm.pegMultiplier.sub(newPeg))
|
|
256
|
+
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
257
|
+
console.log(convertToNumber(cost2, QUOTE_PRECISION));
|
|
213
258
|
return cost;
|
|
214
259
|
}
|
|
215
260
|
|
|
@@ -220,10 +265,6 @@ export function calculateRepegCost(
|
|
|
220
265
|
* @returns cost : Precision MARK_PRICE_PRECISION
|
|
221
266
|
*/
|
|
222
267
|
export function calculateTerminalPrice(market: Market) {
|
|
223
|
-
if (!market.initialized) {
|
|
224
|
-
return new BN(0);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
268
|
const directionToClose = market.baseAssetAmount.gt(ZERO)
|
|
228
269
|
? PositionDirection.SHORT
|
|
229
270
|
: PositionDirection.LONG;
|
|
@@ -235,6 +276,7 @@ export function calculateTerminalPrice(market: Market) {
|
|
|
235
276
|
market.baseAssetAmount.abs(),
|
|
236
277
|
getSwapDirection('base', directionToClose)
|
|
237
278
|
);
|
|
279
|
+
|
|
238
280
|
const terminalPrice = newQuoteAssetReserve
|
|
239
281
|
.mul(MARK_PRICE_PRECISION)
|
|
240
282
|
.mul(market.amm.pegMultiplier)
|
|
@@ -243,3 +285,116 @@ export function calculateTerminalPrice(market: Market) {
|
|
|
243
285
|
|
|
244
286
|
return terminalPrice;
|
|
245
287
|
}
|
|
288
|
+
|
|
289
|
+
export function calculateMaxBaseAssetAmountToTrade(
|
|
290
|
+
amm: AMM,
|
|
291
|
+
limit_price: BN
|
|
292
|
+
): [BN, PositionDirection] {
|
|
293
|
+
const invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
294
|
+
|
|
295
|
+
const newBaseAssetReserveSquared = invariant
|
|
296
|
+
.mul(MARK_PRICE_PRECISION)
|
|
297
|
+
.mul(amm.pegMultiplier)
|
|
298
|
+
.div(limit_price)
|
|
299
|
+
.div(PEG_PRECISION);
|
|
300
|
+
|
|
301
|
+
const newBaseAssetReserve = squareRootBN(newBaseAssetReserveSquared);
|
|
302
|
+
|
|
303
|
+
if (newBaseAssetReserve.gt(amm.baseAssetReserve)) {
|
|
304
|
+
return [
|
|
305
|
+
newBaseAssetReserve.sub(amm.baseAssetReserve),
|
|
306
|
+
PositionDirection.SHORT,
|
|
307
|
+
];
|
|
308
|
+
} else if (newBaseAssetReserve.lt(amm.baseAssetReserve)) {
|
|
309
|
+
return [
|
|
310
|
+
amm.baseAssetReserve.sub(newBaseAssetReserve),
|
|
311
|
+
PositionDirection.LONG,
|
|
312
|
+
];
|
|
313
|
+
} else {
|
|
314
|
+
console.log('tradeSize Too Small');
|
|
315
|
+
return [new BN(0), PositionDirection.LONG];
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export function calculateBudgetedK(market: Market, cost: BN): [BN, BN] {
|
|
320
|
+
// wolframalpha.com
|
|
321
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
322
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
323
|
+
|
|
324
|
+
// todo: assumes k = x * y
|
|
325
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
326
|
+
|
|
327
|
+
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
328
|
+
const x = market.amm.baseAssetReserve;
|
|
329
|
+
const y = market.amm.quoteAssetReserve;
|
|
330
|
+
|
|
331
|
+
const d = market.baseAssetAmount;
|
|
332
|
+
const Q = market.amm.pegMultiplier;
|
|
333
|
+
|
|
334
|
+
const C = cost.mul(new BN(-1));
|
|
335
|
+
|
|
336
|
+
const numer1 = y.mul(d).mul(Q).div(AMM_RESERVE_PRECISION).div(PEG_PRECISION);
|
|
337
|
+
const numer2 = C.mul(x.add(d)).div(QUOTE_PRECISION);
|
|
338
|
+
const denom1 = C.mul(x)
|
|
339
|
+
.mul(x.add(d))
|
|
340
|
+
.div(AMM_RESERVE_PRECISION)
|
|
341
|
+
.div(QUOTE_PRECISION);
|
|
342
|
+
const denom2 = y
|
|
343
|
+
.mul(d)
|
|
344
|
+
.mul(d)
|
|
345
|
+
.mul(Q)
|
|
346
|
+
.div(AMM_RESERVE_PRECISION)
|
|
347
|
+
.div(AMM_RESERVE_PRECISION)
|
|
348
|
+
.div(PEG_PRECISION);
|
|
349
|
+
|
|
350
|
+
const numerator = d
|
|
351
|
+
.mul(numer1.add(numer2))
|
|
352
|
+
.div(AMM_RESERVE_PRECISION)
|
|
353
|
+
.div(AMM_RESERVE_PRECISION)
|
|
354
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
355
|
+
const denominator = denom1
|
|
356
|
+
.add(denom2)
|
|
357
|
+
.div(AMM_RESERVE_PRECISION)
|
|
358
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
359
|
+
console.log(numerator, denominator);
|
|
360
|
+
// const p = (numerator).div(denominator);
|
|
361
|
+
|
|
362
|
+
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
363
|
+
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
364
|
+
|
|
365
|
+
return [numerator, denominator];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function calculateBudgetedPeg(market: Market, cost: BN): BN {
|
|
369
|
+
// wolframalpha.com
|
|
370
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
371
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
372
|
+
|
|
373
|
+
// todo: assumes k = x * y
|
|
374
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
375
|
+
|
|
376
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
377
|
+
const x = market.amm.baseAssetReserve;
|
|
378
|
+
const y = market.amm.quoteAssetReserve;
|
|
379
|
+
|
|
380
|
+
const d = market.baseAssetAmount;
|
|
381
|
+
const Q = market.amm.pegMultiplier;
|
|
382
|
+
|
|
383
|
+
const C = cost.mul(new BN(-1));
|
|
384
|
+
|
|
385
|
+
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
386
|
+
const deltaPegMultiplier = C.mul(MARK_PRICE_PRECISION)
|
|
387
|
+
.div(deltaQuoteAssetReserves.div(AMM_TO_QUOTE_PRECISION_RATIO))
|
|
388
|
+
.mul(PEG_PRECISION)
|
|
389
|
+
.div(QUOTE_PRECISION);
|
|
390
|
+
console.log(
|
|
391
|
+
Q.toNumber(),
|
|
392
|
+
'change by',
|
|
393
|
+
deltaPegMultiplier.toNumber() / MARK_PRICE_PRECISION.toNumber()
|
|
394
|
+
);
|
|
395
|
+
const newPeg = Q.sub(
|
|
396
|
+
deltaPegMultiplier.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION)
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
return newPeg;
|
|
400
|
+
}
|
package/src/math/market.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { BN } from '@project-serum/anchor';
|
|
2
|
-
import { Market } from '../types';
|
|
3
|
-
import {
|
|
2
|
+
import { Market, PositionDirection } from '../types';
|
|
3
|
+
import {
|
|
4
|
+
calculateAmmReservesAfterSwap,
|
|
5
|
+
calculatePrice,
|
|
6
|
+
getSwapDirection,
|
|
7
|
+
} from './amm';
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Calculates market mark price
|
|
@@ -15,3 +19,25 @@ export function calculateMarkPrice(market: Market): BN {
|
|
|
15
19
|
market.amm.pegMultiplier
|
|
16
20
|
);
|
|
17
21
|
}
|
|
22
|
+
|
|
23
|
+
export function calculateNewMarketAfterTrade(
|
|
24
|
+
baseAssetAmount: BN,
|
|
25
|
+
direction: PositionDirection,
|
|
26
|
+
market: Market
|
|
27
|
+
): Market {
|
|
28
|
+
const [newQuoteAssetReserve, newBaseAssetReserve] =
|
|
29
|
+
calculateAmmReservesAfterSwap(
|
|
30
|
+
market.amm,
|
|
31
|
+
'base',
|
|
32
|
+
baseAssetAmount.abs(),
|
|
33
|
+
getSwapDirection('base', direction)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const newAmm = Object.assign({}, market.amm);
|
|
37
|
+
const newMarket = Object.assign({}, market);
|
|
38
|
+
newMarket.amm = newAmm;
|
|
39
|
+
newMarket.amm.quoteAssetReserve = newQuoteAssetReserve;
|
|
40
|
+
newMarket.amm.baseAssetReserve = newBaseAssetReserve;
|
|
41
|
+
|
|
42
|
+
return newMarket;
|
|
43
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ClearingHouseUser } from '../clearingHouseUser';
|
|
2
|
+
import { isVariant, Order } from '../types';
|
|
3
|
+
import { ZERO, TWO } from '../constants/numericConstants';
|
|
4
|
+
|
|
5
|
+
export function isOrderRiskIncreasing(
|
|
6
|
+
user: ClearingHouseUser,
|
|
7
|
+
order: Order
|
|
8
|
+
): boolean {
|
|
9
|
+
if (isVariant(order.status, 'init')) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const position =
|
|
14
|
+
user.getUserPosition(order.marketIndex) ||
|
|
15
|
+
user.getEmptyPosition(order.marketIndex);
|
|
16
|
+
|
|
17
|
+
// if no position exists, it's risk increasing
|
|
18
|
+
if (position.baseAssetAmount.eq(ZERO)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// if position is long and order is long
|
|
23
|
+
if (position.baseAssetAmount.gt(ZERO) && isVariant(order.direction, 'long')) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// if position is short and order is short
|
|
28
|
+
if (
|
|
29
|
+
position.baseAssetAmount.lt(ZERO) &&
|
|
30
|
+
isVariant(order.direction, 'short')
|
|
31
|
+
) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const baseAssetAmountToFill = order.baseAssetAmount.sub(
|
|
36
|
+
order.baseAssetAmountFilled
|
|
37
|
+
);
|
|
38
|
+
// if order will flip position
|
|
39
|
+
if (baseAssetAmountToFill.gt(position.baseAssetAmount.abs().mul(TWO))) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return false;
|
|
44
|
+
}
|
package/src/math/position.ts
CHANGED
|
@@ -27,9 +27,7 @@ export function calculateBaseAssetValue(
|
|
|
27
27
|
return ZERO;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
const directionToClose = userPosition
|
|
31
|
-
? PositionDirection.SHORT
|
|
32
|
-
: PositionDirection.LONG;
|
|
30
|
+
const directionToClose = findDirectionToClose(userPosition);
|
|
33
31
|
|
|
34
32
|
const [newQuoteAssetReserve, _] = calculateAmmReservesAfterSwap(
|
|
35
33
|
market.amm,
|
|
@@ -138,3 +136,25 @@ export function calculateEntryPrice(userPosition: UserPosition): BN {
|
|
|
138
136
|
.div(userPosition.baseAssetAmount)
|
|
139
137
|
.abs();
|
|
140
138
|
}
|
|
139
|
+
|
|
140
|
+
export function findDirectionToClose(
|
|
141
|
+
userPosition: UserPosition
|
|
142
|
+
): PositionDirection {
|
|
143
|
+
return userPosition.baseAssetAmount.gt(ZERO)
|
|
144
|
+
? PositionDirection.SHORT
|
|
145
|
+
: PositionDirection.LONG;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function positionCurrentDirection(
|
|
149
|
+
userPosition: UserPosition
|
|
150
|
+
): PositionDirection {
|
|
151
|
+
return userPosition.baseAssetAmount.gte(ZERO)
|
|
152
|
+
? PositionDirection.LONG
|
|
153
|
+
: PositionDirection.SHORT;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function isEmptyPosition(userPosition: UserPosition): boolean {
|
|
157
|
+
return (
|
|
158
|
+
userPosition.baseAssetAmount.eq(ZERO) && userPosition.openOrders.eq(ZERO)
|
|
159
|
+
);
|
|
160
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OrderParams,
|
|
3
|
+
OrderTriggerCondition,
|
|
4
|
+
OrderType,
|
|
5
|
+
PositionDirection,
|
|
6
|
+
} from './types';
|
|
7
|
+
import { BN } from '@project-serum/anchor';
|
|
8
|
+
import { ZERO } from './constants/numericConstants';
|
|
9
|
+
|
|
10
|
+
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
|
+
): OrderParams {
|
|
20
|
+
return {
|
|
21
|
+
orderType: OrderType.LIMIT,
|
|
22
|
+
userOrderId,
|
|
23
|
+
marketIndex,
|
|
24
|
+
direction,
|
|
25
|
+
quoteAssetAmount: ZERO,
|
|
26
|
+
baseAssetAmount,
|
|
27
|
+
price,
|
|
28
|
+
reduceOnly,
|
|
29
|
+
postOnly: false,
|
|
30
|
+
immediateOrCancel: false,
|
|
31
|
+
positionLimit: ZERO,
|
|
32
|
+
padding0: true,
|
|
33
|
+
padding1: ZERO,
|
|
34
|
+
optionalAccounts: {
|
|
35
|
+
discountToken,
|
|
36
|
+
referrer,
|
|
37
|
+
},
|
|
38
|
+
triggerCondition: OrderTriggerCondition.ABOVE,
|
|
39
|
+
triggerPrice: ZERO,
|
|
40
|
+
oraclePriceOffset: ZERO,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getTriggerMarketOrderParams(
|
|
45
|
+
marketIndex: BN,
|
|
46
|
+
direction: PositionDirection,
|
|
47
|
+
baseAssetAmount: BN,
|
|
48
|
+
triggerPrice: BN,
|
|
49
|
+
triggerCondition: OrderTriggerCondition,
|
|
50
|
+
reduceOnly: boolean,
|
|
51
|
+
discountToken = false,
|
|
52
|
+
referrer = false,
|
|
53
|
+
userOrderId = 0
|
|
54
|
+
): OrderParams {
|
|
55
|
+
return {
|
|
56
|
+
orderType: OrderType.TRIGGER_MARKET,
|
|
57
|
+
userOrderId,
|
|
58
|
+
marketIndex,
|
|
59
|
+
direction,
|
|
60
|
+
quoteAssetAmount: ZERO,
|
|
61
|
+
baseAssetAmount,
|
|
62
|
+
price: ZERO,
|
|
63
|
+
reduceOnly,
|
|
64
|
+
postOnly: false,
|
|
65
|
+
immediateOrCancel: false,
|
|
66
|
+
positionLimit: ZERO,
|
|
67
|
+
padding0: true,
|
|
68
|
+
padding1: ZERO,
|
|
69
|
+
optionalAccounts: {
|
|
70
|
+
discountToken,
|
|
71
|
+
referrer,
|
|
72
|
+
},
|
|
73
|
+
triggerCondition,
|
|
74
|
+
triggerPrice,
|
|
75
|
+
oraclePriceOffset: ZERO,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function getTriggerLimitOrderParams(
|
|
80
|
+
marketIndex: BN,
|
|
81
|
+
direction: PositionDirection,
|
|
82
|
+
baseAssetAmount: BN,
|
|
83
|
+
price: BN,
|
|
84
|
+
triggerPrice: BN,
|
|
85
|
+
triggerCondition: OrderTriggerCondition,
|
|
86
|
+
reduceOnly: boolean,
|
|
87
|
+
discountToken = false,
|
|
88
|
+
referrer = false,
|
|
89
|
+
userOrderId = 0
|
|
90
|
+
): OrderParams {
|
|
91
|
+
return {
|
|
92
|
+
orderType: OrderType.TRIGGER_LIMIT,
|
|
93
|
+
userOrderId,
|
|
94
|
+
marketIndex,
|
|
95
|
+
direction,
|
|
96
|
+
quoteAssetAmount: ZERO,
|
|
97
|
+
baseAssetAmount,
|
|
98
|
+
price,
|
|
99
|
+
reduceOnly,
|
|
100
|
+
postOnly: false,
|
|
101
|
+
immediateOrCancel: false,
|
|
102
|
+
positionLimit: ZERO,
|
|
103
|
+
padding0: true,
|
|
104
|
+
padding1: ZERO,
|
|
105
|
+
optionalAccounts: {
|
|
106
|
+
discountToken,
|
|
107
|
+
referrer,
|
|
108
|
+
},
|
|
109
|
+
triggerCondition,
|
|
110
|
+
triggerPrice,
|
|
111
|
+
oraclePriceOffset: ZERO,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function getMarketOrderParams(
|
|
116
|
+
marketIndex: BN,
|
|
117
|
+
direction: PositionDirection,
|
|
118
|
+
quoteAssetAmount: BN,
|
|
119
|
+
baseAssetAmount: BN,
|
|
120
|
+
reduceOnly: boolean,
|
|
121
|
+
price = ZERO,
|
|
122
|
+
discountToken = false,
|
|
123
|
+
referrer = false
|
|
124
|
+
): OrderParams {
|
|
125
|
+
if (baseAssetAmount.eq(ZERO) && quoteAssetAmount.eq(ZERO)) {
|
|
126
|
+
throw Error('baseAssetAmount or quoteAssetAmount must be zero');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
orderType: OrderType.MARKET,
|
|
131
|
+
userOrderId: 0,
|
|
132
|
+
marketIndex,
|
|
133
|
+
direction,
|
|
134
|
+
quoteAssetAmount,
|
|
135
|
+
baseAssetAmount,
|
|
136
|
+
price,
|
|
137
|
+
reduceOnly,
|
|
138
|
+
postOnly: false,
|
|
139
|
+
immediateOrCancel: false,
|
|
140
|
+
positionLimit: ZERO,
|
|
141
|
+
padding0: true,
|
|
142
|
+
padding1: ZERO,
|
|
143
|
+
optionalAccounts: {
|
|
144
|
+
discountToken,
|
|
145
|
+
referrer,
|
|
146
|
+
},
|
|
147
|
+
triggerCondition: OrderTriggerCondition.ABOVE,
|
|
148
|
+
triggerPrice: ZERO,
|
|
149
|
+
oraclePriceOffset: ZERO,
|
|
150
|
+
};
|
|
151
|
+
}
|