@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.0
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 +6 -6
- package/lib/accounts/bulkAccountLoader.js +81 -95
- package/lib/accounts/bulkUserSubscription.js +13 -57
- package/lib/accounts/fetch.d.ts +4 -0
- package/lib/accounts/fetch.js +18 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
- package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
- package/lib/accounts/pollingOracleSubscriber.js +37 -49
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
- package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
- package/lib/accounts/types.d.ts +34 -41
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
- package/lib/accounts/webSocketAccountSubscriber.js +39 -35
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
- package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
- package/lib/addresses/marketAddresses.d.ts +4 -0
- package/lib/addresses/marketAddresses.js +15 -0
- package/lib/addresses/pda.d.ts +12 -0
- package/lib/addresses/pda.js +83 -0
- package/lib/admin.d.ts +8 -17
- package/lib/admin.js +366 -558
- package/lib/clearingHouse.d.ts +84 -109
- package/lib/clearingHouse.js +778 -899
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -22
- package/lib/clearingHouseUser.js +155 -141
- package/lib/clearingHouseUserConfig.d.ts +14 -0
- package/lib/clearingHouseUserConfig.js +2 -0
- package/lib/config.d.ts +12 -0
- package/lib/config.js +35 -4
- package/lib/constants/banks.d.ts +16 -0
- package/lib/constants/banks.js +34 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +16 -0
- package/lib/constants/numericConstants.js +22 -6
- package/lib/events/eventList.d.ts +22 -0
- package/lib/events/eventList.js +77 -0
- package/lib/events/eventSubscriber.d.ts +34 -0
- package/lib/events/eventSubscriber.js +126 -0
- package/lib/events/fetchLogs.d.ts +13 -0
- package/lib/events/fetchLogs.js +39 -0
- package/lib/events/pollingLogProvider.d.ts +15 -0
- package/lib/events/pollingLogProvider.js +53 -0
- package/lib/events/sort.d.ts +2 -0
- package/lib/events/sort.js +44 -0
- package/lib/events/txEventCache.d.ts +24 -0
- package/lib/events/txEventCache.js +71 -0
- package/lib/events/types.d.ts +49 -0
- package/lib/events/types.js +20 -0
- package/lib/events/webSocketLogProvider.d.ts +12 -0
- package/lib/events/webSocketLogProvider.js +30 -0
- package/lib/examples/makeTradeExample.js +26 -27
- package/lib/factory/bigNum.d.ts +112 -0
- package/lib/factory/bigNum.js +356 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +2213 -2951
- package/lib/index.d.ts +12 -4
- package/lib/index.js +12 -4
- package/lib/math/amm.d.ts +19 -29
- package/lib/math/amm.js +129 -179
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +39 -0
- package/lib/math/bankBalance.d.ts +9 -0
- package/lib/math/bankBalance.js +75 -0
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/conversion.js +1 -5
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +158 -175
- package/lib/math/market.d.ts +6 -6
- package/lib/math/market.js +10 -9
- package/lib/math/orders.d.ts +5 -0
- package/lib/math/orders.js +31 -1
- package/lib/math/position.d.ts +7 -5
- package/lib/math/position.js +27 -27
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +5 -4
- package/lib/math/trade.js +29 -21
- package/lib/mockUSDCFaucet.js +87 -116
- package/lib/oracles/oracleClientCache.d.ts +8 -0
- package/lib/oracles/oracleClientCache.js +19 -0
- package/lib/oracles/pythClient.d.ts +3 -5
- package/lib/oracles/pythClient.js +12 -31
- package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
- package/lib/oracles/quoteAssetOracleClient.js +21 -0
- package/lib/oracles/switchboardClient.d.ts +3 -5
- package/lib/oracles/switchboardClient.js +29 -50
- package/lib/oracles/types.d.ts +6 -1
- package/lib/orders.d.ts +6 -6
- package/lib/orders.js +10 -9
- package/lib/slot/SlotSubscriber.d.ts +12 -0
- package/lib/slot/SlotSubscriber.js +23 -0
- package/lib/tx/retryTxSender.d.ts +2 -2
- package/lib/tx/retryTxSender.js +108 -123
- package/lib/tx/types.d.ts +5 -1
- package/lib/tx/utils.d.ts +1 -1
- package/lib/tx/utils.js +11 -2
- package/lib/types.d.ts +105 -109
- package/lib/types.js +13 -1
- package/lib/userName.d.ts +4 -0
- package/lib/userName.js +20 -0
- package/lib/util/computeUnits.js +10 -21
- package/lib/util/tps.js +11 -22
- package/lib/wallet.js +7 -20
- package/package.json +10 -3
- package/src/accounts/bulkAccountLoader.ts +21 -15
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.ts +41 -70
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.ts +18 -0
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +205 -346
- package/src/clearingHouse.ts +918 -961
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +275 -185
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +43 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +33 -5
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.ts +507 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +2213 -2951
- package/src/index.ts +12 -4
- package/src/math/amm.ts +229 -245
- package/src/math/auction.ts +39 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.ts +12 -9
- package/src/math/market.ts +37 -30
- package/src/math/orders.ts +38 -0
- package/src/math/position.ts +48 -35
- package/src/math/repeg.ts +175 -0
- package/src/math/trade.ts +45 -35
- package/src/math/utils.js +27 -0
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.ts +4 -11
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.ts +11 -24
- package/src/oracles/types.ts +7 -1
- package/src/orders.ts +35 -20
- package/src/slot/SlotSubscriber.ts +32 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.ts +22 -3
- package/src/types.ts +108 -122
- package/src/userName.ts +20 -0
- package/src/util/computeUnits.js +17 -0
- package/src/util/computeUnits.js.map +1 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -10
- package/lib/addresses.js +0 -93
- package/lib/constants/accounts.d.ts +0 -15
- package/lib/constants/accounts.js +0 -18
- package/lib/factory/clearingHouse.d.ts +0 -35
- package/lib/factory/clearingHouse.js +0 -81
- package/lib/factory/clearingHouseUser.d.ts +0 -19
- package/lib/factory/clearingHouseUser.js +0 -34
- package/lib/math/insuranceFund.d.ts +0 -15
- package/lib/math/insuranceFund.js +0 -33
- package/lib/settlement.d.ts +0 -4
- package/lib/settlement.js +0 -10
- package/lib/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -82
- package/src/constants/accounts.ts +0 -26
- package/src/factory/clearingHouse.ts +0 -173
- package/src/factory/clearingHouseUser.ts +0 -73
- package/src/math/insuranceFund.ts +0 -29
- package/src/settlement.ts +0 -9
- package/src/tx/defaultTxSender.ts +0 -24
package/lib/math/orders.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
const auction_1 = require("./auction");
|
|
6
8
|
function isOrderRiskIncreasing(user, order) {
|
|
7
9
|
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
8
10
|
return false;
|
|
@@ -71,3 +73,31 @@ function isOrderReduceOnly(user, order) {
|
|
|
71
73
|
return true;
|
|
72
74
|
}
|
|
73
75
|
exports.isOrderReduceOnly = isOrderReduceOnly;
|
|
76
|
+
function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
|
|
77
|
+
const remainder = baseAssetAmount.mod(stepSize);
|
|
78
|
+
return baseAssetAmount.sub(remainder);
|
|
79
|
+
}
|
|
80
|
+
exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
|
|
81
|
+
function getLimitPrice(order, oraclePriceData, slot) {
|
|
82
|
+
let limitPrice;
|
|
83
|
+
if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
|
|
84
|
+
const floatingPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
85
|
+
if (order.postOnly) {
|
|
86
|
+
limitPrice = (0, types_1.isVariant)(order.direction, 'long')
|
|
87
|
+
? anchor_1.BN.min(order.price, floatingPrice)
|
|
88
|
+
: anchor_1.BN.max(order.price, floatingPrice);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
limitPrice = floatingPrice;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if ((0, types_1.isVariant)(order.orderType, 'market') ||
|
|
95
|
+
(0, types_1.isVariant)(order.orderType, 'triggerMarket')) {
|
|
96
|
+
limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
limitPrice = order.price;
|
|
100
|
+
}
|
|
101
|
+
return limitPrice;
|
|
102
|
+
}
|
|
103
|
+
exports.getLimitPrice = getLimitPrice;
|
package/lib/math/position.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from '../';
|
|
3
|
-
import {
|
|
3
|
+
import { OraclePriceData } from '../oracles/types';
|
|
4
|
+
import { MarketAccount, PositionDirection, UserPosition } from '../types';
|
|
4
5
|
/**
|
|
5
6
|
* calculateBaseAssetValue
|
|
6
7
|
* = market value of closing entire position
|
|
7
8
|
* @param market
|
|
8
9
|
* @param userPosition
|
|
10
|
+
* @param oraclePriceData
|
|
9
11
|
* @returns Base Asset Value. : Precision QUOTE_PRECISION
|
|
10
12
|
*/
|
|
11
|
-
export declare function calculateBaseAssetValue(market:
|
|
13
|
+
export declare function calculateBaseAssetValue(market: MarketAccount, userPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
|
|
12
14
|
/**
|
|
13
15
|
* calculatePositionPNL
|
|
14
16
|
* = BaseAssetAmount * (Avg Exit Price - Avg Entry Price)
|
|
@@ -17,15 +19,15 @@ export declare function calculateBaseAssetValue(market: Market, userPosition: Us
|
|
|
17
19
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
18
20
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
19
21
|
*/
|
|
20
|
-
export declare function calculatePositionPNL(market:
|
|
21
|
-
export declare function calculateSettledPositionPNL(market: Market, marketPosition: UserPosition): BN;
|
|
22
|
+
export declare function calculatePositionPNL(market: MarketAccount, marketPosition: UserPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
|
|
22
23
|
/**
|
|
23
24
|
*
|
|
24
25
|
* @param market
|
|
25
26
|
* @param marketPosition
|
|
26
27
|
* @returns // TODO-PRECISION
|
|
27
28
|
*/
|
|
28
|
-
export declare function calculatePositionFundingPNL(market:
|
|
29
|
+
export declare function calculatePositionFundingPNL(market: MarketAccount, marketPosition: UserPosition): BN;
|
|
30
|
+
export declare function positionIsAvailable(position: UserPosition): boolean;
|
|
29
31
|
/**
|
|
30
32
|
*
|
|
31
33
|
* @param userPosition
|
package/lib/math/position.js
CHANGED
|
@@ -1,34 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.
|
|
3
|
+
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
4
4
|
const __1 = require("../");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
7
7
|
const amm_1 = require("./amm");
|
|
8
|
-
const settlement_1 = require("../settlement");
|
|
9
8
|
/**
|
|
10
9
|
* calculateBaseAssetValue
|
|
11
10
|
* = market value of closing entire position
|
|
12
11
|
* @param market
|
|
13
12
|
* @param userPosition
|
|
13
|
+
* @param oraclePriceData
|
|
14
14
|
* @returns Base Asset Value. : Precision QUOTE_PRECISION
|
|
15
15
|
*/
|
|
16
|
-
function calculateBaseAssetValue(market, userPosition) {
|
|
16
|
+
function calculateBaseAssetValue(market, userPosition, oraclePriceData) {
|
|
17
17
|
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
18
18
|
return numericConstants_1.ZERO;
|
|
19
19
|
}
|
|
20
20
|
const directionToClose = findDirectionToClose(userPosition);
|
|
21
|
-
|
|
21
|
+
let prepegAmm;
|
|
22
|
+
if (market.amm.baseSpread > 0) {
|
|
23
|
+
const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, directionToClose, oraclePriceData);
|
|
24
|
+
prepegAmm = {
|
|
25
|
+
baseAssetReserve,
|
|
26
|
+
quoteAssetReserve,
|
|
27
|
+
sqrtK: sqrtK,
|
|
28
|
+
pegMultiplier: newPeg,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
prepegAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
|
|
33
|
+
}
|
|
34
|
+
const [newQuoteAssetReserve, _] = (0, amm_1.calculateAmmReservesAfterSwap)(prepegAmm, 'base', userPosition.baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', directionToClose));
|
|
22
35
|
switch (directionToClose) {
|
|
23
36
|
case types_1.PositionDirection.SHORT:
|
|
24
|
-
return
|
|
37
|
+
return prepegAmm.quoteAssetReserve
|
|
25
38
|
.sub(newQuoteAssetReserve)
|
|
26
|
-
.mul(
|
|
39
|
+
.mul(prepegAmm.pegMultiplier)
|
|
27
40
|
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
28
41
|
case types_1.PositionDirection.LONG:
|
|
29
42
|
return newQuoteAssetReserve
|
|
30
|
-
.sub(
|
|
31
|
-
.mul(
|
|
43
|
+
.sub(prepegAmm.quoteAssetReserve)
|
|
44
|
+
.mul(prepegAmm.pegMultiplier)
|
|
32
45
|
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
33
46
|
.add(numericConstants_1.ONE);
|
|
34
47
|
}
|
|
@@ -42,11 +55,11 @@ exports.calculateBaseAssetValue = calculateBaseAssetValue;
|
|
|
42
55
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
43
56
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
44
57
|
*/
|
|
45
|
-
function calculatePositionPNL(market, marketPosition, withFunding = false) {
|
|
58
|
+
function calculatePositionPNL(market, marketPosition, withFunding = false, oraclePriceData) {
|
|
46
59
|
if (marketPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
47
60
|
return numericConstants_1.ZERO;
|
|
48
61
|
}
|
|
49
|
-
const baseAssetValue = calculateBaseAssetValue(market, marketPosition);
|
|
62
|
+
const baseAssetValue = calculateBaseAssetValue(market, marketPosition, oraclePriceData);
|
|
50
63
|
let pnl;
|
|
51
64
|
if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
52
65
|
pnl = baseAssetValue.sub(marketPosition.quoteAssetAmount);
|
|
@@ -61,23 +74,6 @@ function calculatePositionPNL(market, marketPosition, withFunding = false) {
|
|
|
61
74
|
return pnl;
|
|
62
75
|
}
|
|
63
76
|
exports.calculatePositionPNL = calculatePositionPNL;
|
|
64
|
-
function calculateSettledPositionPNL(market, marketPosition) {
|
|
65
|
-
let pnl = calculatePositionPNL(market, marketPosition);
|
|
66
|
-
if (pnl.gt(numericConstants_1.ZERO)) {
|
|
67
|
-
try {
|
|
68
|
-
pnl = pnl
|
|
69
|
-
.mul(new __1.BN(settlement_1.SETTLEMENT_RATIOS[marketPosition.marketIndex.toNumber()]))
|
|
70
|
-
.div(settlement_1.SETTLEMENT_RATIO_PRECISION);
|
|
71
|
-
}
|
|
72
|
-
catch (e) {
|
|
73
|
-
console.log(pnl.toString());
|
|
74
|
-
console.log(marketPosition.marketIndex.toNumber());
|
|
75
|
-
throw e;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return pnl;
|
|
79
|
-
}
|
|
80
|
-
exports.calculateSettledPositionPNL = calculateSettledPositionPNL;
|
|
81
77
|
/**
|
|
82
78
|
*
|
|
83
79
|
* @param market
|
|
@@ -104,6 +100,10 @@ function calculatePositionFundingPNL(market, marketPosition) {
|
|
|
104
100
|
return perPositionFundingRate;
|
|
105
101
|
}
|
|
106
102
|
exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
|
|
103
|
+
function positionIsAvailable(position) {
|
|
104
|
+
return position.baseAssetAmount.eq(numericConstants_1.ZERO) && position.openOrders.eq(numericConstants_1.ZERO);
|
|
105
|
+
}
|
|
106
|
+
exports.positionIsAvailable = positionIsAvailable;
|
|
107
107
|
/**
|
|
108
108
|
*
|
|
109
109
|
* @param userPosition
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@project-serum/anchor';
|
|
3
|
+
import { AMM } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Helper function calculating adjust k cost
|
|
6
|
+
* @param amm
|
|
7
|
+
* @param numerator
|
|
8
|
+
* @param denomenator
|
|
9
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
10
|
+
*/
|
|
11
|
+
export declare function calculateAdjustKCost(amm: AMM, numerator: BN, denomenator: BN): BN;
|
|
12
|
+
/**
|
|
13
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
14
|
+
*
|
|
15
|
+
* @param amm
|
|
16
|
+
* @param newPeg
|
|
17
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
18
|
+
*/
|
|
19
|
+
export declare function calculateRepegCost(amm: AMM, newPeg: BN): BN;
|
|
20
|
+
export declare function calculateBudgetedKBN(x: BN, y: BN, budget: BN, Q: BN, d: BN): [BN, BN];
|
|
21
|
+
export declare function calculateBudgetedK(amm: AMM, cost: BN): [BN, BN];
|
|
22
|
+
export declare function calculateBudgetedPeg(amm: AMM, cost: BN, targetPrice: BN): BN;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateBudgetedKBN = exports.calculateRepegCost = exports.calculateAdjustKCost = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
const assert_1 = require("../assert/assert");
|
|
6
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
/**
|
|
8
|
+
* Helper function calculating adjust k cost
|
|
9
|
+
* @param amm
|
|
10
|
+
* @param numerator
|
|
11
|
+
* @param denomenator
|
|
12
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
13
|
+
*/
|
|
14
|
+
function calculateAdjustKCost(amm, numerator, denomenator) {
|
|
15
|
+
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
16
|
+
const x = amm.baseAssetReserve;
|
|
17
|
+
const y = amm.quoteAssetReserve;
|
|
18
|
+
const d = amm.netBaseAssetAmount;
|
|
19
|
+
const Q = amm.pegMultiplier;
|
|
20
|
+
const quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
|
|
21
|
+
const p = numerator.mul(numericConstants_1.MARK_PRICE_PRECISION).div(denomenator);
|
|
22
|
+
const cost = quoteScale
|
|
23
|
+
.div(x.add(d))
|
|
24
|
+
.sub(quoteScale
|
|
25
|
+
.mul(p)
|
|
26
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
27
|
+
.div(x.mul(p).div(numericConstants_1.MARK_PRICE_PRECISION).add(d)))
|
|
28
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
29
|
+
.div(numericConstants_1.PEG_PRECISION);
|
|
30
|
+
return cost.mul(new anchor_1.BN(-1));
|
|
31
|
+
}
|
|
32
|
+
exports.calculateAdjustKCost = calculateAdjustKCost;
|
|
33
|
+
/**
|
|
34
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
35
|
+
*
|
|
36
|
+
* @param amm
|
|
37
|
+
* @param newPeg
|
|
38
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
39
|
+
*/
|
|
40
|
+
function calculateRepegCost(amm, newPeg) {
|
|
41
|
+
const dqar = amm.quoteAssetReserve.sub(amm.terminalQuoteAssetReserve);
|
|
42
|
+
const cost = dqar
|
|
43
|
+
.mul(newPeg.sub(amm.pegMultiplier))
|
|
44
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
45
|
+
.div(numericConstants_1.PEG_PRECISION);
|
|
46
|
+
return cost;
|
|
47
|
+
}
|
|
48
|
+
exports.calculateRepegCost = calculateRepegCost;
|
|
49
|
+
function calculateBudgetedKBN(x, y, budget, Q, d) {
|
|
50
|
+
(0, assert_1.assert)(Q.gt(new anchor_1.BN(0)));
|
|
51
|
+
const C = budget.mul(new anchor_1.BN(-1));
|
|
52
|
+
let dSign = new anchor_1.BN(1);
|
|
53
|
+
if (d.lt(new anchor_1.BN(0))) {
|
|
54
|
+
dSign = new anchor_1.BN(-1);
|
|
55
|
+
}
|
|
56
|
+
const pegged_y_d_d = y
|
|
57
|
+
.mul(d)
|
|
58
|
+
.mul(d)
|
|
59
|
+
.mul(Q)
|
|
60
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
61
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
62
|
+
.div(numericConstants_1.PEG_PRECISION);
|
|
63
|
+
const numer1 = pegged_y_d_d;
|
|
64
|
+
const numer2 = C.mul(d)
|
|
65
|
+
.div(numericConstants_1.QUOTE_PRECISION)
|
|
66
|
+
.mul(x.add(d))
|
|
67
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
68
|
+
.mul(dSign);
|
|
69
|
+
const denom1 = C.mul(x)
|
|
70
|
+
.mul(x.add(d))
|
|
71
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
72
|
+
.div(numericConstants_1.QUOTE_PRECISION);
|
|
73
|
+
const denom2 = pegged_y_d_d;
|
|
74
|
+
const numerator = numer1.sub(numer2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
75
|
+
const denominator = denom1.add(denom2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
76
|
+
return [numerator, denominator];
|
|
77
|
+
}
|
|
78
|
+
exports.calculateBudgetedKBN = calculateBudgetedKBN;
|
|
79
|
+
function calculateBudgetedK(amm, cost) {
|
|
80
|
+
// wolframalpha.com
|
|
81
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
82
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*d*d*Q)
|
|
83
|
+
// numer
|
|
84
|
+
// = y*d*d*Q - Cxd - Cdd
|
|
85
|
+
// = y/x*Q*d*d - Cd - Cd/x
|
|
86
|
+
// = mark - C/d - C/(x)
|
|
87
|
+
// = mark/C - 1/d - 1/x
|
|
88
|
+
// denom
|
|
89
|
+
// = C*x*x + C*x*d + y*d*d*Q
|
|
90
|
+
// = x/d**2 + 1 / d + mark/C
|
|
91
|
+
// todo: assumes k = x * y
|
|
92
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
93
|
+
const x = amm.baseAssetReserve;
|
|
94
|
+
const y = amm.quoteAssetReserve;
|
|
95
|
+
const d = amm.netBaseAssetAmount;
|
|
96
|
+
const Q = amm.pegMultiplier;
|
|
97
|
+
const [numerator, denominator] = calculateBudgetedKBN(x, y, cost, Q, d);
|
|
98
|
+
return [numerator, denominator];
|
|
99
|
+
}
|
|
100
|
+
exports.calculateBudgetedK = calculateBudgetedK;
|
|
101
|
+
function calculateBudgetedPeg(amm, cost, targetPrice) {
|
|
102
|
+
// wolframalpha.com
|
|
103
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
104
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
105
|
+
// todo: assumes k = x * y
|
|
106
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
107
|
+
const targetPeg = targetPrice
|
|
108
|
+
.mul(amm.baseAssetReserve)
|
|
109
|
+
.div(amm.quoteAssetReserve)
|
|
110
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.PEG_PRECISION));
|
|
111
|
+
const k = amm.sqrtK.mul(amm.sqrtK);
|
|
112
|
+
const x = amm.baseAssetReserve;
|
|
113
|
+
const y = amm.quoteAssetReserve;
|
|
114
|
+
const d = amm.netBaseAssetAmount;
|
|
115
|
+
const Q = amm.pegMultiplier;
|
|
116
|
+
const C = cost.mul(new anchor_1.BN(-1));
|
|
117
|
+
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
118
|
+
const pegChangeDirection = targetPeg.sub(Q);
|
|
119
|
+
const useTargetPeg = (deltaQuoteAssetReserves.lt(numericConstants_1.ZERO) && pegChangeDirection.gt(numericConstants_1.ZERO)) ||
|
|
120
|
+
(deltaQuoteAssetReserves.gt(numericConstants_1.ZERO) && pegChangeDirection.lt(numericConstants_1.ZERO));
|
|
121
|
+
if (deltaQuoteAssetReserves.eq(numericConstants_1.ZERO) || useTargetPeg) {
|
|
122
|
+
return targetPeg;
|
|
123
|
+
}
|
|
124
|
+
const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
|
|
125
|
+
const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
|
|
126
|
+
return newPeg;
|
|
127
|
+
}
|
|
128
|
+
exports.calculateBudgetedPeg = calculateBudgetedPeg;
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import {
|
|
2
|
+
import { MarketAccount, PositionDirection } from '../types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
import { AssetType } from './amm';
|
|
5
|
+
import { OraclePriceData } from '../oracles/types';
|
|
5
6
|
export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' | 'priceDeltaAsNumber' | 'pctAvg' | 'pctMax' | 'quoteAssetAmount' | 'quoteAssetAmountPeg' | 'acquiredBaseAssetAmount' | 'acquiredQuoteAssetAmount' | 'all';
|
|
6
7
|
/**
|
|
7
8
|
* Calculates avg/max slippage (price impact) for candidate trade
|
|
@@ -20,7 +21,7 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
|
|
|
20
21
|
*
|
|
21
22
|
* 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
|
|
22
23
|
*/
|
|
23
|
-
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market:
|
|
24
|
+
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: MarketAccount, inputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [BN, BN, BN, BN];
|
|
24
25
|
/**
|
|
25
26
|
* Calculates acquired amounts for trade executed
|
|
26
27
|
* @param direction
|
|
@@ -32,7 +33,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
|
|
|
32
33
|
* | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
|
|
33
34
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
34
35
|
*/
|
|
35
|
-
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market:
|
|
36
|
+
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: MarketAccount, inputAssetType: AssetType, oraclePriceData: OraclePriceData, useSpread?: boolean): [BN, BN];
|
|
36
37
|
/**
|
|
37
38
|
* calculateTargetPriceTrade
|
|
38
39
|
* simple function for finding arbitraging trades
|
|
@@ -50,4 +51,4 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
|
|
|
50
51
|
* targetPrice => the target price MARK_PRICE_PRECISION
|
|
51
52
|
* ]
|
|
52
53
|
*/
|
|
53
|
-
export declare function calculateTargetPriceTrade(market:
|
|
54
|
+
export declare function calculateTargetPriceTrade(market: MarketAccount, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [PositionDirection, BN, BN, BN];
|
package/lib/math/trade.js
CHANGED
|
@@ -27,32 +27,39 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
|
|
|
27
27
|
*
|
|
28
28
|
* 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
|
|
29
29
|
*/
|
|
30
|
-
function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
|
|
30
|
+
function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
31
31
|
let oldPrice;
|
|
32
32
|
if (useSpread && market.amm.baseSpread > 0) {
|
|
33
33
|
if ((0, types_2.isVariant)(direction, 'long')) {
|
|
34
|
-
oldPrice = (0, market_1.calculateAskPrice)(market);
|
|
34
|
+
oldPrice = (0, market_1.calculateAskPrice)(market, oraclePriceData);
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
oldPrice = (0, market_1.calculateBidPrice)(market);
|
|
37
|
+
oldPrice = (0, market_1.calculateBidPrice)(market, oraclePriceData);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
|
-
oldPrice = (0, market_1.calculateMarkPrice)(market);
|
|
41
|
+
oldPrice = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
|
|
42
42
|
}
|
|
43
43
|
if (amount.eq(numericConstants_1.ZERO)) {
|
|
44
44
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
|
|
45
45
|
}
|
|
46
|
-
const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, useSpread);
|
|
47
|
-
const
|
|
46
|
+
const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, oraclePriceData, useSpread);
|
|
47
|
+
const swapDirection = (0, types_2.isVariant)(direction, 'long')
|
|
48
|
+
? types_1.SwapDirection.REMOVE
|
|
49
|
+
: types_1.SwapDirection.ADD;
|
|
50
|
+
const quoteAssetAmountAcquired = (0, amm_1.calculateQuoteAssetAmountSwapped)(acquiredQuote.abs(), market.amm.pegMultiplier, swapDirection);
|
|
51
|
+
const entryPrice = quoteAssetAmountAcquired
|
|
52
|
+
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
53
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
54
|
+
.div(acquiredBase.abs());
|
|
48
55
|
let amm;
|
|
49
56
|
if (useSpread && market.amm.baseSpread > 0) {
|
|
50
|
-
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.
|
|
57
|
+
const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
|
|
51
58
|
amm = {
|
|
52
59
|
baseAssetReserve,
|
|
53
60
|
quoteAssetReserve,
|
|
54
|
-
sqrtK:
|
|
55
|
-
pegMultiplier:
|
|
61
|
+
sqrtK: sqrtK,
|
|
62
|
+
pegMultiplier: newPeg,
|
|
56
63
|
};
|
|
57
64
|
}
|
|
58
65
|
else {
|
|
@@ -60,10 +67,10 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
60
67
|
}
|
|
61
68
|
const newPrice = (0, amm_1.calculatePrice)(amm.baseAssetReserve.sub(acquiredBase), amm.quoteAssetReserve.sub(acquiredQuote), amm.pegMultiplier);
|
|
62
69
|
if (direction == types_1.PositionDirection.SHORT) {
|
|
63
|
-
(0, assert_1.assert)(newPrice.
|
|
70
|
+
(0, assert_1.assert)(newPrice.lte(oldPrice));
|
|
64
71
|
}
|
|
65
72
|
else {
|
|
66
|
-
(0, assert_1.assert)(oldPrice.
|
|
73
|
+
(0, assert_1.assert)(oldPrice.lte(newPrice));
|
|
67
74
|
}
|
|
68
75
|
const pctMaxSlippage = newPrice
|
|
69
76
|
.sub(oldPrice)
|
|
@@ -89,19 +96,19 @@ exports.calculateTradeSlippage = calculateTradeSlippage;
|
|
|
89
96
|
* | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
|
|
90
97
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
91
98
|
*/
|
|
92
|
-
function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
|
|
99
|
+
function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
93
100
|
if (amount.eq(numericConstants_1.ZERO)) {
|
|
94
101
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
95
102
|
}
|
|
96
103
|
const swapDirection = (0, amm_1.getSwapDirection)(inputAssetType, direction);
|
|
97
104
|
let amm;
|
|
98
105
|
if (useSpread && market.amm.baseSpread > 0) {
|
|
99
|
-
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.
|
|
106
|
+
const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
|
|
100
107
|
amm = {
|
|
101
108
|
baseAssetReserve,
|
|
102
109
|
quoteAssetReserve,
|
|
103
|
-
sqrtK:
|
|
104
|
-
pegMultiplier:
|
|
110
|
+
sqrtK: sqrtK,
|
|
111
|
+
pegMultiplier: newPeg,
|
|
105
112
|
};
|
|
106
113
|
}
|
|
107
114
|
else {
|
|
@@ -130,13 +137,13 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
|
130
137
|
* targetPrice => the target price MARK_PRICE_PRECISION
|
|
131
138
|
* ]
|
|
132
139
|
*/
|
|
133
|
-
function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', useSpread = true) {
|
|
140
|
+
function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
134
141
|
(0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
|
|
135
142
|
(0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
|
|
136
143
|
(0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
|
|
137
|
-
const markPriceBefore = (0, market_1.calculateMarkPrice)(market);
|
|
138
|
-
const bidPriceBefore = (0, market_1.calculateBidPrice)(market);
|
|
139
|
-
const askPriceBefore = (0, market_1.calculateAskPrice)(market);
|
|
144
|
+
const markPriceBefore = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
|
|
145
|
+
const bidPriceBefore = (0, market_1.calculateBidPrice)(market, oraclePriceData);
|
|
146
|
+
const askPriceBefore = (0, market_1.calculateAskPrice)(market, oraclePriceData);
|
|
140
147
|
let direction;
|
|
141
148
|
if (targetPrice.gt(markPriceBefore)) {
|
|
142
149
|
const priceGap = targetPrice.sub(markPriceBefore);
|
|
@@ -154,16 +161,17 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
154
161
|
let baseSize;
|
|
155
162
|
let baseAssetReserveBefore;
|
|
156
163
|
let quoteAssetReserveBefore;
|
|
164
|
+
let peg = market.amm.pegMultiplier;
|
|
157
165
|
if (useSpread && market.amm.baseSpread > 0) {
|
|
158
|
-
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.
|
|
166
|
+
const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
|
|
159
167
|
baseAssetReserveBefore = baseAssetReserve;
|
|
160
168
|
quoteAssetReserveBefore = quoteAssetReserve;
|
|
169
|
+
peg = newPeg;
|
|
161
170
|
}
|
|
162
171
|
else {
|
|
163
172
|
baseAssetReserveBefore = market.amm.baseAssetReserve;
|
|
164
173
|
quoteAssetReserveBefore = market.amm.quoteAssetReserve;
|
|
165
174
|
}
|
|
166
|
-
const peg = market.amm.pegMultiplier;
|
|
167
175
|
const invariant = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
168
176
|
const k = invariant.mul(numericConstants_1.MARK_PRICE_PRECISION);
|
|
169
177
|
let baseAssetReserveAfter;
|