@drift-labs/sdk 0.1.32 → 0.1.34-master.1
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/pollingClearingHouseAccountSubscriber.d.ts +1 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +17 -4
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +1 -0
- package/lib/accounts/pollingUserAccountSubscriber.js +17 -3
- package/lib/admin.d.ts +1 -0
- package/lib/admin.js +11 -0
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/idl/clearing_house.json +40 -2
- package/lib/math/amm.d.ts +7 -2
- package/lib/math/amm.js +45 -6
- package/lib/math/funding.js +3 -1
- package/lib/math/market.d.ts +15 -0
- package/lib/math/market.js +29 -2
- package/lib/math/orders.js +4 -3
- package/lib/math/trade.d.ts +3 -1
- package/lib/math/trade.js +18 -6
- package/lib/orders.js +38 -5
- package/lib/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +19 -4
- package/src/accounts/pollingUserAccountSubscriber.ts +20 -3
- package/src/admin.ts +17 -0
- package/src/constants/numericConstants.ts +2 -0
- package/src/idl/clearing_house.json +40 -2
- package/src/math/amm.ts +71 -6
- package/src/math/funding.ts +11 -8
- package/src/math/market.ts +47 -1
- package/src/math/orders.ts +6 -3
- package/src/math/trade.ts +24 -13
- package/src/orders.ts +51 -7
- package/src/types.ts +2 -1
- package/src/assert/assert.js +0 -10
- package/src/assert/assert.js.map +0 -1
- package/src/math/conversion.js +0 -16
- package/src/math/conversion.js.map +0 -1
- package/src/math/funding.js +0 -223
- package/src/math/funding.js.map +0 -1
- package/src/math/insuranceFund.js +0 -23
- package/src/math/insuranceFund.js.map +0 -1
- package/src/math/position.js +0 -121
- package/src/math/position.js.map +0 -1
- package/src/math/utils.js +0 -27
- package/src/math/utils.js.map +0 -1
- package/src/oracles/switchboardClient.js +0 -60
- package/src/oracles/switchboardClient.js.map +0 -1
- package/src/token/index.js +0 -39
- package/src/token/index.js.map +0 -1
- package/src/tx/defaultTxSender.js +0 -13
- package/src/tx/defaultTxSender.js.map +0 -1
- package/src/tx/types.js +0 -3
- package/src/tx/types.js.map +0 -1
- package/src/tx/utils.js +0 -9
- package/src/tx/utils.js.map +0 -1
- package/src/util/computeUnits.js +0 -17
- package/src/util/computeUnits.js.map +0 -1
- package/src/util/tps.js +0 -17
- package/src/util/tps.js.map +0 -1
|
@@ -35,6 +35,7 @@ export declare class PollingClearingHouseAccountSubscriber implements ClearingHo
|
|
|
35
35
|
getClearingHouseAccounts(): Promise<ClearingHouseAccounts>;
|
|
36
36
|
addToAccountLoader(): Promise<void>;
|
|
37
37
|
fetch(): Promise<void>;
|
|
38
|
+
didSubscriptionSucceed(): boolean;
|
|
38
39
|
unsubscribe(): Promise<void>;
|
|
39
40
|
assertIsSubscribed(): void;
|
|
40
41
|
assertOptionalIsSubscribed(optionalSubscription: ClearingHouseAccountTypes): void;
|
|
@@ -42,11 +42,14 @@ class PollingClearingHouseAccountSubscriber {
|
|
|
42
42
|
yield this.updateAccountsToPoll();
|
|
43
43
|
yield this.addToAccountLoader();
|
|
44
44
|
yield this.fetch();
|
|
45
|
-
this.
|
|
45
|
+
const subscriptionSucceeded = this.didSubscriptionSucceed();
|
|
46
|
+
if (subscriptionSucceeded) {
|
|
47
|
+
this.eventEmitter.emit('update');
|
|
48
|
+
}
|
|
46
49
|
this.isSubscribing = false;
|
|
47
|
-
this.isSubscribed =
|
|
48
|
-
this.subscriptionPromiseResolver(
|
|
49
|
-
return
|
|
50
|
+
this.isSubscribed = subscriptionSucceeded;
|
|
51
|
+
this.subscriptionPromiseResolver(subscriptionSucceeded);
|
|
52
|
+
return subscriptionSucceeded;
|
|
50
53
|
});
|
|
51
54
|
}
|
|
52
55
|
updateAccountsToPoll() {
|
|
@@ -177,6 +180,16 @@ class PollingClearingHouseAccountSubscriber {
|
|
|
177
180
|
}
|
|
178
181
|
});
|
|
179
182
|
}
|
|
183
|
+
didSubscriptionSucceed() {
|
|
184
|
+
let success = true;
|
|
185
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
186
|
+
if (!this[accountToPoll.key]) {
|
|
187
|
+
success = false;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return success;
|
|
192
|
+
}
|
|
180
193
|
unsubscribe() {
|
|
181
194
|
return __awaiter(this, void 0, void 0, function* () {
|
|
182
195
|
if (!this.isSubscribed) {
|
|
@@ -24,6 +24,7 @@ export declare class PollingUserAccountSubscriber implements UserAccountSubscrib
|
|
|
24
24
|
addToAccountLoader(userPublicKeys?: UserPublicKeys): Promise<void>;
|
|
25
25
|
fetchIfUnloaded(): Promise<void>;
|
|
26
26
|
fetch(): Promise<void>;
|
|
27
|
+
didSubscriptionSucceed(): boolean;
|
|
27
28
|
unsubscribe(): Promise<void>;
|
|
28
29
|
assertIsSubscribed(): void;
|
|
29
30
|
getUserAccount(): UserAccount;
|
|
@@ -31,9 +31,12 @@ class PollingUserAccountSubscriber {
|
|
|
31
31
|
}
|
|
32
32
|
yield this.addToAccountLoader();
|
|
33
33
|
yield this.fetchIfUnloaded();
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
const subscriptionSucceeded = this.didSubscriptionSucceed();
|
|
35
|
+
if (subscriptionSucceeded) {
|
|
36
|
+
this.eventEmitter.emit('update');
|
|
37
|
+
}
|
|
38
|
+
this.isSubscribed = subscriptionSucceeded;
|
|
39
|
+
return subscriptionSucceeded;
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
42
|
addToAccountLoader(userPublicKeys) {
|
|
@@ -122,6 +125,17 @@ class PollingUserAccountSubscriber {
|
|
|
122
125
|
}
|
|
123
126
|
});
|
|
124
127
|
}
|
|
128
|
+
didSubscriptionSucceed() {
|
|
129
|
+
let success = true;
|
|
130
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
131
|
+
// userOrders may not exist
|
|
132
|
+
if (accountToPoll.key !== 'userOrders' && !this[accountToPoll.key]) {
|
|
133
|
+
success = false;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return success;
|
|
138
|
+
}
|
|
125
139
|
unsubscribe() {
|
|
126
140
|
return __awaiter(this, void 0, void 0, function* () {
|
|
127
141
|
if (!this.isSubscribed) {
|
package/lib/admin.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class Admin extends ClearingHouse {
|
|
|
24
24
|
withdrawFromInsuranceVaultToMarket(marketIndex: BN, amount: BN): Promise<TransactionSignature>;
|
|
25
25
|
updateAdmin(admin: PublicKey): Promise<TransactionSignature>;
|
|
26
26
|
updateMarginRatio(marketIndex: BN, marginRatioInitial: number, marginRatioPartial: number, marginRatioMaintenance: number): Promise<TransactionSignature>;
|
|
27
|
+
updateMarketBaseSpread(marketIndex: BN, baseSpread: number): Promise<TransactionSignature>;
|
|
27
28
|
updatePartialLiquidationClosePercentage(numerator: BN, denominator: BN): Promise<TransactionSignature>;
|
|
28
29
|
updatePartialLiquidationPenaltyPercentage(numerator: BN, denominator: BN): Promise<TransactionSignature>;
|
|
29
30
|
updateFullLiquidationPenaltyPercentage(numerator: BN, denominator: BN): Promise<TransactionSignature>;
|
package/lib/admin.js
CHANGED
|
@@ -338,6 +338,17 @@ class Admin extends clearingHouse_1.ClearingHouse {
|
|
|
338
338
|
});
|
|
339
339
|
});
|
|
340
340
|
}
|
|
341
|
+
updateMarketBaseSpread(marketIndex, baseSpread) {
|
|
342
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
343
|
+
return yield this.program.rpc.updateMarketBaseSpread(marketIndex, baseSpread, {
|
|
344
|
+
accounts: {
|
|
345
|
+
admin: this.wallet.publicKey,
|
|
346
|
+
state: yield this.getStatePublicKey(),
|
|
347
|
+
markets: this.getStateAccount().markets,
|
|
348
|
+
},
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
}
|
|
341
352
|
updatePartialLiquidationClosePercentage(numerator, denominator) {
|
|
342
353
|
return __awaiter(this, void 0, void 0, function* () {
|
|
343
354
|
return yield this.program.rpc.updatePartialLiquidationClosePercentage(numerator, denominator, {
|
|
@@ -6,6 +6,7 @@ export declare const TWO: BN;
|
|
|
6
6
|
export declare const TEN: BN;
|
|
7
7
|
export declare const TEN_THOUSAND: BN;
|
|
8
8
|
export declare const BN_MAX: BN;
|
|
9
|
+
export declare const TEN_MILLION: BN;
|
|
9
10
|
export declare const MAX_LEVERAGE: BN;
|
|
10
11
|
export declare const QUOTE_PRECISION: BN;
|
|
11
12
|
export declare const MARK_PRICE_PRECISION: BN;
|
|
@@ -17,3 +18,4 @@ export declare const AMM_TO_QUOTE_PRECISION_RATIO: BN;
|
|
|
17
18
|
export declare const PRICE_TO_QUOTE_PRECISION: BN;
|
|
18
19
|
export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
|
|
19
20
|
export declare const MARGIN_PRECISION: BN;
|
|
21
|
+
export declare const BID_ASK_SPREAD_PRECISION: BN;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
3
|
+
exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
4
4
|
const __1 = require("../");
|
|
5
5
|
exports.ZERO = new __1.BN(0);
|
|
6
6
|
exports.ONE = new __1.BN(1);
|
|
@@ -8,6 +8,7 @@ exports.TWO = new __1.BN(2);
|
|
|
8
8
|
exports.TEN = new __1.BN(10);
|
|
9
9
|
exports.TEN_THOUSAND = new __1.BN(10000);
|
|
10
10
|
exports.BN_MAX = new __1.BN(Number.MAX_SAFE_INTEGER);
|
|
11
|
+
exports.TEN_MILLION = exports.TEN_THOUSAND.mul(exports.TEN_THOUSAND);
|
|
11
12
|
exports.MAX_LEVERAGE = new __1.BN(5);
|
|
12
13
|
exports.QUOTE_PRECISION = new __1.BN(Math.pow(10, 6));
|
|
13
14
|
exports.MARK_PRICE_PRECISION = new __1.BN(Math.pow(10, 10));
|
|
@@ -19,3 +20,4 @@ exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.div(exports
|
|
|
19
20
|
exports.PRICE_TO_QUOTE_PRECISION = exports.MARK_PRICE_PRECISION.div(exports.QUOTE_PRECISION);
|
|
20
21
|
exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.mul(exports.PEG_PRECISION).div(exports.QUOTE_PRECISION); // 10^10
|
|
21
22
|
exports.MARGIN_PRECISION = exports.TEN_THOUSAND;
|
|
23
|
+
exports.BID_ASK_SPREAD_PRECISION = new __1.BN(1000000);
|
|
@@ -1905,6 +1905,36 @@
|
|
|
1905
1905
|
}
|
|
1906
1906
|
]
|
|
1907
1907
|
},
|
|
1908
|
+
{
|
|
1909
|
+
"name": "updateMarketBaseSpread",
|
|
1910
|
+
"accounts": [
|
|
1911
|
+
{
|
|
1912
|
+
"name": "admin",
|
|
1913
|
+
"isMut": false,
|
|
1914
|
+
"isSigner": true
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
"name": "state",
|
|
1918
|
+
"isMut": false,
|
|
1919
|
+
"isSigner": false
|
|
1920
|
+
},
|
|
1921
|
+
{
|
|
1922
|
+
"name": "markets",
|
|
1923
|
+
"isMut": true,
|
|
1924
|
+
"isSigner": false
|
|
1925
|
+
}
|
|
1926
|
+
],
|
|
1927
|
+
"args": [
|
|
1928
|
+
{
|
|
1929
|
+
"name": "marketIndex",
|
|
1930
|
+
"type": "u64"
|
|
1931
|
+
},
|
|
1932
|
+
{
|
|
1933
|
+
"name": "baseSpread",
|
|
1934
|
+
"type": "u16"
|
|
1935
|
+
}
|
|
1936
|
+
]
|
|
1937
|
+
},
|
|
1908
1938
|
{
|
|
1909
1939
|
"name": "updateMarketMinimumBaseAssetTradeSize",
|
|
1910
1940
|
"accounts": [
|
|
@@ -3265,9 +3295,17 @@
|
|
|
3265
3295
|
"name": "minimumBaseAssetTradeSize",
|
|
3266
3296
|
"type": "u128"
|
|
3267
3297
|
},
|
|
3298
|
+
{
|
|
3299
|
+
"name": "baseSpread",
|
|
3300
|
+
"type": "u16"
|
|
3301
|
+
},
|
|
3302
|
+
{
|
|
3303
|
+
"name": "padding0",
|
|
3304
|
+
"type": "u16"
|
|
3305
|
+
},
|
|
3268
3306
|
{
|
|
3269
3307
|
"name": "padding1",
|
|
3270
|
-
"type": "
|
|
3308
|
+
"type": "u32"
|
|
3271
3309
|
},
|
|
3272
3310
|
{
|
|
3273
3311
|
"name": "padding2",
|
|
@@ -3585,7 +3623,7 @@
|
|
|
3585
3623
|
"type": "u128"
|
|
3586
3624
|
},
|
|
3587
3625
|
{
|
|
3588
|
-
"name": "
|
|
3626
|
+
"name": "quoteAssetAmountSurplus",
|
|
3589
3627
|
"type": "u128"
|
|
3590
3628
|
},
|
|
3591
3629
|
{
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -20,7 +20,11 @@ export declare type AssetType = 'quote' | 'base';
|
|
|
20
20
|
* @param swapDirection
|
|
21
21
|
* @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
|
|
22
22
|
*/
|
|
23
|
-
export declare function calculateAmmReservesAfterSwap(amm: AMM, inputAssetType: AssetType, swapAmount: BN, swapDirection: SwapDirection): [BN, BN];
|
|
23
|
+
export declare function calculateAmmReservesAfterSwap(amm: Pick<AMM, 'pegMultiplier' | 'quoteAssetReserve' | 'sqrtK' | 'baseAssetReserve'>, inputAssetType: AssetType, swapAmount: BN, swapDirection: SwapDirection): [BN, BN];
|
|
24
|
+
export declare function calculateSpreadReserves(amm: AMM, direction: PositionDirection): {
|
|
25
|
+
baseAssetReserve: BN;
|
|
26
|
+
quoteAssetReserve: BN;
|
|
27
|
+
};
|
|
24
28
|
/**
|
|
25
29
|
* Helper function calculating constant product curve output. Agnostic to whether input asset is quote or base
|
|
26
30
|
*
|
|
@@ -63,6 +67,7 @@ export declare function calculateRepegCost(market: Market, marketIndex: BN, newP
|
|
|
63
67
|
* @returns cost : Precision MARK_PRICE_PRECISION
|
|
64
68
|
*/
|
|
65
69
|
export declare function calculateTerminalPrice(market: Market): BN;
|
|
66
|
-
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN): [BN, PositionDirection];
|
|
70
|
+
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, useSpread: boolean): [BN, PositionDirection];
|
|
67
71
|
export declare function calculateBudgetedK(market: Market, cost: BN): [BN, BN];
|
|
68
72
|
export declare function calculateBudgetedPeg(market: Market, cost: BN): BN;
|
|
73
|
+
export declare function calculateQuoteAssetAmountSwapped(quoteAssetReserves: BN, pegMultiplier: BN, swapDirection: SwapDirection): BN;
|
package/lib/math/amm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.calculateRepegCost = exports.calculateAdjustKCost = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
|
|
3
|
+
exports.calculateQuoteAssetAmountSwapped = exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.calculateRepegCost = exports.calculateAdjustKCost = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const position_1 = require("./position");
|
|
@@ -51,6 +51,28 @@ function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDire
|
|
|
51
51
|
return [newQuoteAssetReserve, newBaseAssetReserve];
|
|
52
52
|
}
|
|
53
53
|
exports.calculateAmmReservesAfterSwap = calculateAmmReservesAfterSwap;
|
|
54
|
+
function calculateSpreadReserves(amm, direction) {
|
|
55
|
+
if (amm.baseSpread === 0) {
|
|
56
|
+
return {
|
|
57
|
+
baseAssetReserve: amm.baseAssetReserve,
|
|
58
|
+
quoteAssetReserve: amm.quoteAssetReserve,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const quoteAsserReserveDelta = amm.quoteAssetReserve.div(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(new anchor_1.BN(amm.baseSpread / 4)));
|
|
62
|
+
let quoteAssetReserve;
|
|
63
|
+
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
64
|
+
quoteAssetReserve = amm.quoteAssetReserve.add(quoteAsserReserveDelta);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
quoteAssetReserve = amm.quoteAssetReserve.sub(quoteAsserReserveDelta);
|
|
68
|
+
}
|
|
69
|
+
const baseAssetReserve = amm.sqrtK.mul(amm.sqrtK).div(quoteAssetReserve);
|
|
70
|
+
return {
|
|
71
|
+
baseAssetReserve,
|
|
72
|
+
quoteAssetReserve,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
exports.calculateSpreadReserves = calculateSpreadReserves;
|
|
54
76
|
/**
|
|
55
77
|
* Helper function calculating constant product curve output. Agnostic to whether input asset is quote or base
|
|
56
78
|
*
|
|
@@ -193,7 +215,7 @@ function calculateTerminalPrice(market) {
|
|
|
193
215
|
return terminalPrice;
|
|
194
216
|
}
|
|
195
217
|
exports.calculateTerminalPrice = calculateTerminalPrice;
|
|
196
|
-
function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
|
|
218
|
+
function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, useSpread) {
|
|
197
219
|
const invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
198
220
|
const newBaseAssetReserveSquared = invariant
|
|
199
221
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
@@ -201,15 +223,22 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
|
|
|
201
223
|
.div(limit_price)
|
|
202
224
|
.div(numericConstants_1.PEG_PRECISION);
|
|
203
225
|
const newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
|
|
204
|
-
|
|
226
|
+
let baseAssetReserveBefore;
|
|
227
|
+
if (useSpread) {
|
|
228
|
+
baseAssetReserveBefore = calculateSpreadReserves(amm, direction).baseAssetReserve;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
baseAssetReserveBefore = amm.baseAssetReserve;
|
|
232
|
+
}
|
|
233
|
+
if (newBaseAssetReserve.gt(baseAssetReserveBefore)) {
|
|
205
234
|
return [
|
|
206
|
-
newBaseAssetReserve.sub(
|
|
235
|
+
newBaseAssetReserve.sub(baseAssetReserveBefore),
|
|
207
236
|
types_1.PositionDirection.SHORT,
|
|
208
237
|
];
|
|
209
238
|
}
|
|
210
|
-
else if (newBaseAssetReserve.lt(
|
|
239
|
+
else if (newBaseAssetReserve.lt(baseAssetReserveBefore)) {
|
|
211
240
|
return [
|
|
212
|
-
|
|
241
|
+
baseAssetReserveBefore.sub(newBaseAssetReserve),
|
|
213
242
|
types_1.PositionDirection.LONG,
|
|
214
243
|
];
|
|
215
244
|
}
|
|
@@ -282,3 +311,13 @@ function calculateBudgetedPeg(market, cost) {
|
|
|
282
311
|
return newPeg;
|
|
283
312
|
}
|
|
284
313
|
exports.calculateBudgetedPeg = calculateBudgetedPeg;
|
|
314
|
+
function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swapDirection) {
|
|
315
|
+
let quoteAssetAmount = quoteAssetReserves
|
|
316
|
+
.mul(pegMultiplier)
|
|
317
|
+
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
318
|
+
if ((0, types_1.isVariant)(swapDirection, 'remove')) {
|
|
319
|
+
quoteAssetAmount = quoteAssetAmount.add(numericConstants_1.ONE);
|
|
320
|
+
}
|
|
321
|
+
return quoteAssetAmount;
|
|
322
|
+
}
|
|
323
|
+
exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
|
package/lib/math/funding.js
CHANGED
|
@@ -66,7 +66,9 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
|
|
|
66
66
|
.mul(lastOracleTwapWithMantissa)
|
|
67
67
|
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
68
68
|
.add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
|
|
69
|
-
.div(timeSinceLastMarkChange
|
|
69
|
+
.div(timeSinceLastMarkChange
|
|
70
|
+
.add(oracleTwapTimeSinceLastUpdate)
|
|
71
|
+
.add(oracleInvalidDuration));
|
|
70
72
|
}
|
|
71
73
|
const twapSpread = lastMarkTwapWithMantissa.sub(lastOracleTwapWithMantissa);
|
|
72
74
|
const twapSpreadPct = twapSpread
|
package/lib/math/market.d.ts
CHANGED
|
@@ -9,5 +9,20 @@ import { OraclePriceData } from '../oracles/types';
|
|
|
9
9
|
* @return markPrice : Precision MARK_PRICE_PRECISION
|
|
10
10
|
*/
|
|
11
11
|
export declare function calculateMarkPrice(market: Market): BN;
|
|
12
|
+
/**
|
|
13
|
+
* Calculates market bid price
|
|
14
|
+
*
|
|
15
|
+
* @param market
|
|
16
|
+
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateBidPrice(market: Market): BN;
|
|
19
|
+
/**
|
|
20
|
+
* Calculates market ask price
|
|
21
|
+
*
|
|
22
|
+
* @param market
|
|
23
|
+
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
24
|
+
*/
|
|
25
|
+
export declare function calculateAskPrice(market: Market): BN;
|
|
12
26
|
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: Market): Market;
|
|
13
27
|
export declare function calculateMarkOracleSpread(market: Market, oraclePriceData: OraclePriceData): BN;
|
|
28
|
+
export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
|
package/lib/math/market.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateMarkPrice = void 0;
|
|
3
|
+
exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
4
5
|
const amm_1 = require("./amm");
|
|
5
6
|
/**
|
|
6
7
|
* Calculates market mark price
|
|
@@ -12,6 +13,28 @@ function calculateMarkPrice(market) {
|
|
|
12
13
|
return (0, amm_1.calculatePrice)(market.amm.baseAssetReserve, market.amm.quoteAssetReserve, market.amm.pegMultiplier);
|
|
13
14
|
}
|
|
14
15
|
exports.calculateMarkPrice = calculateMarkPrice;
|
|
16
|
+
/**
|
|
17
|
+
* Calculates market bid price
|
|
18
|
+
*
|
|
19
|
+
* @param market
|
|
20
|
+
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
21
|
+
*/
|
|
22
|
+
function calculateBidPrice(market) {
|
|
23
|
+
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, types_1.PositionDirection.SHORT);
|
|
24
|
+
return (0, amm_1.calculatePrice)(baseAssetReserve, quoteAssetReserve, market.amm.pegMultiplier);
|
|
25
|
+
}
|
|
26
|
+
exports.calculateBidPrice = calculateBidPrice;
|
|
27
|
+
/**
|
|
28
|
+
* Calculates market ask price
|
|
29
|
+
*
|
|
30
|
+
* @param market
|
|
31
|
+
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
32
|
+
*/
|
|
33
|
+
function calculateAskPrice(market) {
|
|
34
|
+
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, types_1.PositionDirection.LONG);
|
|
35
|
+
return (0, amm_1.calculatePrice)(baseAssetReserve, quoteAssetReserve, market.amm.pegMultiplier);
|
|
36
|
+
}
|
|
37
|
+
exports.calculateAskPrice = calculateAskPrice;
|
|
15
38
|
function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
|
|
16
39
|
const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', direction));
|
|
17
40
|
const newAmm = Object.assign({}, market.amm);
|
|
@@ -24,6 +47,10 @@ function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
|
|
|
24
47
|
exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
|
|
25
48
|
function calculateMarkOracleSpread(market, oraclePriceData) {
|
|
26
49
|
const markPrice = calculateMarkPrice(market);
|
|
27
|
-
return markPrice
|
|
50
|
+
return calculateOracleSpread(markPrice, oraclePriceData);
|
|
28
51
|
}
|
|
29
52
|
exports.calculateMarkOracleSpread = calculateMarkOracleSpread;
|
|
53
|
+
function calculateOracleSpread(price, oraclePriceData) {
|
|
54
|
+
return price.sub(oraclePriceData.price);
|
|
55
|
+
}
|
|
56
|
+
exports.calculateOracleSpread = calculateOracleSpread;
|
package/lib/math/orders.js
CHANGED
|
@@ -59,14 +59,15 @@ function isOrderReduceOnly(user, order) {
|
|
|
59
59
|
const position = user.getUserPosition(order.marketIndex) ||
|
|
60
60
|
user.getEmptyPosition(order.marketIndex);
|
|
61
61
|
// if position is long and order is long
|
|
62
|
-
if (position.baseAssetAmount.
|
|
62
|
+
if (position.baseAssetAmount.gte(numericConstants_1.ZERO) &&
|
|
63
|
+
(0, types_1.isVariant)(order.direction, 'long')) {
|
|
63
64
|
return false;
|
|
64
65
|
}
|
|
65
66
|
// if position is short and order is short
|
|
66
|
-
if (position.baseAssetAmount.
|
|
67
|
+
if (position.baseAssetAmount.lte(numericConstants_1.ZERO) &&
|
|
67
68
|
(0, types_1.isVariant)(order.direction, 'short')) {
|
|
68
69
|
return false;
|
|
69
70
|
}
|
|
70
|
-
return
|
|
71
|
+
return true;
|
|
71
72
|
}
|
|
72
73
|
exports.isOrderReduceOnly = isOrderReduceOnly;
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -24,11 +24,13 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
|
|
|
24
24
|
* @param direction
|
|
25
25
|
* @param amount
|
|
26
26
|
* @param market
|
|
27
|
+
* @param inputAssetType
|
|
28
|
+
* @param useSpread
|
|
27
29
|
* @return
|
|
28
30
|
* | 'acquiredBase' => positive/negative change in user's base : BN TODO-PRECISION
|
|
29
31
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
30
32
|
*/
|
|
31
|
-
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType): [BN, BN];
|
|
33
|
+
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN];
|
|
32
34
|
/**
|
|
33
35
|
* calculateTargetPriceTrade
|
|
34
36
|
* simple function for finding arbitraging trades
|
package/lib/math/trade.js
CHANGED
|
@@ -56,21 +56,33 @@ exports.calculateTradeSlippage = calculateTradeSlippage;
|
|
|
56
56
|
* @param direction
|
|
57
57
|
* @param amount
|
|
58
58
|
* @param market
|
|
59
|
+
* @param inputAssetType
|
|
60
|
+
* @param useSpread
|
|
59
61
|
* @return
|
|
60
62
|
* | 'acquiredBase' => positive/negative change in user's base : BN TODO-PRECISION
|
|
61
63
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
62
64
|
*/
|
|
63
|
-
function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote') {
|
|
65
|
+
function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
|
|
64
66
|
if (amount.eq(numericConstants_1.ZERO)) {
|
|
65
67
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
66
68
|
}
|
|
67
69
|
const swapDirection = (0, amm_1.getSwapDirection)(inputAssetType, direction);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
let amm;
|
|
71
|
+
if (useSpread && market.amm.baseSpread > 0) {
|
|
72
|
+
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
|
|
73
|
+
amm = {
|
|
74
|
+
baseAssetReserve,
|
|
75
|
+
quoteAssetReserve,
|
|
76
|
+
sqrtK: market.amm.sqrtK,
|
|
77
|
+
pegMultiplier: market.amm.pegMultiplier,
|
|
78
|
+
};
|
|
73
79
|
}
|
|
80
|
+
else {
|
|
81
|
+
amm = market.amm;
|
|
82
|
+
}
|
|
83
|
+
const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(amm, inputAssetType, amount, swapDirection);
|
|
84
|
+
const acquiredBase = amm.baseAssetReserve.sub(newBaseAssetReserve);
|
|
85
|
+
const acquiredQuote = amm.quoteAssetReserve.sub(newQuoteAssetReserve);
|
|
74
86
|
return [acquiredBase, acquiredQuote];
|
|
75
87
|
}
|
|
76
88
|
exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
package/lib/orders.js
CHANGED
|
@@ -112,7 +112,7 @@ function calculateAmountToTradeForLimit(market, order, oraclePriceData) {
|
|
|
112
112
|
limitPrice = floatingPrice;
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice);
|
|
115
|
+
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, !order.postOnly);
|
|
116
116
|
// Check that directions are the same
|
|
117
117
|
const sameDirection = isSameDirection(direction, order.direction);
|
|
118
118
|
if (!sameDirection) {
|
|
@@ -170,10 +170,43 @@ function calculateBaseAssetAmountUserCanExecute(market, order, user) {
|
|
|
170
170
|
if (quoteAssetAmount.lte(numericConstants_1.ZERO)) {
|
|
171
171
|
return numericConstants_1.ZERO;
|
|
172
172
|
}
|
|
173
|
-
const
|
|
174
|
-
const [_, baseAssetReservesAfter] = (0, _1.calculateAmmReservesAfterSwap)(market.amm, 'quote', quoteAssetAmount, (0, types_1.isVariant)(order.direction, 'long')
|
|
173
|
+
const swapDirection = (0, types_1.isVariant)(order.direction, 'long')
|
|
175
174
|
? types_1.SwapDirection.ADD
|
|
176
|
-
: types_1.SwapDirection.REMOVE
|
|
177
|
-
|
|
175
|
+
: types_1.SwapDirection.REMOVE;
|
|
176
|
+
const useSpread = !order.postOnly;
|
|
177
|
+
let amm;
|
|
178
|
+
if (useSpread) {
|
|
179
|
+
const { baseAssetReserve, quoteAssetReserve } = (0, _1.calculateSpreadReserves)(market.amm, order.direction);
|
|
180
|
+
amm = {
|
|
181
|
+
baseAssetReserve,
|
|
182
|
+
quoteAssetReserve,
|
|
183
|
+
sqrtK: market.amm.sqrtK,
|
|
184
|
+
pegMultiplier: market.amm.pegMultiplier,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
amm = market.amm;
|
|
189
|
+
}
|
|
190
|
+
const baseAssetReservesBefore = amm.baseAssetReserve;
|
|
191
|
+
const [_, baseAssetReservesAfter] = (0, _1.calculateAmmReservesAfterSwap)(amm, 'quote', quoteAssetAmount, swapDirection);
|
|
192
|
+
let baseAssetAmount = baseAssetReservesBefore
|
|
193
|
+
.sub(baseAssetReservesAfter)
|
|
194
|
+
.abs();
|
|
195
|
+
if (order.reduceOnly) {
|
|
196
|
+
const position = user.getUserPosition(order.marketIndex) ||
|
|
197
|
+
user.getEmptyPosition(order.marketIndex);
|
|
198
|
+
if ((0, types_1.isVariant)(order.direction, 'long') &&
|
|
199
|
+
position.baseAssetAmount.gte(numericConstants_1.ZERO)) {
|
|
200
|
+
baseAssetAmount = numericConstants_1.ZERO;
|
|
201
|
+
}
|
|
202
|
+
else if ((0, types_1.isVariant)(order.direction, 'short') &&
|
|
203
|
+
position.baseAssetAmount.lte(numericConstants_1.ZERO)) {
|
|
204
|
+
baseAssetAmount = numericConstants_1.ZERO;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
_1.BN.min(baseAssetAmount, position.baseAssetAmount.abs());
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return baseAssetAmount;
|
|
178
211
|
}
|
|
179
212
|
exports.calculateBaseAssetAmountUserCanExecute = calculateBaseAssetAmountUserCanExecute;
|
package/lib/types.d.ts
CHANGED
|
@@ -168,7 +168,7 @@ export declare type TradeRecord = {
|
|
|
168
168
|
markPriceBefore: BN;
|
|
169
169
|
markPriceAfter: BN;
|
|
170
170
|
fee: BN;
|
|
171
|
-
|
|
171
|
+
quoteAssetAmountSurplus: BN;
|
|
172
172
|
refereeDiscount: BN;
|
|
173
173
|
tokenDiscount: BN;
|
|
174
174
|
marketIndex: BN;
|
|
@@ -314,6 +314,7 @@ export declare type AMM = {
|
|
|
314
314
|
minimumQuoteAssetTradeSize: BN;
|
|
315
315
|
minimumBaseAssetTradeSize: BN;
|
|
316
316
|
lastOraclePrice: BN;
|
|
317
|
+
baseSpread: number;
|
|
317
318
|
};
|
|
318
319
|
export declare type UserPosition = {
|
|
319
320
|
baseAssetAmount: BN;
|
package/package.json
CHANGED
|
@@ -86,13 +86,17 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
86
86
|
await this.updateAccountsToPoll();
|
|
87
87
|
await this.addToAccountLoader();
|
|
88
88
|
await this.fetch();
|
|
89
|
-
this.
|
|
89
|
+
const subscriptionSucceeded = this.didSubscriptionSucceed();
|
|
90
|
+
|
|
91
|
+
if (subscriptionSucceeded) {
|
|
92
|
+
this.eventEmitter.emit('update');
|
|
93
|
+
}
|
|
90
94
|
|
|
91
95
|
this.isSubscribing = false;
|
|
92
|
-
this.isSubscribed =
|
|
93
|
-
this.subscriptionPromiseResolver(
|
|
96
|
+
this.isSubscribed = subscriptionSucceeded;
|
|
97
|
+
this.subscriptionPromiseResolver(subscriptionSucceeded);
|
|
94
98
|
|
|
95
|
-
return
|
|
99
|
+
return subscriptionSucceeded;
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
async updateAccountsToPoll(): Promise<void> {
|
|
@@ -254,6 +258,17 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
254
258
|
}
|
|
255
259
|
}
|
|
256
260
|
|
|
261
|
+
didSubscriptionSucceed(): boolean {
|
|
262
|
+
let success = true;
|
|
263
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
264
|
+
if (!this[accountToPoll.key]) {
|
|
265
|
+
success = false;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return success;
|
|
270
|
+
}
|
|
271
|
+
|
|
257
272
|
public async unsubscribe(): Promise<void> {
|
|
258
273
|
if (!this.isSubscribed) {
|
|
259
274
|
return;
|
|
@@ -53,10 +53,15 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
53
53
|
|
|
54
54
|
await this.addToAccountLoader();
|
|
55
55
|
await this.fetchIfUnloaded();
|
|
56
|
-
this.eventEmitter.emit('update');
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const subscriptionSucceeded = this.didSubscriptionSucceed();
|
|
58
|
+
|
|
59
|
+
if (subscriptionSucceeded) {
|
|
60
|
+
this.eventEmitter.emit('update');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.isSubscribed = subscriptionSucceeded;
|
|
64
|
+
return subscriptionSucceeded;
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
async addToAccountLoader(userPublicKeys?: UserPublicKeys): Promise<void> {
|
|
@@ -168,6 +173,18 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
168
173
|
}
|
|
169
174
|
}
|
|
170
175
|
|
|
176
|
+
didSubscriptionSucceed(): boolean {
|
|
177
|
+
let success = true;
|
|
178
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
179
|
+
// userOrders may not exist
|
|
180
|
+
if (accountToPoll.key !== 'userOrders' && !this[accountToPoll.key]) {
|
|
181
|
+
success = false;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return success;
|
|
186
|
+
}
|
|
187
|
+
|
|
171
188
|
async unsubscribe(): Promise<void> {
|
|
172
189
|
if (!this.isSubscribed) {
|
|
173
190
|
return;
|