@drift-labs/sdk 0.1.23-master.2 → 0.1.23-master.3
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/math/orders.d.ts +1 -0
- package/lib/math/orders.js +23 -1
- package/lib/orders.d.ts +3 -1
- package/lib/orders.js +31 -3
- package/package.json +1 -1
- package/src/math/orders.ts +33 -0
- package/src/orders.ts +56 -3
package/lib/math/orders.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ClearingHouseUser } from '../clearingHouseUser';
|
|
2
2
|
import { Order } from '../types';
|
|
3
3
|
export declare function isOrderRiskIncreasing(user: ClearingHouseUser, order: Order): boolean;
|
|
4
|
+
export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouseUser, order: Order): boolean;
|
package/lib/math/orders.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
function isOrderRiskIncreasing(user, order) {
|
|
@@ -30,3 +30,25 @@ function isOrderRiskIncreasing(user, order) {
|
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
32
|
exports.isOrderRiskIncreasing = isOrderRiskIncreasing;
|
|
33
|
+
function isOrderRiskIncreasingInSameDirection(user, order) {
|
|
34
|
+
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const position = user.getUserPosition(order.marketIndex) ||
|
|
38
|
+
user.getEmptyPosition(order.marketIndex);
|
|
39
|
+
// if no position exists, it's risk increasing
|
|
40
|
+
if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// if position is long and order is long
|
|
44
|
+
if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(order.direction, 'long')) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
// if position is short and order is short
|
|
48
|
+
if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
|
|
49
|
+
(0, types_1.isVariant)(order.direction, 'short')) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
exports.isOrderRiskIncreasingInSameDirection = isOrderRiskIncreasingInSameDirection;
|
package/lib/orders.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { Market, Order, UserAccount, UserPosition } from './types';
|
|
3
|
-
import { BN } from '.';
|
|
3
|
+
import { BN, ClearingHouseUser } from '.';
|
|
4
4
|
export declare function calculateNewStateAfterOrder(userAccount: UserAccount, userPosition: UserPosition, market: Market, order: Order): [UserAccount, UserPosition, Market] | null;
|
|
5
|
+
export declare function calculateBaseAssetAmountMarketCanExecute(market: Market, order: Order): BN;
|
|
5
6
|
export declare function calculateAmountToTradeForLimit(market: Market, order: Order): BN;
|
|
6
7
|
export declare function calculateAmountToTradeForTriggerLimit(market: Market, order: Order): BN;
|
|
8
|
+
export declare function calculateBaseAssetAmountUserCanExecute(market: Market, order: Order, user: ClearingHouseUser): BN;
|
package/lib/orders.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateNewStateAfterOrder = void 0;
|
|
3
|
+
exports.calculateBaseAssetAmountUserCanExecute = exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute = exports.calculateNewStateAfterOrder = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
|
+
const _1 = require(".");
|
|
5
6
|
const market_1 = require("./math/market");
|
|
6
7
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
7
8
|
const amm_1 = require("./math/amm");
|
|
@@ -10,7 +11,7 @@ function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
|
|
|
10
11
|
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
11
12
|
return null;
|
|
12
13
|
}
|
|
13
|
-
const baseAssetAmountToTrade =
|
|
14
|
+
const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(market, order);
|
|
14
15
|
if (baseAssetAmountToTrade.lt(market.amm.minimumBaseAssetTradeSize)) {
|
|
15
16
|
return null;
|
|
16
17
|
}
|
|
@@ -79,7 +80,7 @@ function calculateAmountSwapped(marketBefore, marketAfter) {
|
|
|
79
80
|
baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
|
|
80
81
|
};
|
|
81
82
|
}
|
|
82
|
-
function
|
|
83
|
+
function calculateBaseAssetAmountMarketCanExecute(market, order) {
|
|
83
84
|
if ((0, types_1.isVariant)(order.orderType, 'limit')) {
|
|
84
85
|
return calculateAmountToTradeForLimit(market, order);
|
|
85
86
|
}
|
|
@@ -94,6 +95,7 @@ function calculateAmountToTrade(market, order) {
|
|
|
94
95
|
return calculateAmountToTradeForTriggerMarket(market, order);
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
exports.calculateBaseAssetAmountMarketCanExecute = calculateBaseAssetAmountMarketCanExecute;
|
|
97
99
|
function calculateAmountToTradeForLimit(market, order) {
|
|
98
100
|
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, order.price);
|
|
99
101
|
// Check that directions are the same
|
|
@@ -134,3 +136,29 @@ function isTriggerConditionSatisfied(market, order) {
|
|
|
134
136
|
return markPrice.lt(order.triggerPrice);
|
|
135
137
|
}
|
|
136
138
|
}
|
|
139
|
+
function calculateBaseAssetAmountUserCanExecute(market, order, user) {
|
|
140
|
+
const maxLeverage = user.getMaxLeverage('Initial');
|
|
141
|
+
const freeCollateral = user.getFreeCollateral();
|
|
142
|
+
let quoteAssetAmount;
|
|
143
|
+
if ((0, _1.isOrderRiskIncreasingInSameDirection)(user, order)) {
|
|
144
|
+
quoteAssetAmount = freeCollateral.mul(maxLeverage).div(_1.TEN_THOUSAND);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const position = user.getUserPosition(order.marketIndex) ||
|
|
148
|
+
user.getEmptyPosition(order.marketIndex);
|
|
149
|
+
const positionValue = (0, _1.calculateBaseAssetValue)(market, position);
|
|
150
|
+
quoteAssetAmount = freeCollateral
|
|
151
|
+
.mul(maxLeverage)
|
|
152
|
+
.div(_1.TEN_THOUSAND)
|
|
153
|
+
.add(positionValue.mul(numericConstants_1.TWO));
|
|
154
|
+
}
|
|
155
|
+
if (quoteAssetAmount.lte(numericConstants_1.ZERO)) {
|
|
156
|
+
return numericConstants_1.ZERO;
|
|
157
|
+
}
|
|
158
|
+
const baseAssetReservesBefore = market.amm.baseAssetReserve;
|
|
159
|
+
const [_, baseAssetReservesAfter] = (0, _1.calculateAmmReservesAfterSwap)(market.amm, 'quote', quoteAssetAmount, (0, types_1.isVariant)(order.direction, 'long')
|
|
160
|
+
? types_1.SwapDirection.ADD
|
|
161
|
+
: types_1.SwapDirection.REMOVE);
|
|
162
|
+
return baseAssetReservesBefore.sub(baseAssetReservesAfter).abs();
|
|
163
|
+
}
|
|
164
|
+
exports.calculateBaseAssetAmountUserCanExecute = calculateBaseAssetAmountUserCanExecute;
|
package/package.json
CHANGED
package/src/math/orders.ts
CHANGED
|
@@ -42,3 +42,36 @@ export function isOrderRiskIncreasing(
|
|
|
42
42
|
|
|
43
43
|
return false;
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
export function isOrderRiskIncreasingInSameDirection(
|
|
47
|
+
user: ClearingHouseUser,
|
|
48
|
+
order: Order
|
|
49
|
+
): boolean {
|
|
50
|
+
if (isVariant(order.status, 'init')) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const position =
|
|
55
|
+
user.getUserPosition(order.marketIndex) ||
|
|
56
|
+
user.getEmptyPosition(order.marketIndex);
|
|
57
|
+
|
|
58
|
+
// if no position exists, it's risk increasing
|
|
59
|
+
if (position.baseAssetAmount.eq(ZERO)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// if position is long and order is long
|
|
64
|
+
if (position.baseAssetAmount.gt(ZERO) && isVariant(order.direction, 'long')) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// if position is short and order is short
|
|
69
|
+
if (
|
|
70
|
+
position.baseAssetAmount.lt(ZERO) &&
|
|
71
|
+
isVariant(order.direction, 'short')
|
|
72
|
+
) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return false;
|
|
77
|
+
}
|
package/src/orders.ts
CHANGED
|
@@ -3,16 +3,25 @@ import {
|
|
|
3
3
|
Market,
|
|
4
4
|
Order,
|
|
5
5
|
PositionDirection,
|
|
6
|
+
SwapDirection,
|
|
6
7
|
UserAccount,
|
|
7
8
|
UserPosition,
|
|
8
9
|
} from './types';
|
|
9
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
BN,
|
|
12
|
+
calculateAmmReservesAfterSwap,
|
|
13
|
+
calculateBaseAssetValue,
|
|
14
|
+
ClearingHouseUser,
|
|
15
|
+
isOrderRiskIncreasingInSameDirection,
|
|
16
|
+
TEN_THOUSAND,
|
|
17
|
+
} from '.';
|
|
10
18
|
import {
|
|
11
19
|
calculateMarkPrice,
|
|
12
20
|
calculateNewMarketAfterTrade,
|
|
13
21
|
} from './math/market';
|
|
14
22
|
import {
|
|
15
23
|
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
24
|
+
TWO,
|
|
16
25
|
PEG_PRECISION,
|
|
17
26
|
ZERO,
|
|
18
27
|
} from './constants/numericConstants';
|
|
@@ -32,7 +41,10 @@ export function calculateNewStateAfterOrder(
|
|
|
32
41
|
return null;
|
|
33
42
|
}
|
|
34
43
|
|
|
35
|
-
const baseAssetAmountToTrade =
|
|
44
|
+
const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(
|
|
45
|
+
market,
|
|
46
|
+
order
|
|
47
|
+
);
|
|
36
48
|
if (baseAssetAmountToTrade.lt(market.amm.minimumBaseAssetTradeSize)) {
|
|
37
49
|
return null;
|
|
38
50
|
}
|
|
@@ -157,7 +169,10 @@ function calculateAmountSwapped(
|
|
|
157
169
|
};
|
|
158
170
|
}
|
|
159
171
|
|
|
160
|
-
function
|
|
172
|
+
export function calculateBaseAssetAmountMarketCanExecute(
|
|
173
|
+
market: Market,
|
|
174
|
+
order: Order
|
|
175
|
+
): BN {
|
|
161
176
|
if (isVariant(order.orderType, 'limit')) {
|
|
162
177
|
return calculateAmountToTradeForLimit(market, order);
|
|
163
178
|
} else if (isVariant(order.orderType, 'triggerLimit')) {
|
|
@@ -234,3 +249,41 @@ function isTriggerConditionSatisfied(market: Market, order: Order): boolean {
|
|
|
234
249
|
return markPrice.lt(order.triggerPrice);
|
|
235
250
|
}
|
|
236
251
|
}
|
|
252
|
+
|
|
253
|
+
export function calculateBaseAssetAmountUserCanExecute(
|
|
254
|
+
market: Market,
|
|
255
|
+
order: Order,
|
|
256
|
+
user: ClearingHouseUser
|
|
257
|
+
): BN {
|
|
258
|
+
const maxLeverage = user.getMaxLeverage('Initial');
|
|
259
|
+
const freeCollateral = user.getFreeCollateral();
|
|
260
|
+
let quoteAssetAmount: BN;
|
|
261
|
+
if (isOrderRiskIncreasingInSameDirection(user, order)) {
|
|
262
|
+
quoteAssetAmount = freeCollateral.mul(maxLeverage).div(TEN_THOUSAND);
|
|
263
|
+
} else {
|
|
264
|
+
const position =
|
|
265
|
+
user.getUserPosition(order.marketIndex) ||
|
|
266
|
+
user.getEmptyPosition(order.marketIndex);
|
|
267
|
+
const positionValue = calculateBaseAssetValue(market, position);
|
|
268
|
+
quoteAssetAmount = freeCollateral
|
|
269
|
+
.mul(maxLeverage)
|
|
270
|
+
.div(TEN_THOUSAND)
|
|
271
|
+
.add(positionValue.mul(TWO));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (quoteAssetAmount.lte(ZERO)) {
|
|
275
|
+
return ZERO;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const baseAssetReservesBefore = market.amm.baseAssetReserve;
|
|
279
|
+
const [_, baseAssetReservesAfter] = calculateAmmReservesAfterSwap(
|
|
280
|
+
market.amm,
|
|
281
|
+
'quote',
|
|
282
|
+
quoteAssetAmount,
|
|
283
|
+
isVariant(order.direction, 'long')
|
|
284
|
+
? SwapDirection.ADD
|
|
285
|
+
: SwapDirection.REMOVE
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
return baseAssetReservesBefore.sub(baseAssetReservesAfter).abs();
|
|
289
|
+
}
|