@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,133 @@
|
|
|
1
|
+
import { squareRootBN } from './utils';
|
|
2
|
+
import {
|
|
3
|
+
SPOT_MARKET_WEIGHT_PRECISION,
|
|
4
|
+
SPOT_MARKET_IMF_PRECISION,
|
|
5
|
+
ZERO,
|
|
6
|
+
BID_ASK_SPREAD_PRECISION,
|
|
7
|
+
AMM_RESERVE_PRECISION,
|
|
8
|
+
} from '../constants/numericConstants';
|
|
9
|
+
import { BN } from '@project-serum/anchor';
|
|
10
|
+
import { OraclePriceData } from '../oracles/types';
|
|
11
|
+
import { PerpMarketAccount, PerpPosition } from '..';
|
|
12
|
+
import { isVariant } from '../types';
|
|
13
|
+
import { assert } from '../assert/assert';
|
|
14
|
+
|
|
15
|
+
export function calculateSizePremiumLiabilityWeight(
|
|
16
|
+
size: BN, // AMM_RESERVE_PRECISION
|
|
17
|
+
imfFactor: BN,
|
|
18
|
+
liabilityWeight: BN,
|
|
19
|
+
precision: BN
|
|
20
|
+
): BN {
|
|
21
|
+
if (imfFactor.eq(ZERO)) {
|
|
22
|
+
return liabilityWeight;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const sizeSqrt = squareRootBN(size.mul(new BN(10)).add(new BN(1))); //1e9 -> 1e10 -> 1e5
|
|
26
|
+
|
|
27
|
+
const denom0 = BN.max(new BN(1), SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
28
|
+
assert(denom0.gt(ZERO));
|
|
29
|
+
const liabilityWeightNumerator = liabilityWeight.sub(
|
|
30
|
+
liabilityWeight.div(
|
|
31
|
+
BN.max(new BN(1), SPOT_MARKET_IMF_PRECISION.div(imfFactor))
|
|
32
|
+
)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const denom = new BN(100_000).mul(SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
36
|
+
assert(denom.gt(ZERO));
|
|
37
|
+
|
|
38
|
+
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(
|
|
39
|
+
sizeSqrt // 1e5
|
|
40
|
+
.mul(imfFactor)
|
|
41
|
+
.div(denom) // 1e5
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const maxLiabilityWeight = BN.max(
|
|
45
|
+
liabilityWeight,
|
|
46
|
+
sizePremiumLiabilityWeight
|
|
47
|
+
);
|
|
48
|
+
return maxLiabilityWeight;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function calculateSizeDiscountAssetWeight(
|
|
52
|
+
size: BN, // AMM_RESERVE_PRECISION
|
|
53
|
+
imfFactor: BN,
|
|
54
|
+
assetWeight: BN
|
|
55
|
+
): BN {
|
|
56
|
+
if (imfFactor.eq(ZERO)) {
|
|
57
|
+
return assetWeight;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const sizeSqrt = squareRootBN(size.mul(new BN(10)).add(new BN(1))); //1e9 -> 1e10 -> 1e5
|
|
61
|
+
const imfNumerator = SPOT_MARKET_IMF_PRECISION.add(
|
|
62
|
+
SPOT_MARKET_IMF_PRECISION.div(new BN(10))
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const sizeDiscountAssetWeight = imfNumerator
|
|
66
|
+
.mul(SPOT_MARKET_WEIGHT_PRECISION)
|
|
67
|
+
.div(
|
|
68
|
+
SPOT_MARKET_IMF_PRECISION.add(
|
|
69
|
+
sizeSqrt // 1e5
|
|
70
|
+
.mul(imfFactor)
|
|
71
|
+
.div(new BN(100_000)) // 1e5
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const minAssetWeight = BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
76
|
+
|
|
77
|
+
return minAssetWeight;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function calculateOraclePriceForPerpMargin(
|
|
81
|
+
perpPosition: PerpPosition,
|
|
82
|
+
market: PerpMarketAccount,
|
|
83
|
+
oraclePriceData: OraclePriceData
|
|
84
|
+
): BN {
|
|
85
|
+
const oraclePriceOffset = BN.min(
|
|
86
|
+
new BN(market.amm.maxSpread)
|
|
87
|
+
.mul(oraclePriceData.price)
|
|
88
|
+
.div(BID_ASK_SPREAD_PRECISION),
|
|
89
|
+
oraclePriceData.confidence.add(
|
|
90
|
+
new BN(market.amm.baseSpread)
|
|
91
|
+
.mul(oraclePriceData.price)
|
|
92
|
+
.div(BID_ASK_SPREAD_PRECISION)
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
let marginPrice: BN;
|
|
97
|
+
if (perpPosition.baseAssetAmount.gt(ZERO)) {
|
|
98
|
+
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
99
|
+
} else {
|
|
100
|
+
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return marginPrice;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function calculateBaseAssetValueWithOracle(
|
|
107
|
+
market: PerpMarketAccount,
|
|
108
|
+
perpPosition: PerpPosition,
|
|
109
|
+
oraclePriceData: OraclePriceData
|
|
110
|
+
): BN {
|
|
111
|
+
let price = oraclePriceData.price;
|
|
112
|
+
if (isVariant(market.status, 'settlement')) {
|
|
113
|
+
price = market.expiryPrice;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return perpPosition.baseAssetAmount
|
|
117
|
+
.abs()
|
|
118
|
+
.mul(price)
|
|
119
|
+
.div(AMM_RESERVE_PRECISION);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function calculateWorstCaseBaseAssetAmount(
|
|
123
|
+
perpPosition: PerpPosition
|
|
124
|
+
): BN {
|
|
125
|
+
const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
|
|
126
|
+
const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
|
|
127
|
+
|
|
128
|
+
if (allBids.abs().gt(allAsks.abs())) {
|
|
129
|
+
return allBids;
|
|
130
|
+
} else {
|
|
131
|
+
return allAsks;
|
|
132
|
+
}
|
|
133
|
+
}
|
package/src/math/market.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { BN } from '@project-serum/anchor';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
PerpMarketAccount,
|
|
4
|
+
PositionDirection,
|
|
5
|
+
MarginCategory,
|
|
6
|
+
SpotMarketAccount,
|
|
7
|
+
SpotBalanceType,
|
|
8
|
+
} from '../types';
|
|
3
9
|
import {
|
|
4
10
|
calculateAmmReservesAfterSwap,
|
|
5
11
|
calculatePrice,
|
|
@@ -7,16 +13,27 @@ import {
|
|
|
7
13
|
getSwapDirection,
|
|
8
14
|
calculateUpdatedAMM,
|
|
9
15
|
} from './amm';
|
|
16
|
+
import {
|
|
17
|
+
calculateSizeDiscountAssetWeight,
|
|
18
|
+
calculateSizePremiumLiabilityWeight,
|
|
19
|
+
} from './margin';
|
|
10
20
|
import { OraclePriceData } from '../oracles/types';
|
|
21
|
+
import {
|
|
22
|
+
BASE_PRECISION,
|
|
23
|
+
MARGIN_PRECISION,
|
|
24
|
+
PRICE_TO_QUOTE_PRECISION,
|
|
25
|
+
ZERO,
|
|
26
|
+
} from '../constants/numericConstants';
|
|
27
|
+
import { getTokenAmount } from './spotBalance';
|
|
11
28
|
|
|
12
29
|
/**
|
|
13
30
|
* Calculates market mark price
|
|
14
31
|
*
|
|
15
32
|
* @param market
|
|
16
|
-
* @return markPrice : Precision
|
|
33
|
+
* @return markPrice : Precision PRICE_PRECISION
|
|
17
34
|
*/
|
|
18
|
-
export function
|
|
19
|
-
market:
|
|
35
|
+
export function calculateReservePrice(
|
|
36
|
+
market: PerpMarketAccount,
|
|
20
37
|
oraclePriceData: OraclePriceData
|
|
21
38
|
): BN {
|
|
22
39
|
const newAmm = calculateUpdatedAMM(market.amm, oraclePriceData);
|
|
@@ -31,10 +48,10 @@ export function calculateMarkPrice(
|
|
|
31
48
|
* Calculates market bid price
|
|
32
49
|
*
|
|
33
50
|
* @param market
|
|
34
|
-
* @return bidPrice : Precision
|
|
51
|
+
* @return bidPrice : Precision PRICE_PRECISION
|
|
35
52
|
*/
|
|
36
53
|
export function calculateBidPrice(
|
|
37
|
-
market:
|
|
54
|
+
market: PerpMarketAccount,
|
|
38
55
|
oraclePriceData: OraclePriceData
|
|
39
56
|
): BN {
|
|
40
57
|
const { baseAssetReserve, quoteAssetReserve, newPeg } =
|
|
@@ -51,10 +68,10 @@ export function calculateBidPrice(
|
|
|
51
68
|
* Calculates market ask price
|
|
52
69
|
*
|
|
53
70
|
* @param market
|
|
54
|
-
* @return
|
|
71
|
+
* @return askPrice : Precision PRICE_PRECISION
|
|
55
72
|
*/
|
|
56
73
|
export function calculateAskPrice(
|
|
57
|
-
market:
|
|
74
|
+
market: PerpMarketAccount,
|
|
58
75
|
oraclePriceData: OraclePriceData
|
|
59
76
|
): BN {
|
|
60
77
|
const { baseAssetReserve, quoteAssetReserve, newPeg } =
|
|
@@ -70,8 +87,8 @@ export function calculateAskPrice(
|
|
|
70
87
|
export function calculateNewMarketAfterTrade(
|
|
71
88
|
baseAssetAmount: BN,
|
|
72
89
|
direction: PositionDirection,
|
|
73
|
-
market:
|
|
74
|
-
):
|
|
90
|
+
market: PerpMarketAccount
|
|
91
|
+
): PerpMarketAccount {
|
|
75
92
|
const [newQuoteAssetReserve, newBaseAssetReserve] =
|
|
76
93
|
calculateAmmReservesAfterSwap(
|
|
77
94
|
market.amm,
|
|
@@ -89,12 +106,12 @@ export function calculateNewMarketAfterTrade(
|
|
|
89
106
|
return newMarket;
|
|
90
107
|
}
|
|
91
108
|
|
|
92
|
-
export function
|
|
93
|
-
market:
|
|
109
|
+
export function calculateOracleReserveSpread(
|
|
110
|
+
market: PerpMarketAccount,
|
|
94
111
|
oraclePriceData: OraclePriceData
|
|
95
112
|
): BN {
|
|
96
|
-
const
|
|
97
|
-
return calculateOracleSpread(
|
|
113
|
+
const reservePrice = calculateReservePrice(market, oraclePriceData);
|
|
114
|
+
return calculateOracleSpread(reservePrice, oraclePriceData);
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
export function calculateOracleSpread(
|
|
@@ -103,3 +120,115 @@ export function calculateOracleSpread(
|
|
|
103
120
|
): BN {
|
|
104
121
|
return price.sub(oraclePriceData.price);
|
|
105
122
|
}
|
|
123
|
+
|
|
124
|
+
export function calculateMarketMarginRatio(
|
|
125
|
+
market: PerpMarketAccount,
|
|
126
|
+
size: BN,
|
|
127
|
+
marginCategory: MarginCategory
|
|
128
|
+
): number {
|
|
129
|
+
let marginRatio;
|
|
130
|
+
switch (marginCategory) {
|
|
131
|
+
case 'Initial':
|
|
132
|
+
marginRatio = calculateSizePremiumLiabilityWeight(
|
|
133
|
+
size,
|
|
134
|
+
new BN(market.imfFactor),
|
|
135
|
+
new BN(market.marginRatioInitial),
|
|
136
|
+
MARGIN_PRECISION
|
|
137
|
+
).toNumber();
|
|
138
|
+
break;
|
|
139
|
+
case 'Maintenance':
|
|
140
|
+
marginRatio = calculateSizePremiumLiabilityWeight(
|
|
141
|
+
size,
|
|
142
|
+
new BN(market.imfFactor),
|
|
143
|
+
new BN(market.marginRatioMaintenance),
|
|
144
|
+
MARGIN_PRECISION
|
|
145
|
+
).toNumber();
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return marginRatio;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function calculateUnrealizedAssetWeight(
|
|
153
|
+
market: PerpMarketAccount,
|
|
154
|
+
quoteSpotMarket: SpotMarketAccount,
|
|
155
|
+
unrealizedPnl: BN,
|
|
156
|
+
marginCategory: MarginCategory,
|
|
157
|
+
oraclePriceData: OraclePriceData
|
|
158
|
+
): BN {
|
|
159
|
+
let assetWeight: BN;
|
|
160
|
+
switch (marginCategory) {
|
|
161
|
+
case 'Initial':
|
|
162
|
+
assetWeight = new BN(market.unrealizedPnlInitialAssetWeight);
|
|
163
|
+
|
|
164
|
+
if (market.unrealizedPnlMaxImbalance.gt(ZERO)) {
|
|
165
|
+
const netUnsettledPnl = calculateNetUserPnlImbalance(
|
|
166
|
+
market,
|
|
167
|
+
quoteSpotMarket,
|
|
168
|
+
oraclePriceData
|
|
169
|
+
);
|
|
170
|
+
if (netUnsettledPnl.gt(market.unrealizedPnlMaxImbalance)) {
|
|
171
|
+
assetWeight = assetWeight
|
|
172
|
+
.mul(market.unrealizedPnlMaxImbalance)
|
|
173
|
+
.div(netUnsettledPnl);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
assetWeight = calculateSizeDiscountAssetWeight(
|
|
178
|
+
unrealizedPnl,
|
|
179
|
+
new BN(market.unrealizedPnlImfFactor),
|
|
180
|
+
assetWeight
|
|
181
|
+
);
|
|
182
|
+
break;
|
|
183
|
+
case 'Maintenance':
|
|
184
|
+
assetWeight = new BN(market.unrealizedPnlMaintenanceAssetWeight);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return assetWeight;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function calculateMarketAvailablePNL(
|
|
192
|
+
perpMarket: PerpMarketAccount,
|
|
193
|
+
spotMarket: SpotMarketAccount
|
|
194
|
+
): BN {
|
|
195
|
+
return getTokenAmount(
|
|
196
|
+
perpMarket.pnlPool.scaledBalance,
|
|
197
|
+
spotMarket,
|
|
198
|
+
SpotBalanceType.DEPOSIT
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function calculateNetUserPnl(
|
|
203
|
+
perpMarket: PerpMarketAccount,
|
|
204
|
+
oraclePriceData: OraclePriceData
|
|
205
|
+
): BN {
|
|
206
|
+
const netUserPositionValue = perpMarket.amm.baseAssetAmountWithAmm
|
|
207
|
+
.mul(oraclePriceData.price)
|
|
208
|
+
.div(BASE_PRECISION)
|
|
209
|
+
.div(PRICE_TO_QUOTE_PRECISION);
|
|
210
|
+
|
|
211
|
+
const netUserCostBasis = perpMarket.amm.quoteAssetAmount;
|
|
212
|
+
|
|
213
|
+
const netUserPnl = netUserPositionValue.add(netUserCostBasis);
|
|
214
|
+
|
|
215
|
+
return netUserPnl;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function calculateNetUserPnlImbalance(
|
|
219
|
+
perpMarket: PerpMarketAccount,
|
|
220
|
+
spotMarket: SpotMarketAccount,
|
|
221
|
+
oraclePriceData: OraclePriceData
|
|
222
|
+
): BN {
|
|
223
|
+
const netUserPnl = calculateNetUserPnl(perpMarket, oraclePriceData);
|
|
224
|
+
|
|
225
|
+
const pnlPool = getTokenAmount(
|
|
226
|
+
perpMarket.pnlPool.scaledBalance,
|
|
227
|
+
spotMarket,
|
|
228
|
+
SpotBalanceType.DEPOSIT
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const imbalance = netUserPnl.sub(pnlPool);
|
|
232
|
+
|
|
233
|
+
return imbalance;
|
|
234
|
+
}
|
package/src/math/oracles.ts
CHANGED
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import { AMM, OracleGuardRails } from '../types';
|
|
2
2
|
import { OraclePriceData } from '../oracles/types';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
BID_ASK_SPREAD_PRECISION,
|
|
5
|
+
MARGIN_PRECISION,
|
|
6
|
+
PRICE_PRECISION,
|
|
7
|
+
ONE,
|
|
8
|
+
ZERO,
|
|
9
|
+
} from '../constants/numericConstants';
|
|
10
|
+
import { BN, PerpMarketAccount } from '../index';
|
|
11
|
+
import { assert } from '../assert/assert';
|
|
12
|
+
|
|
13
|
+
export function oraclePriceBands(
|
|
14
|
+
market: PerpMarketAccount,
|
|
15
|
+
oraclePriceData: OraclePriceData
|
|
16
|
+
): [BN, BN] {
|
|
17
|
+
const maxPercentDiff =
|
|
18
|
+
market.marginRatioInitial - market.marginRatioMaintenance;
|
|
19
|
+
const offset = oraclePriceData.price
|
|
20
|
+
.mul(new BN(maxPercentDiff))
|
|
21
|
+
.div(MARGIN_PRECISION);
|
|
22
|
+
|
|
23
|
+
assert(offset.gt(ZERO));
|
|
24
|
+
|
|
25
|
+
return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
|
|
26
|
+
}
|
|
5
27
|
|
|
6
28
|
export function isOracleValid(
|
|
7
29
|
amm: AMM,
|
|
@@ -9,22 +31,24 @@ export function isOracleValid(
|
|
|
9
31
|
oracleGuardRails: OracleGuardRails,
|
|
10
32
|
slot: number
|
|
11
33
|
): boolean {
|
|
12
|
-
const isOraclePriceNonPositive = oraclePriceData.price.
|
|
34
|
+
const isOraclePriceNonPositive = oraclePriceData.price.lte(ZERO);
|
|
13
35
|
const isOraclePriceTooVolatile =
|
|
14
36
|
oraclePriceData.price
|
|
15
|
-
.div(BN.max(ONE, amm.lastOraclePriceTwap))
|
|
37
|
+
.div(BN.max(ONE, amm.historicalOracleData.lastOraclePriceTwap))
|
|
16
38
|
.gt(oracleGuardRails.validity.tooVolatileRatio) ||
|
|
17
|
-
amm.lastOraclePriceTwap
|
|
39
|
+
amm.historicalOracleData.lastOraclePriceTwap
|
|
18
40
|
.div(BN.max(ONE, oraclePriceData.price))
|
|
19
41
|
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
20
42
|
|
|
21
|
-
const isConfidenceTooLarge =
|
|
22
|
-
.
|
|
23
|
-
.
|
|
43
|
+
const isConfidenceTooLarge = new BN(amm.baseSpread)
|
|
44
|
+
.add(BN.max(ONE, oraclePriceData.confidence))
|
|
45
|
+
.mul(BID_ASK_SPREAD_PRECISION)
|
|
46
|
+
.div(oraclePriceData.price)
|
|
47
|
+
.gt(new BN(amm.maxSpread));
|
|
24
48
|
|
|
25
49
|
const oracleIsStale = oraclePriceData.slot
|
|
26
50
|
.sub(new BN(slot))
|
|
27
|
-
.gt(oracleGuardRails.validity.
|
|
51
|
+
.gt(oracleGuardRails.validity.slotsBeforeStaleForAmm);
|
|
28
52
|
|
|
29
53
|
return !(
|
|
30
54
|
!oraclePriceData.hasSufficientNumberOfDataPoints ||
|
|
@@ -34,3 +58,33 @@ export function isOracleValid(
|
|
|
34
58
|
isConfidenceTooLarge
|
|
35
59
|
);
|
|
36
60
|
}
|
|
61
|
+
|
|
62
|
+
export function isOracleTooDivergent(
|
|
63
|
+
amm: AMM,
|
|
64
|
+
oraclePriceData: OraclePriceData,
|
|
65
|
+
oracleGuardRails: OracleGuardRails,
|
|
66
|
+
now: BN
|
|
67
|
+
): boolean {
|
|
68
|
+
const sinceLastUpdate = now.sub(
|
|
69
|
+
amm.historicalOracleData.lastOraclePriceTwapTs
|
|
70
|
+
);
|
|
71
|
+
const sinceStart = BN.max(ZERO, new BN(60 * 5).sub(sinceLastUpdate));
|
|
72
|
+
const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5min
|
|
73
|
+
.mul(sinceStart)
|
|
74
|
+
.add(oraclePriceData.price)
|
|
75
|
+
.mul(sinceLastUpdate)
|
|
76
|
+
.div(sinceStart.add(sinceLastUpdate));
|
|
77
|
+
|
|
78
|
+
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
79
|
+
const oracleSpreadPct = oracleSpread.mul(PRICE_PRECISION).div(oracleTwap5min);
|
|
80
|
+
|
|
81
|
+
const tooDivergent = oracleSpreadPct
|
|
82
|
+
.abs()
|
|
83
|
+
.gte(
|
|
84
|
+
BID_ASK_SPREAD_PRECISION.mul(
|
|
85
|
+
oracleGuardRails.priceDivergence.markOracleDivergenceNumerator
|
|
86
|
+
).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
return tooDivergent;
|
|
90
|
+
}
|
package/src/math/orders.ts
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { User } from '../user';
|
|
2
|
+
import {
|
|
3
|
+
isOneOfVariant,
|
|
4
|
+
isVariant,
|
|
5
|
+
PerpMarketAccount,
|
|
6
|
+
Order,
|
|
7
|
+
PositionDirection,
|
|
8
|
+
} from '../types';
|
|
3
9
|
import { ZERO, TWO } from '../constants/numericConstants';
|
|
4
10
|
import { BN } from '@project-serum/anchor';
|
|
5
11
|
import { OraclePriceData } from '../oracles/types';
|
|
6
12
|
import { getAuctionPrice, isAuctionComplete } from './auction';
|
|
7
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
calculateMaxBaseAssetAmountFillable,
|
|
15
|
+
calculateMaxBaseAssetAmountToTrade,
|
|
16
|
+
} from './amm';
|
|
8
17
|
|
|
9
|
-
export function isOrderRiskIncreasing(
|
|
10
|
-
user: ClearingHouseUser,
|
|
11
|
-
order: Order
|
|
12
|
-
): boolean {
|
|
18
|
+
export function isOrderRiskIncreasing(user: User, order: Order): boolean {
|
|
13
19
|
if (isVariant(order.status, 'init')) {
|
|
14
20
|
return false;
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
const position =
|
|
18
|
-
user.
|
|
24
|
+
user.getPerpPosition(order.marketIndex) ||
|
|
19
25
|
user.getEmptyPosition(order.marketIndex);
|
|
20
26
|
|
|
21
27
|
// if no position exists, it's risk increasing
|
|
@@ -48,7 +54,7 @@ export function isOrderRiskIncreasing(
|
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
export function isOrderRiskIncreasingInSameDirection(
|
|
51
|
-
user:
|
|
57
|
+
user: User,
|
|
52
58
|
order: Order
|
|
53
59
|
): boolean {
|
|
54
60
|
if (isVariant(order.status, 'init')) {
|
|
@@ -56,7 +62,7 @@ export function isOrderRiskIncreasingInSameDirection(
|
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
const position =
|
|
59
|
-
user.
|
|
65
|
+
user.getPerpPosition(order.marketIndex) ||
|
|
60
66
|
user.getEmptyPosition(order.marketIndex);
|
|
61
67
|
|
|
62
68
|
// if no position exists, it's risk increasing
|
|
@@ -80,16 +86,13 @@ export function isOrderRiskIncreasingInSameDirection(
|
|
|
80
86
|
return false;
|
|
81
87
|
}
|
|
82
88
|
|
|
83
|
-
export function isOrderReduceOnly(
|
|
84
|
-
user: ClearingHouseUser,
|
|
85
|
-
order: Order
|
|
86
|
-
): boolean {
|
|
89
|
+
export function isOrderReduceOnly(user: User, order: Order): boolean {
|
|
87
90
|
if (isVariant(order.status, 'init')) {
|
|
88
91
|
return false;
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
const position =
|
|
92
|
-
user.
|
|
95
|
+
user.getPerpPosition(order.marketIndex) ||
|
|
93
96
|
user.getEmptyPosition(order.marketIndex);
|
|
94
97
|
|
|
95
98
|
// if position is long and order is long
|
|
@@ -121,26 +124,25 @@ export function standardizeBaseAssetAmount(
|
|
|
121
124
|
|
|
122
125
|
export function getLimitPrice(
|
|
123
126
|
order: Order,
|
|
124
|
-
market: MarketAccount,
|
|
125
127
|
oraclePriceData: OraclePriceData,
|
|
126
128
|
slot: number
|
|
127
129
|
): BN {
|
|
128
130
|
let limitPrice;
|
|
129
|
-
if (
|
|
130
|
-
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
131
|
+
if (order.oraclePriceOffset !== 0) {
|
|
132
|
+
limitPrice = oraclePriceData.price.add(new BN(order.oraclePriceOffset));
|
|
131
133
|
} else if (isOneOfVariant(order.orderType, ['market', 'triggerMarket'])) {
|
|
132
|
-
if (isAuctionComplete(order, slot)) {
|
|
134
|
+
if (!isAuctionComplete(order, slot)) {
|
|
133
135
|
limitPrice = getAuctionPrice(order, slot);
|
|
134
136
|
} else if (!order.price.eq(ZERO)) {
|
|
135
137
|
limitPrice = order.price;
|
|
136
|
-
} else if (isVariant(order.direction, 'long')) {
|
|
137
|
-
const askPrice = calculateAskPrice(market, oraclePriceData);
|
|
138
|
-
const delta = askPrice.div(new BN(market.amm.maxSlippageRatio));
|
|
139
|
-
limitPrice = askPrice.add(delta);
|
|
140
138
|
} else {
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
139
|
+
// check oracle validity?
|
|
140
|
+
const oraclePrice1Pct = oraclePriceData.price.div(new BN(100));
|
|
141
|
+
if (isVariant(order.direction, 'long')) {
|
|
142
|
+
limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
|
|
143
|
+
} else {
|
|
144
|
+
limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
|
|
145
|
+
}
|
|
144
146
|
}
|
|
145
147
|
} else {
|
|
146
148
|
limitPrice = order.price;
|
|
@@ -148,3 +150,138 @@ export function getLimitPrice(
|
|
|
148
150
|
|
|
149
151
|
return limitPrice;
|
|
150
152
|
}
|
|
153
|
+
|
|
154
|
+
export function getOptionalLimitPrice(
|
|
155
|
+
order: Order,
|
|
156
|
+
oraclePriceData: OraclePriceData,
|
|
157
|
+
slot: number
|
|
158
|
+
): BN | undefined {
|
|
159
|
+
if (hasLimitPrice(order, slot)) {
|
|
160
|
+
return getLimitPrice(order, oraclePriceData, slot);
|
|
161
|
+
} else {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function hasLimitPrice(order: Order, slot: number): boolean {
|
|
167
|
+
return (
|
|
168
|
+
order.price.gt(ZERO) ||
|
|
169
|
+
order.oraclePriceOffset != 0 ||
|
|
170
|
+
!isAuctionComplete(order, slot)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function isFillableByVAMM(
|
|
175
|
+
order: Order,
|
|
176
|
+
market: PerpMarketAccount,
|
|
177
|
+
oraclePriceData: OraclePriceData,
|
|
178
|
+
slot: number,
|
|
179
|
+
ts: number
|
|
180
|
+
): boolean {
|
|
181
|
+
return (
|
|
182
|
+
(isAuctionComplete(order, slot) &&
|
|
183
|
+
!calculateBaseAssetAmountForAmmToFulfill(
|
|
184
|
+
order,
|
|
185
|
+
market,
|
|
186
|
+
oraclePriceData,
|
|
187
|
+
slot
|
|
188
|
+
).eq(ZERO)) ||
|
|
189
|
+
isOrderExpired(order, ts)
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function calculateBaseAssetAmountForAmmToFulfill(
|
|
194
|
+
order: Order,
|
|
195
|
+
market: PerpMarketAccount,
|
|
196
|
+
oraclePriceData: OraclePriceData,
|
|
197
|
+
slot: number
|
|
198
|
+
): BN {
|
|
199
|
+
if (
|
|
200
|
+
isOneOfVariant(order.orderType, ['triggerMarket', 'triggerLimit']) &&
|
|
201
|
+
order.triggered === false
|
|
202
|
+
) {
|
|
203
|
+
return ZERO;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const limitPrice = getOptionalLimitPrice(order, oraclePriceData, slot);
|
|
207
|
+
let baseAssetAmount;
|
|
208
|
+
if (limitPrice !== undefined) {
|
|
209
|
+
baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(
|
|
210
|
+
order,
|
|
211
|
+
market,
|
|
212
|
+
limitPrice,
|
|
213
|
+
oraclePriceData
|
|
214
|
+
);
|
|
215
|
+
} else {
|
|
216
|
+
baseAssetAmount = order.baseAssetAmount.sub(order.baseAssetAmountFilled);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const maxBaseAssetAmount = calculateMaxBaseAssetAmountFillable(
|
|
220
|
+
market.amm,
|
|
221
|
+
order.direction
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
return BN.min(maxBaseAssetAmount, baseAssetAmount);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function calculateBaseAssetAmountToFillUpToLimitPrice(
|
|
228
|
+
order: Order,
|
|
229
|
+
market: PerpMarketAccount,
|
|
230
|
+
limitPrice: BN,
|
|
231
|
+
oraclePriceData: OraclePriceData
|
|
232
|
+
): BN {
|
|
233
|
+
const [maxAmountToTrade, direction] = calculateMaxBaseAssetAmountToTrade(
|
|
234
|
+
market.amm,
|
|
235
|
+
limitPrice,
|
|
236
|
+
order.direction,
|
|
237
|
+
oraclePriceData
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const baseAssetAmount = standardizeBaseAssetAmount(
|
|
241
|
+
maxAmountToTrade,
|
|
242
|
+
market.amm.orderStepSize
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
// Check that directions are the same
|
|
246
|
+
const sameDirection = isSameDirection(direction, order.direction);
|
|
247
|
+
if (!sameDirection) {
|
|
248
|
+
return ZERO;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const baseAssetAmountUnfilled = order.baseAssetAmount.sub(
|
|
252
|
+
order.baseAssetAmountFilled
|
|
253
|
+
);
|
|
254
|
+
return baseAssetAmount.gt(baseAssetAmountUnfilled)
|
|
255
|
+
? baseAssetAmountUnfilled
|
|
256
|
+
: baseAssetAmount;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function isSameDirection(
|
|
260
|
+
firstDirection: PositionDirection,
|
|
261
|
+
secondDirection: PositionDirection
|
|
262
|
+
): boolean {
|
|
263
|
+
return (
|
|
264
|
+
(isVariant(firstDirection, 'long') && isVariant(secondDirection, 'long')) ||
|
|
265
|
+
(isVariant(firstDirection, 'short') && isVariant(secondDirection, 'short'))
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export function isOrderExpired(order: Order, ts: number): boolean {
|
|
270
|
+
if (
|
|
271
|
+
isOneOfVariant(order.orderType, ['triggerMarket', 'triggerLimit']) ||
|
|
272
|
+
!isVariant(order.status, 'open') ||
|
|
273
|
+
order.maxTs.eq(ZERO)
|
|
274
|
+
) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return new BN(ts).gt(order.maxTs);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export function isMarketOrder(order: Order): boolean {
|
|
282
|
+
return isOneOfVariant(order.orderType, ['market', 'triggerMarket']);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function isLimitOrder(order: Order): boolean {
|
|
286
|
+
return isOneOfVariant(order.orderType, ['limit', 'triggerLimit']);
|
|
287
|
+
}
|