@drift-labs/sdk 0.2.0-master.4 → 0.2.0-master.40
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/README.md +27 -27
- package/lib/accounts/bulkAccountLoader.d.ts +2 -0
- package/lib/accounts/bulkAccountLoader.js +36 -29
- package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
- package/lib/accounts/bulkUserStatsSubscription.js +21 -0
- package/lib/accounts/bulkUserSubscription.d.ts +2 -2
- package/lib/accounts/bulkUserSubscription.js +0 -1
- package/lib/accounts/fetch.d.ts +2 -1
- package/lib/accounts/fetch.js +9 -1
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +20 -25
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +45 -49
- package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
- package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
- package/lib/accounts/types.d.ts +26 -15
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +49 -0
- package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +47 -45
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
- package/lib/addresses/marketAddresses.d.ts +1 -3
- package/lib/addresses/marketAddresses.js +1 -1
- package/lib/addresses/pda.d.ts +15 -9
- package/lib/addresses/pda.js +73 -35
- package/lib/adminClient.d.ts +65 -0
- package/lib/adminClient.js +637 -0
- package/lib/config.d.ts +9 -9
- package/lib/config.js +25 -21
- package/lib/constants/numericConstants.d.ts +30 -12
- package/lib/constants/numericConstants.js +41 -21
- package/lib/constants/perpMarkets.d.ts +18 -0
- package/lib/constants/{markets.js → perpMarkets.js} +7 -7
- package/lib/constants/spotMarkets.d.ts +19 -0
- package/lib/constants/spotMarkets.js +53 -0
- package/lib/dlob/DLOB.d.ts +82 -0
- package/lib/dlob/DLOB.js +696 -0
- package/lib/dlob/DLOBNode.d.ts +54 -0
- package/lib/dlob/DLOBNode.js +77 -0
- package/lib/dlob/NodeList.d.ts +27 -0
- package/lib/dlob/NodeList.js +144 -0
- package/lib/driftClient.d.ts +233 -0
- package/lib/driftClient.js +2096 -0
- package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +9 -9
- package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
- package/lib/events/eventList.js +3 -0
- package/lib/events/eventSubscriber.d.ts +5 -2
- package/lib/events/eventSubscriber.js +25 -11
- package/lib/events/fetchLogs.d.ts +13 -2
- package/lib/events/fetchLogs.js +40 -12
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +7 -3
- package/lib/events/sort.js +8 -11
- package/lib/events/types.d.ts +9 -3
- package/lib/events/types.js +6 -0
- package/lib/events/webSocketLogProvider.js +1 -1
- package/lib/examples/makeTradeExample.js +30 -18
- package/lib/factory/bigNum.d.ts +8 -4
- package/lib/factory/bigNum.js +109 -19
- package/lib/idl/drift.json +8250 -0
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +30 -13
- package/lib/index.js +30 -13
- package/lib/math/amm.d.ts +9 -6
- package/lib/math/amm.js +91 -38
- package/lib/math/conversion.js +1 -1
- package/lib/math/exchangeStatus.d.ts +4 -0
- package/lib/math/exchangeStatus.js +18 -0
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +23 -21
- package/lib/math/insurance.d.ts +4 -0
- package/lib/math/insurance.js +27 -0
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +82 -0
- package/lib/math/market.d.ts +14 -9
- package/lib/math/market.js +70 -10
- package/lib/math/oracles.d.ts +4 -0
- package/lib/math/oracles.js +36 -8
- package/lib/math/orders.d.ts +14 -6
- package/lib/math/orders.js +90 -17
- package/lib/math/position.d.ts +27 -13
- package/lib/math/position.js +92 -36
- package/lib/math/repeg.js +17 -8
- package/lib/math/spotBalance.d.ts +22 -0
- package/lib/math/spotBalance.js +192 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +6 -0
- package/lib/math/spotPosition.js +23 -0
- package/lib/math/trade.d.ts +10 -10
- package/lib/math/trade.js +27 -31
- package/lib/oracles/pythClient.js +1 -1
- package/lib/oracles/quoteAssetOracleClient.js +1 -1
- package/lib/oracles/switchboardClient.js +1 -1
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
- package/lib/serum/serumFulfillmentConfigMap.js +17 -0
- package/lib/serum/serumSubscriber.d.ts +27 -0
- package/lib/serum/serumSubscriber.js +56 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/{clearingHouseUserConfig.js → serum/types.js} +0 -0
- package/lib/slot/SlotSubscriber.d.ts +7 -0
- package/lib/slot/SlotSubscriber.js +3 -0
- package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
- package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +13 -4
- package/lib/tx/types.d.ts +1 -1
- package/lib/tx/utils.js +1 -1
- package/lib/types.d.ts +589 -196
- package/lib/types.js +108 -17
- package/lib/user.d.ts +226 -0
- package/lib/user.js +949 -0
- package/lib/userConfig.d.ts +14 -0
- package/lib/userConfig.js +2 -0
- package/lib/userMap/userMap.d.ts +41 -0
- package/lib/userMap/userMap.js +85 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/lib/userName.d.ts +1 -0
- package/lib/userName.js +3 -2
- package/lib/userStats.d.ts +18 -0
- package/lib/userStats.js +49 -0
- package/lib/userStatsConfig.d.ts +14 -0
- package/lib/userStatsConfig.js +2 -0
- package/lib/util/computeUnits.js +1 -1
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +10 -3
- package/src/accounts/bulkAccountLoader.ts +44 -34
- package/src/accounts/bulkUserStatsSubscription.ts +33 -0
- package/src/accounts/bulkUserSubscription.ts +2 -3
- package/src/accounts/fetch.ts +27 -2
- package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +65 -75
- package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
- package/src/accounts/types.ts +35 -15
- package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +78 -73
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
- package/src/addresses/marketAddresses.ts +3 -4
- package/src/addresses/pda.ts +105 -33
- package/src/adminClient.ts +1207 -0
- package/src/config.ts +37 -31
- package/src/constants/numericConstants.ts +58 -24
- package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
- package/src/constants/spotMarkets.ts +73 -0
- package/src/dlob/DLOB.ts +1123 -0
- package/src/dlob/DLOBNode.ts +155 -0
- package/src/dlob/NodeList.ts +195 -0
- package/src/driftClient.ts +3564 -0
- package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +9 -8
- package/src/events/eventList.ts +3 -0
- package/src/events/eventSubscriber.ts +36 -14
- package/src/events/fetchLogs.ts +55 -13
- package/src/events/pollingLogProvider.ts +11 -3
- package/src/events/sort.ts +11 -15
- package/src/events/types.ts +21 -2
- package/src/events/webSocketLogProvider.ts +1 -1
- package/src/examples/makeTradeExample.ts +44 -28
- package/src/factory/bigNum.ts +150 -22
- package/src/idl/drift.json +8250 -0
- package/src/idl/pyth.json +98 -2
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.ts +30 -13
- package/src/math/amm.ts +161 -48
- package/src/math/conversion.ts +2 -2
- package/src/math/exchangeStatus.ts +31 -0
- package/src/math/funding.ts +41 -31
- package/src/math/insurance.ts +35 -0
- package/src/math/margin.ts +133 -0
- package/src/math/market.ts +143 -14
- package/src/math/oracles.ts +63 -9
- package/src/math/orders.ts +163 -26
- package/src/math/position.ts +136 -58
- package/src/math/repeg.ts +19 -9
- package/src/math/spotBalance.ts +319 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.ts +47 -0
- package/src/math/trade.ts +33 -37
- package/src/oracles/pythClient.ts +2 -2
- package/src/oracles/quoteAssetOracleClient.ts +2 -2
- package/src/oracles/switchboardClient.ts +2 -2
- package/src/orderParams.ts +16 -8
- package/src/serum/serumFulfillmentConfigMap.ts +26 -0
- package/src/serum/serumSubscriber.ts +99 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.ts +11 -1
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
- package/src/tx/retryTxSender.ts +16 -5
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.ts +1 -1
- package/src/types.ts +572 -178
- package/src/user.ts +1582 -0
- package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
- package/src/userMap/userMap.ts +124 -0
- package/src/userMap/userStatsMap.ts +108 -0
- package/src/userName.ts +2 -1
- package/src/userStats.ts +75 -0
- package/src/userStatsConfig.ts +18 -0
- package/src/util/computeUnits.ts +1 -1
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +46 -11
- package/tests/dlob/helpers.ts +611 -0
- package/tests/dlob/test.ts +4588 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +0 -49
- package/lib/admin.d.ts +0 -44
- package/lib/admin.js +0 -433
- package/lib/clearingHouse.d.ts +0 -133
- package/lib/clearingHouse.js +0 -931
- package/lib/clearingHouseUser.d.ts +0 -187
- package/lib/clearingHouseUser.js +0 -643
- package/lib/clearingHouseUserConfig.d.ts +0 -14
- package/lib/constants/banks.d.ts +0 -16
- package/lib/constants/banks.js +0 -34
- package/lib/constants/markets.d.ts +0 -19
- package/lib/idl/clearing_house.json +0 -3998
- package/lib/math/bankBalance.d.ts +0 -9
- package/lib/math/bankBalance.js +0 -75
- package/lib/math/state.d.ts +0 -8
- package/lib/math/state.js +0 -15
- package/lib/orders.d.ts +0 -8
- package/lib/orders.js +0 -134
- package/src/admin.ts +0 -722
- package/src/clearingHouse.ts +0 -1451
- package/src/clearingHouseUser.ts +0 -989
- package/src/constants/banks.ts +0 -43
- package/src/idl/clearing_house.json +0 -3998
- package/src/math/bankBalance.ts +0 -112
- package/src/math/state.ts +0 -14
- package/src/math/utils.js +0 -27
- package/src/math/utils.js.map +0 -1
- package/src/orders.ts +0 -244
- package/src/util/computeUnits.js +0 -17
- package/src/util/computeUnits.js.map +0 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
6
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
8
|
+
function getBalance(tokenAmount, spotMarket, balanceType) {
|
|
9
|
+
const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(19 - spotMarket.decimals));
|
|
10
|
+
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
11
|
+
? spotMarket.cumulativeDepositInterest
|
|
12
|
+
: spotMarket.cumulativeBorrowInterest;
|
|
13
|
+
let balance = tokenAmount.mul(precisionIncrease).div(cumulativeInterest);
|
|
14
|
+
if (!balance.eq(numericConstants_1.ZERO) && (0, types_1.isVariant)(balanceType, 'borrow')) {
|
|
15
|
+
balance = balance.add(numericConstants_1.ONE);
|
|
16
|
+
}
|
|
17
|
+
return balance;
|
|
18
|
+
}
|
|
19
|
+
exports.getBalance = getBalance;
|
|
20
|
+
function getTokenAmount(balanceAmount, spotMarket, balanceType) {
|
|
21
|
+
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(19 - spotMarket.decimals));
|
|
22
|
+
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
23
|
+
? spotMarket.cumulativeDepositInterest
|
|
24
|
+
: spotMarket.cumulativeBorrowInterest;
|
|
25
|
+
return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
|
|
26
|
+
}
|
|
27
|
+
exports.getTokenAmount = getTokenAmount;
|
|
28
|
+
function getSignedTokenAmount(tokenAmount, balanceType) {
|
|
29
|
+
if ((0, types_1.isVariant)(balanceType, 'deposit')) {
|
|
30
|
+
return tokenAmount;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return tokenAmount.abs().neg();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.getSignedTokenAmount = getSignedTokenAmount;
|
|
37
|
+
function getTokenValue(tokenAmount, spotDecimals, oraclePriceData) {
|
|
38
|
+
if (tokenAmount.eq(numericConstants_1.ZERO)) {
|
|
39
|
+
return numericConstants_1.ZERO;
|
|
40
|
+
}
|
|
41
|
+
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(spotDecimals));
|
|
42
|
+
return tokenAmount.mul(oraclePriceData.price).div(precisionDecrease);
|
|
43
|
+
}
|
|
44
|
+
exports.getTokenValue = getTokenValue;
|
|
45
|
+
function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
|
|
46
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
|
|
47
|
+
let sizeInAmmReservePrecision;
|
|
48
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
49
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
53
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
54
|
+
.div(sizePrecision);
|
|
55
|
+
}
|
|
56
|
+
let assetWeight;
|
|
57
|
+
switch (marginCategory) {
|
|
58
|
+
case 'Initial':
|
|
59
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.initialAssetWeight));
|
|
60
|
+
break;
|
|
61
|
+
case 'Maintenance':
|
|
62
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.maintenanceAssetWeight));
|
|
63
|
+
break;
|
|
64
|
+
default:
|
|
65
|
+
assetWeight = new anchor_1.BN(spotMarket.initialAssetWeight);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
return assetWeight;
|
|
69
|
+
}
|
|
70
|
+
exports.calculateAssetWeight = calculateAssetWeight;
|
|
71
|
+
function calculateLiabilityWeight(balanceAmount, spotMarket, marginCategory) {
|
|
72
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
|
|
73
|
+
let sizeInAmmReservePrecision;
|
|
74
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
75
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
79
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
80
|
+
.div(sizePrecision);
|
|
81
|
+
}
|
|
82
|
+
let assetWeight;
|
|
83
|
+
switch (marginCategory) {
|
|
84
|
+
case 'Initial':
|
|
85
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.initialLiabilityWeight), numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
86
|
+
break;
|
|
87
|
+
case 'Maintenance':
|
|
88
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.maintenanceLiabilityWeight), numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
assetWeight = spotMarket.initialLiabilityWeight;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
return assetWeight;
|
|
95
|
+
}
|
|
96
|
+
exports.calculateLiabilityWeight = calculateLiabilityWeight;
|
|
97
|
+
function calculateUtilization(bank) {
|
|
98
|
+
const tokenDepositAmount = getTokenAmount(bank.depositBalance, bank, types_1.SpotBalanceType.DEPOSIT);
|
|
99
|
+
const tokenBorrowAmount = getTokenAmount(bank.borrowBalance, bank, types_1.SpotBalanceType.BORROW);
|
|
100
|
+
let utilization;
|
|
101
|
+
if (tokenBorrowAmount.eq(numericConstants_1.ZERO) && tokenDepositAmount.eq(numericConstants_1.ZERO)) {
|
|
102
|
+
utilization = numericConstants_1.ZERO;
|
|
103
|
+
}
|
|
104
|
+
else if (tokenDepositAmount.eq(numericConstants_1.ZERO)) {
|
|
105
|
+
utilization = numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
utilization = tokenBorrowAmount
|
|
109
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
110
|
+
.div(tokenDepositAmount);
|
|
111
|
+
}
|
|
112
|
+
return utilization;
|
|
113
|
+
}
|
|
114
|
+
exports.calculateUtilization = calculateUtilization;
|
|
115
|
+
function calculateInterestRate(bank) {
|
|
116
|
+
const utilization = calculateUtilization(bank);
|
|
117
|
+
let interestRate;
|
|
118
|
+
if (utilization.gt(new anchor_1.BN(bank.optimalUtilization))) {
|
|
119
|
+
const surplusUtilization = utilization.sub(new anchor_1.BN(bank.optimalUtilization));
|
|
120
|
+
const borrowRateSlope = new anchor_1.BN(bank.maxBorrowRate - bank.optimalBorrowRate)
|
|
121
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
122
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(new anchor_1.BN(bank.optimalUtilization)));
|
|
123
|
+
interestRate = new anchor_1.BN(bank.optimalBorrowRate).add(surplusUtilization
|
|
124
|
+
.mul(borrowRateSlope)
|
|
125
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const borrowRateSlope = new anchor_1.BN(bank.optimalBorrowRate)
|
|
129
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
130
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(new anchor_1.BN(bank.optimalUtilization)));
|
|
131
|
+
interestRate = utilization
|
|
132
|
+
.mul(borrowRateSlope)
|
|
133
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
134
|
+
}
|
|
135
|
+
return interestRate;
|
|
136
|
+
}
|
|
137
|
+
exports.calculateInterestRate = calculateInterestRate;
|
|
138
|
+
function calculateDepositRate(bank) {
|
|
139
|
+
const utilization = calculateUtilization(bank);
|
|
140
|
+
const borrowRate = calculateBorrowRate(bank);
|
|
141
|
+
const depositRate = borrowRate
|
|
142
|
+
.mul(utilization)
|
|
143
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
144
|
+
return depositRate;
|
|
145
|
+
}
|
|
146
|
+
exports.calculateDepositRate = calculateDepositRate;
|
|
147
|
+
function calculateBorrowRate(bank) {
|
|
148
|
+
return calculateInterestRate(bank);
|
|
149
|
+
}
|
|
150
|
+
exports.calculateBorrowRate = calculateBorrowRate;
|
|
151
|
+
function calculateInterestAccumulated(bank, now) {
|
|
152
|
+
const interestRate = calculateInterestRate(bank);
|
|
153
|
+
const timeSinceLastUpdate = now.sub(bank.lastInterestTs);
|
|
154
|
+
const modifiedBorrowRate = interestRate.mul(timeSinceLastUpdate);
|
|
155
|
+
const utilization = calculateUtilization(bank);
|
|
156
|
+
const modifiedDepositRate = modifiedBorrowRate
|
|
157
|
+
.mul(utilization)
|
|
158
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
159
|
+
const borrowInterest = bank.cumulativeBorrowInterest
|
|
160
|
+
.mul(modifiedBorrowRate)
|
|
161
|
+
.div(numericConstants_1.ONE_YEAR)
|
|
162
|
+
.div(numericConstants_1.SPOT_MARKET_RATE_PRECISION)
|
|
163
|
+
.add(numericConstants_1.ONE);
|
|
164
|
+
const depositInterest = bank.cumulativeDepositInterest
|
|
165
|
+
.mul(modifiedDepositRate)
|
|
166
|
+
.div(numericConstants_1.ONE_YEAR)
|
|
167
|
+
.div(numericConstants_1.SPOT_MARKET_RATE_PRECISION);
|
|
168
|
+
return { borrowInterest, depositInterest };
|
|
169
|
+
}
|
|
170
|
+
exports.calculateInterestAccumulated = calculateInterestAccumulated;
|
|
171
|
+
function calculateWithdrawLimit(spotMarket, now) {
|
|
172
|
+
const marketDepositTokenAmount = getTokenAmount(spotMarket.depositBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
173
|
+
const marketBorrowTokenAmount = getTokenAmount(spotMarket.borrowBalance, spotMarket, types_1.SpotBalanceType.BORROW);
|
|
174
|
+
const twentyFourHours = new anchor_1.BN(60 * 60 * 24);
|
|
175
|
+
const sinceLast = now.sub(spotMarket.lastTwapTs);
|
|
176
|
+
const sinceStart = anchor_1.BN.max(numericConstants_1.ZERO, twentyFourHours.sub(sinceLast));
|
|
177
|
+
const borrowTokenTwapLive = spotMarket.borrowTokenTwap
|
|
178
|
+
.mul(sinceStart)
|
|
179
|
+
.add(marketBorrowTokenAmount.mul(sinceLast))
|
|
180
|
+
.div(sinceLast.add(sinceStart));
|
|
181
|
+
const depositTokenTwapLive = spotMarket.depositTokenTwap
|
|
182
|
+
.mul(sinceStart)
|
|
183
|
+
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
184
|
+
.div(sinceLast.add(sinceStart));
|
|
185
|
+
const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(5)))); // between ~15-80% utilization with friction on twap
|
|
186
|
+
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
|
|
187
|
+
return {
|
|
188
|
+
borrowLimit: maxBorrowTokens.sub(marketBorrowTokenAmount),
|
|
189
|
+
withdrawLimit: marketDepositTokenAmount.sub(minDepositTokens),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
exports.calculateWithdrawLimit = calculateWithdrawLimit;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.castNumberToSpotPrecision = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
function castNumberToSpotPrecision(value, spotMarket) {
|
|
6
|
+
return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
|
|
7
|
+
}
|
|
8
|
+
exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { SpotMarketAccount, SpotPosition } from '../types';
|
|
3
|
+
import { BN } from '@project-serum/anchor';
|
|
4
|
+
import { OraclePriceData } from '../oracles/types';
|
|
5
|
+
export declare function isSpotPositionAvailable(position: SpotPosition): boolean;
|
|
6
|
+
export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWorstCaseTokenAmounts = exports.isSpotPositionAvailable = void 0;
|
|
4
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
const spotBalance_1 = require("./spotBalance");
|
|
6
|
+
function isSpotPositionAvailable(position) {
|
|
7
|
+
return position.scaledBalance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
|
|
8
|
+
}
|
|
9
|
+
exports.isSpotPositionAvailable = isSpotPositionAvailable;
|
|
10
|
+
function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, oraclePriceData) {
|
|
11
|
+
const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
|
|
12
|
+
const tokenAmountAllBidsFill = tokenAmount.add(spotPosition.openBids);
|
|
13
|
+
const tokenAmountAllAsksFill = tokenAmount.add(spotPosition.openAsks);
|
|
14
|
+
if (tokenAmountAllAsksFill.abs().gt(tokenAmountAllBidsFill.abs())) {
|
|
15
|
+
const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.openAsks.neg(), spotMarketAccount.decimals, oraclePriceData);
|
|
16
|
+
return [tokenAmountAllBidsFill, worstCaseQuoteTokenAmount];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.openBids.neg(), spotMarketAccount.decimals, oraclePriceData);
|
|
20
|
+
return [tokenAmountAllAsksFill, worstCaseQuoteTokenAmount];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.getWorstCaseTokenAmounts = getWorstCaseTokenAmounts;
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import {
|
|
2
|
+
import { PerpMarketAccount, PositionDirection } from '../types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
import { AssetType } from './amm';
|
|
5
5
|
import { OraclePriceData } from '../oracles/types';
|
|
@@ -13,15 +13,15 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
|
|
|
13
13
|
* @param useSpread whether to consider spread with calculating slippage
|
|
14
14
|
* @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
|
|
15
15
|
*
|
|
16
|
-
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision
|
|
16
|
+
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision PRICE_PRECISION
|
|
17
17
|
*
|
|
18
|
-
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision
|
|
18
|
+
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision PRICE_PRECISION
|
|
19
19
|
*
|
|
20
|
-
* 'entryPrice' => the average price of the trade : Precision
|
|
20
|
+
* 'entryPrice' => the average price of the trade : Precision PRICE_PRECISION
|
|
21
21
|
*
|
|
22
|
-
* 'newPrice' => the price of the asset after the trade : Precision
|
|
22
|
+
* 'newPrice' => the price of the asset after the trade : Precision PRICE_PRECISION
|
|
23
23
|
*/
|
|
24
|
-
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market:
|
|
24
|
+
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: PerpMarketAccount, inputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [BN, BN, BN, BN];
|
|
25
25
|
/**
|
|
26
26
|
* Calculates acquired amounts for trade executed
|
|
27
27
|
* @param direction
|
|
@@ -33,7 +33,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
|
|
|
33
33
|
* | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
|
|
34
34
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
35
35
|
*/
|
|
36
|
-
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market:
|
|
36
|
+
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: PerpMarketAccount, inputAssetType: AssetType, oraclePriceData: OraclePriceData, useSpread?: boolean): [BN, BN, BN];
|
|
37
37
|
/**
|
|
38
38
|
* calculateTargetPriceTrade
|
|
39
39
|
* simple function for finding arbitraging trades
|
|
@@ -47,8 +47,8 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
|
|
|
47
47
|
* [
|
|
48
48
|
* direction => direction of trade required, PositionDirection
|
|
49
49
|
* tradeSize => size of trade required, TODO-PRECISION
|
|
50
|
-
* entryPrice => the entry price for the trade,
|
|
51
|
-
* targetPrice => the target price
|
|
50
|
+
* entryPrice => the entry price for the trade, PRICE_PRECISION
|
|
51
|
+
* targetPrice => the target price PRICE_PRECISION
|
|
52
52
|
* ]
|
|
53
53
|
*/
|
|
54
|
-
export declare function calculateTargetPriceTrade(market:
|
|
54
|
+
export declare function calculateTargetPriceTrade(market: PerpMarketAccount, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [PositionDirection, BN, BN, BN];
|
package/lib/math/trade.js
CHANGED
|
@@ -19,13 +19,13 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
|
|
|
19
19
|
* @param useSpread whether to consider spread with calculating slippage
|
|
20
20
|
* @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
|
|
21
21
|
*
|
|
22
|
-
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision
|
|
22
|
+
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision PRICE_PRECISION
|
|
23
23
|
*
|
|
24
|
-
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision
|
|
24
|
+
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision PRICE_PRECISION
|
|
25
25
|
*
|
|
26
|
-
* 'entryPrice' => the average price of the trade : Precision
|
|
26
|
+
* 'entryPrice' => the average price of the trade : Precision PRICE_PRECISION
|
|
27
27
|
*
|
|
28
|
-
* 'newPrice' => the price of the asset after the trade : Precision
|
|
28
|
+
* 'newPrice' => the price of the asset after the trade : Precision PRICE_PRECISION
|
|
29
29
|
*/
|
|
30
30
|
function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
31
31
|
let oldPrice;
|
|
@@ -38,7 +38,7 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
|
-
oldPrice = (0, market_1.
|
|
41
|
+
oldPrice = (0, market_1.calculateReservePrice)(market, oraclePriceData);
|
|
42
42
|
}
|
|
43
43
|
if (amount.eq(numericConstants_1.ZERO)) {
|
|
44
44
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
|
|
@@ -46,7 +46,7 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
46
46
|
const [acquiredBaseReserve, acquiredQuoteReserve, acquiredQuoteAssetAmount] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, oraclePriceData, useSpread);
|
|
47
47
|
const entryPrice = acquiredQuoteAssetAmount
|
|
48
48
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
49
|
-
.mul(numericConstants_1.
|
|
49
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
50
50
|
.div(acquiredBaseReserve.abs());
|
|
51
51
|
let amm;
|
|
52
52
|
if (useSpread && market.amm.baseSpread > 0) {
|
|
@@ -70,12 +70,12 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
70
70
|
}
|
|
71
71
|
const pctMaxSlippage = newPrice
|
|
72
72
|
.sub(oldPrice)
|
|
73
|
-
.mul(numericConstants_1.
|
|
73
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
74
74
|
.div(oldPrice)
|
|
75
75
|
.abs();
|
|
76
76
|
const pctAvgSlippage = entryPrice
|
|
77
77
|
.sub(oldPrice)
|
|
78
|
-
.mul(numericConstants_1.
|
|
78
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
79
79
|
.div(oldPrice)
|
|
80
80
|
.abs();
|
|
81
81
|
return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice];
|
|
@@ -113,8 +113,8 @@ function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType
|
|
|
113
113
|
const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(amm, inputAssetType, amount, swapDirection);
|
|
114
114
|
const acquiredBase = amm.baseAssetReserve.sub(newBaseAssetReserve);
|
|
115
115
|
const acquiredQuote = amm.quoteAssetReserve.sub(newQuoteAssetReserve);
|
|
116
|
-
const
|
|
117
|
-
return [acquiredBase, acquiredQuote,
|
|
116
|
+
const acquiredQuoteAssetAmount = (0, amm_1.calculateQuoteAssetAmountSwapped)(acquiredQuote.abs(), amm.pegMultiplier, swapDirection);
|
|
117
|
+
return [acquiredBase, acquiredQuote, acquiredQuoteAssetAmount];
|
|
118
118
|
}
|
|
119
119
|
exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
120
120
|
/**
|
|
@@ -130,28 +130,28 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
|
130
130
|
* [
|
|
131
131
|
* direction => direction of trade required, PositionDirection
|
|
132
132
|
* tradeSize => size of trade required, TODO-PRECISION
|
|
133
|
-
* entryPrice => the entry price for the trade,
|
|
134
|
-
* targetPrice => the target price
|
|
133
|
+
* entryPrice => the entry price for the trade, PRICE_PRECISION
|
|
134
|
+
* targetPrice => the target price PRICE_PRECISION
|
|
135
135
|
* ]
|
|
136
136
|
*/
|
|
137
137
|
function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
138
138
|
(0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
|
|
139
139
|
(0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
|
|
140
140
|
(0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
|
|
141
|
-
const
|
|
141
|
+
const reservePriceBefore = (0, market_1.calculateReservePrice)(market, oraclePriceData);
|
|
142
142
|
const bidPriceBefore = (0, market_1.calculateBidPrice)(market, oraclePriceData);
|
|
143
143
|
const askPriceBefore = (0, market_1.calculateAskPrice)(market, oraclePriceData);
|
|
144
144
|
let direction;
|
|
145
|
-
if (targetPrice.gt(
|
|
146
|
-
const priceGap = targetPrice.sub(
|
|
145
|
+
if (targetPrice.gt(reservePriceBefore)) {
|
|
146
|
+
const priceGap = targetPrice.sub(reservePriceBefore);
|
|
147
147
|
const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
|
|
148
|
-
targetPrice =
|
|
148
|
+
targetPrice = reservePriceBefore.add(priceGapScaled);
|
|
149
149
|
direction = types_1.PositionDirection.LONG;
|
|
150
150
|
}
|
|
151
151
|
else {
|
|
152
|
-
const priceGap =
|
|
152
|
+
const priceGap = reservePriceBefore.sub(targetPrice);
|
|
153
153
|
const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
|
|
154
|
-
targetPrice =
|
|
154
|
+
targetPrice = reservePriceBefore.sub(priceGapScaled);
|
|
155
155
|
direction = types_1.PositionDirection.SHORT;
|
|
156
156
|
}
|
|
157
157
|
let tradeSize;
|
|
@@ -170,7 +170,7 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
170
170
|
quoteAssetReserveBefore = market.amm.quoteAssetReserve;
|
|
171
171
|
}
|
|
172
172
|
const invariant = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
173
|
-
const k = invariant.mul(numericConstants_1.
|
|
173
|
+
const k = invariant.mul(numericConstants_1.PRICE_PRECISION);
|
|
174
174
|
let baseAssetReserveAfter;
|
|
175
175
|
let quoteAssetReserveAfter;
|
|
176
176
|
const biasModifier = new anchor_1.BN(1);
|
|
@@ -179,7 +179,7 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
179
179
|
targetPrice.lt(askPriceBefore) &&
|
|
180
180
|
targetPrice.gt(bidPriceBefore)) {
|
|
181
181
|
// no trade, market is at target
|
|
182
|
-
if (
|
|
182
|
+
if (reservePriceBefore.gt(targetPrice)) {
|
|
183
183
|
direction = types_1.PositionDirection.SHORT;
|
|
184
184
|
}
|
|
185
185
|
else {
|
|
@@ -188,12 +188,10 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
188
188
|
tradeSize = numericConstants_1.ZERO;
|
|
189
189
|
return [direction, tradeSize, targetPrice, targetPrice];
|
|
190
190
|
}
|
|
191
|
-
else if (
|
|
191
|
+
else if (reservePriceBefore.gt(targetPrice)) {
|
|
192
192
|
// overestimate y2
|
|
193
193
|
baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
|
|
194
|
-
quoteAssetReserveAfter = k
|
|
195
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
196
|
-
.div(baseAssetReserveAfter);
|
|
194
|
+
quoteAssetReserveAfter = k.div(numericConstants_1.PRICE_PRECISION).div(baseAssetReserveAfter);
|
|
197
195
|
markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
|
|
198
196
|
direction = types_1.PositionDirection.SHORT;
|
|
199
197
|
tradeSize = quoteAssetReserveBefore
|
|
@@ -203,12 +201,10 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
203
201
|
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
204
202
|
baseSize = baseAssetReserveAfter.sub(baseAssetReserveBefore);
|
|
205
203
|
}
|
|
206
|
-
else if (
|
|
204
|
+
else if (reservePriceBefore.lt(targetPrice)) {
|
|
207
205
|
// underestimate y2
|
|
208
206
|
baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).add(biasModifier)).add(new anchor_1.BN(1));
|
|
209
|
-
quoteAssetReserveAfter = k
|
|
210
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
211
|
-
.div(baseAssetReserveAfter);
|
|
207
|
+
quoteAssetReserveAfter = k.div(numericConstants_1.PRICE_PRECISION).div(baseAssetReserveAfter);
|
|
212
208
|
markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
|
|
213
209
|
direction = types_1.PositionDirection.LONG;
|
|
214
210
|
tradeSize = quoteAssetReserveAfter
|
|
@@ -226,15 +222,15 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
226
222
|
}
|
|
227
223
|
let tp1 = targetPrice;
|
|
228
224
|
let tp2 = markPriceAfter;
|
|
229
|
-
let originalDiff = targetPrice.sub(
|
|
225
|
+
let originalDiff = targetPrice.sub(reservePriceBefore);
|
|
230
226
|
if (direction == types_1.PositionDirection.SHORT) {
|
|
231
227
|
tp1 = markPriceAfter;
|
|
232
228
|
tp2 = targetPrice;
|
|
233
|
-
originalDiff =
|
|
229
|
+
originalDiff = reservePriceBefore.sub(targetPrice);
|
|
234
230
|
}
|
|
235
231
|
const entryPrice = tradeSize
|
|
236
232
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
237
|
-
.mul(numericConstants_1.
|
|
233
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
238
234
|
.div(baseSize.abs());
|
|
239
235
|
(0, assert_1.assert)(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
|
|
240
236
|
(0, assert_1.assert)(tp2.lte(tp1) || tp2.sub(tp1).abs() < 100000, 'Target Price Calculation incorrect' +
|
|
@@ -29,7 +29,7 @@ function convertPythPrice(price, exponent) {
|
|
|
29
29
|
exponent = Math.abs(exponent);
|
|
30
30
|
const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs());
|
|
31
31
|
return new anchor_1.BN(price * Math.pow(10, exponent))
|
|
32
|
-
.mul(numericConstants_1.
|
|
32
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
33
33
|
.div(pythPrecision);
|
|
34
34
|
}
|
|
35
35
|
exports.convertPythPrice = convertPythPrice;
|
|
@@ -4,7 +4,7 @@ exports.QuoteAssetOracleClient = exports.QUOTE_ORACLE_PRICE_DATA = void 0;
|
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
exports.QUOTE_ORACLE_PRICE_DATA = {
|
|
7
|
-
price: numericConstants_1.
|
|
7
|
+
price: numericConstants_1.PRICE_PRECISION,
|
|
8
8
|
slot: new anchor_1.BN(0),
|
|
9
9
|
confidence: new anchor_1.BN(1),
|
|
10
10
|
hasSufficientNumberOfDataPoints: true,
|
|
@@ -53,6 +53,6 @@ function getSwitchboardProgram(connection) {
|
|
|
53
53
|
function convertSwitchboardDecimal(switchboardDecimal) {
|
|
54
54
|
const switchboardPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(switchboardDecimal.scale));
|
|
55
55
|
return switchboardDecimal.mantissa
|
|
56
|
-
.mul(numericConstants_1.
|
|
56
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
57
57
|
.div(switchboardPrecision);
|
|
58
58
|
}
|
package/lib/orderParams.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { OptionalOrderParams, OrderTriggerCondition } from './types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
|
-
export declare function getLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
|
|
4
|
+
export declare function getLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'> & {
|
|
5
5
|
price: BN;
|
|
6
6
|
}): OptionalOrderParams;
|
|
7
|
-
export declare function getTriggerMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
|
|
7
|
+
export declare function getTriggerMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'> & {
|
|
8
8
|
triggerCondition: OrderTriggerCondition;
|
|
9
9
|
triggerPrice: BN;
|
|
10
10
|
}): OptionalOrderParams;
|
|
11
|
-
export declare function getTriggerLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
|
|
11
|
+
export declare function getTriggerLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'> & {
|
|
12
12
|
triggerCondition: OrderTriggerCondition;
|
|
13
13
|
triggerPrice: BN;
|
|
14
14
|
price: BN;
|
|
15
15
|
}): OptionalOrderParams;
|
|
16
|
-
export declare function getMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType'>): OptionalOrderParams;
|
|
16
|
+
export declare function getMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'>): OptionalOrderParams;
|
package/lib/orderParams.js
CHANGED
|
@@ -3,18 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
function getLimitOrderParams(params) {
|
|
6
|
-
return Object.assign({}, params, {
|
|
6
|
+
return Object.assign({}, params, {
|
|
7
|
+
orderType: types_1.OrderType.LIMIT,
|
|
8
|
+
});
|
|
7
9
|
}
|
|
8
10
|
exports.getLimitOrderParams = getLimitOrderParams;
|
|
9
11
|
function getTriggerMarketOrderParams(params) {
|
|
10
|
-
return Object.assign({}, params, {
|
|
12
|
+
return Object.assign({}, params, {
|
|
13
|
+
orderType: types_1.OrderType.TRIGGER_MARKET,
|
|
14
|
+
});
|
|
11
15
|
}
|
|
12
16
|
exports.getTriggerMarketOrderParams = getTriggerMarketOrderParams;
|
|
13
17
|
function getTriggerLimitOrderParams(params) {
|
|
14
|
-
return Object.assign({}, params, {
|
|
18
|
+
return Object.assign({}, params, {
|
|
19
|
+
orderType: types_1.OrderType.TRIGGER_LIMIT,
|
|
20
|
+
});
|
|
15
21
|
}
|
|
16
22
|
exports.getTriggerLimitOrderParams = getTriggerLimitOrderParams;
|
|
17
23
|
function getMarketOrderParams(params) {
|
|
18
|
-
return Object.assign({}, params, {
|
|
24
|
+
return Object.assign({}, params, {
|
|
25
|
+
orderType: types_1.OrderType.MARKET,
|
|
26
|
+
});
|
|
19
27
|
}
|
|
20
28
|
exports.getMarketOrderParams = getMarketOrderParams;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { SerumV3FulfillmentConfigAccount } from '../types';
|
|
3
|
+
import { DriftClient } from '../driftClient';
|
|
4
|
+
export declare class SerumFulfillmentConfigMap {
|
|
5
|
+
driftClient: DriftClient;
|
|
6
|
+
map: Map<number, SerumV3FulfillmentConfigAccount>;
|
|
7
|
+
constructor(driftClient: DriftClient);
|
|
8
|
+
add(marketIndex: number, serumMarketAddress: PublicKey): Promise<void>;
|
|
9
|
+
get(marketIndex: number): SerumV3FulfillmentConfigAccount;
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SerumFulfillmentConfigMap = void 0;
|
|
4
|
+
class SerumFulfillmentConfigMap {
|
|
5
|
+
constructor(driftClient) {
|
|
6
|
+
this.map = new Map();
|
|
7
|
+
this.driftClient = driftClient;
|
|
8
|
+
}
|
|
9
|
+
async add(marketIndex, serumMarketAddress) {
|
|
10
|
+
const account = await this.driftClient.getSerumV3FulfillmentConfig(serumMarketAddress);
|
|
11
|
+
this.map.set(marketIndex, account);
|
|
12
|
+
}
|
|
13
|
+
get(marketIndex) {
|
|
14
|
+
return this.map.get(marketIndex);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.SerumFulfillmentConfigMap = SerumFulfillmentConfigMap;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
|
|
4
|
+
import { Market, Orderbook } from '@project-serum/serum';
|
|
5
|
+
import { SerumMarketSubscriberConfig } from './types';
|
|
6
|
+
import { BN } from '@project-serum/anchor';
|
|
7
|
+
export declare class SerumSubscriber {
|
|
8
|
+
connection: Connection;
|
|
9
|
+
programId: PublicKey;
|
|
10
|
+
marketAddress: PublicKey;
|
|
11
|
+
accountLoader: BulkAccountLoader;
|
|
12
|
+
market: Market;
|
|
13
|
+
subscribed: boolean;
|
|
14
|
+
asksAddress: PublicKey;
|
|
15
|
+
asks: Orderbook;
|
|
16
|
+
asksCallbackId: string;
|
|
17
|
+
lastAsksSlot: number;
|
|
18
|
+
bidsAddress: PublicKey;
|
|
19
|
+
bids: Orderbook;
|
|
20
|
+
bidsCallbackId: string;
|
|
21
|
+
lastBidsSlot: number;
|
|
22
|
+
constructor(config: SerumMarketSubscriberConfig);
|
|
23
|
+
subscribe(): Promise<void>;
|
|
24
|
+
getBestBid(): BN | undefined;
|
|
25
|
+
getBestAsk(): BN | undefined;
|
|
26
|
+
unsubscribe(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SerumSubscriber = void 0;
|
|
4
|
+
const serum_1 = require("@project-serum/serum");
|
|
5
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
6
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
class SerumSubscriber {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.connection = config.connection;
|
|
10
|
+
this.programId = config.programId;
|
|
11
|
+
this.marketAddress = config.marketAddress;
|
|
12
|
+
this.accountLoader = config.accountSubscription.accountLoader;
|
|
13
|
+
}
|
|
14
|
+
async subscribe() {
|
|
15
|
+
if (this.subscribed) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.market = await serum_1.Market.load(this.connection, this.marketAddress, undefined, this.programId);
|
|
19
|
+
this.asksAddress = this.market.asksAddress;
|
|
20
|
+
this.asks = await this.market.loadAsks(this.connection);
|
|
21
|
+
this.asksCallbackId = this.accountLoader.addAccount(this.asksAddress, (buffer, slot) => {
|
|
22
|
+
this.lastAsksSlot = slot;
|
|
23
|
+
this.asks = serum_1.Orderbook.decode(this.market, buffer);
|
|
24
|
+
});
|
|
25
|
+
this.bidsAddress = this.market.bidsAddress;
|
|
26
|
+
this.bids = await this.market.loadBids(this.connection);
|
|
27
|
+
this.bidsCallbackId = this.accountLoader.addAccount(this.bidsAddress, (buffer, slot) => {
|
|
28
|
+
this.lastBidsSlot = slot;
|
|
29
|
+
this.bids = serum_1.Orderbook.decode(this.market, buffer);
|
|
30
|
+
});
|
|
31
|
+
this.subscribed = true;
|
|
32
|
+
}
|
|
33
|
+
getBestBid() {
|
|
34
|
+
const bestBid = this.bids.getL2(1)[0];
|
|
35
|
+
if (!bestBid) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return new anchor_1.BN(bestBid[0] * numericConstants_1.PRICE_PRECISION.toNumber());
|
|
39
|
+
}
|
|
40
|
+
getBestAsk() {
|
|
41
|
+
const bestAsk = this.asks.getL2(1)[0];
|
|
42
|
+
if (!bestAsk) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return new anchor_1.BN(bestAsk[0] * numericConstants_1.PRICE_PRECISION.toNumber());
|
|
46
|
+
}
|
|
47
|
+
async unsubscribe() {
|
|
48
|
+
if (!this.subscribed) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.accountLoader.removeAccount(this.asksAddress, this.asksCallbackId);
|
|
52
|
+
this.accountLoader.removeAccount(this.bidsAddress, this.bidsCallbackId);
|
|
53
|
+
this.subscribed = false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.SerumSubscriber = SerumSubscriber;
|