@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.12
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/clearingHouse.d.ts +7 -2
- package/lib/clearingHouse.js +157 -37
- package/lib/clearingHouseUser.d.ts +10 -15
- package/lib/clearingHouseUser.js +92 -74
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +4 -3
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +37 -11
- package/lib/idl/clearing_house.json +97 -19
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/bankBalance.d.ts +3 -1
- package/lib/math/bankBalance.js +54 -1
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +72 -0
- package/lib/math/market.d.ts +4 -1
- package/lib/math/market.js +35 -1
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +42 -12
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +2 -77
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tokenFaucet.js +23 -12
- package/lib/tx/retryTxSender.js +9 -2
- package/lib/types.d.ts +24 -3
- package/lib/types.js +6 -0
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +1 -1
- package/src/clearingHouse.ts +301 -47
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +213 -104
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +6 -3
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +3 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/types.ts +2 -0
- package/src/factory/bigNum.js +37 -11
- package/src/factory/bigNum.ts +43 -13
- package/src/idl/clearing_house.json +97 -19
- package/src/index.js +67 -98
- package/src/index.ts +1 -0
- package/src/math/bankBalance.ts +98 -1
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/position.ts +59 -9
- package/src/orders.ts +4 -157
- package/src/tokenFaucet.js +189 -0
- package/src/tokenFaucet.ts +38 -15
- package/src/tx/retryTxSender.ts +11 -3
- package/src/types.js +12 -1
- package/src/types.ts +25 -3
- package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +2 -0
- package/src/addresses/pda.js +0 -104
- package/src/math/bankBalance.js +0 -75
- package/src/math/market.js +0 -57
- package/src/math/orders.js +0 -110
- package/src/math/position.js +0 -140
- package/src/orders.js +0 -134
- package/src/tx/retryTxSender.js +0 -188
|
@@ -2027,14 +2027,6 @@
|
|
|
2027
2027
|
"defined": "PoolBalance"
|
|
2028
2028
|
}
|
|
2029
2029
|
},
|
|
2030
|
-
{
|
|
2031
|
-
"name": "unsettledProfit",
|
|
2032
|
-
"type": "u128"
|
|
2033
|
-
},
|
|
2034
|
-
{
|
|
2035
|
-
"name": "unsettledLoss",
|
|
2036
|
-
"type": "u128"
|
|
2037
|
-
},
|
|
2038
2030
|
{
|
|
2039
2031
|
"name": "imfFactor",
|
|
2040
2032
|
"type": "u128"
|
|
@@ -2275,6 +2267,10 @@
|
|
|
2275
2267
|
]
|
|
2276
2268
|
}
|
|
2277
2269
|
},
|
|
2270
|
+
{
|
|
2271
|
+
"name": "nextLiquidationId",
|
|
2272
|
+
"type": "u16"
|
|
2273
|
+
},
|
|
2278
2274
|
{
|
|
2279
2275
|
"name": "beingLiquidated",
|
|
2280
2276
|
"type": "bool"
|
|
@@ -2413,7 +2409,7 @@
|
|
|
2413
2409
|
},
|
|
2414
2410
|
{
|
|
2415
2411
|
"name": "quoteAssetAmount",
|
|
2416
|
-
"type": "
|
|
2412
|
+
"type": "i128"
|
|
2417
2413
|
},
|
|
2418
2414
|
{
|
|
2419
2415
|
"name": "userPnl",
|
|
@@ -2615,11 +2611,19 @@
|
|
|
2615
2611
|
},
|
|
2616
2612
|
{
|
|
2617
2613
|
"name": "quoteAssetAmountLong",
|
|
2618
|
-
"type": "
|
|
2614
|
+
"type": "i128"
|
|
2619
2615
|
},
|
|
2620
2616
|
{
|
|
2621
2617
|
"name": "quoteAssetAmountShort",
|
|
2622
|
-
"type": "
|
|
2618
|
+
"type": "i128"
|
|
2619
|
+
},
|
|
2620
|
+
{
|
|
2621
|
+
"name": "quoteEntryAmountLong",
|
|
2622
|
+
"type": "i128"
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
"name": "quoteEntryAmountShort",
|
|
2626
|
+
"type": "i128"
|
|
2623
2627
|
},
|
|
2624
2628
|
{
|
|
2625
2629
|
"name": "lastFundingRate",
|
|
@@ -3061,11 +3065,11 @@
|
|
|
3061
3065
|
},
|
|
3062
3066
|
{
|
|
3063
3067
|
"name": "quoteAssetAmount",
|
|
3064
|
-
"type": "
|
|
3068
|
+
"type": "i128"
|
|
3065
3069
|
},
|
|
3066
3070
|
{
|
|
3067
3071
|
"name": "quoteEntryAmount",
|
|
3068
|
-
"type": "
|
|
3072
|
+
"type": "i128"
|
|
3069
3073
|
},
|
|
3070
3074
|
{
|
|
3071
3075
|
"name": "lastCumulativeFundingRate",
|
|
@@ -3083,10 +3087,6 @@
|
|
|
3083
3087
|
"name": "openOrders",
|
|
3084
3088
|
"type": "u128"
|
|
3085
3089
|
},
|
|
3086
|
-
{
|
|
3087
|
-
"name": "unsettledPnl",
|
|
3088
|
-
"type": "i128"
|
|
3089
|
-
},
|
|
3090
3090
|
{
|
|
3091
3091
|
"name": "openBids",
|
|
3092
3092
|
"type": "i128"
|
|
@@ -3279,6 +3279,29 @@
|
|
|
3279
3279
|
]
|
|
3280
3280
|
}
|
|
3281
3281
|
},
|
|
3282
|
+
{
|
|
3283
|
+
"name": "PositionUpdateType",
|
|
3284
|
+
"type": {
|
|
3285
|
+
"kind": "enum",
|
|
3286
|
+
"variants": [
|
|
3287
|
+
{
|
|
3288
|
+
"name": "Open"
|
|
3289
|
+
},
|
|
3290
|
+
{
|
|
3291
|
+
"name": "Increase"
|
|
3292
|
+
},
|
|
3293
|
+
{
|
|
3294
|
+
"name": "Reduce"
|
|
3295
|
+
},
|
|
3296
|
+
{
|
|
3297
|
+
"name": "Close"
|
|
3298
|
+
},
|
|
3299
|
+
{
|
|
3300
|
+
"name": "Flip"
|
|
3301
|
+
}
|
|
3302
|
+
]
|
|
3303
|
+
}
|
|
3304
|
+
},
|
|
3282
3305
|
{
|
|
3283
3306
|
"name": "LiquidationMultiplierType",
|
|
3284
3307
|
"type": {
|
|
@@ -3813,12 +3836,12 @@
|
|
|
3813
3836
|
"index": false
|
|
3814
3837
|
},
|
|
3815
3838
|
{
|
|
3816
|
-
"name": "
|
|
3839
|
+
"name": "makerPnl",
|
|
3817
3840
|
"type": "i128",
|
|
3818
3841
|
"index": false
|
|
3819
3842
|
},
|
|
3820
3843
|
{
|
|
3821
|
-
"name": "
|
|
3844
|
+
"name": "takerPnl",
|
|
3822
3845
|
"type": "i128",
|
|
3823
3846
|
"index": false
|
|
3824
3847
|
},
|
|
@@ -3923,6 +3946,11 @@
|
|
|
3923
3946
|
"type": "i128",
|
|
3924
3947
|
"index": false
|
|
3925
3948
|
},
|
|
3949
|
+
{
|
|
3950
|
+
"name": "liquidationId",
|
|
3951
|
+
"type": "u16",
|
|
3952
|
+
"index": false
|
|
3953
|
+
},
|
|
3926
3954
|
{
|
|
3927
3955
|
"name": "liquidatePerp",
|
|
3928
3956
|
"type": {
|
|
@@ -3952,6 +3980,46 @@
|
|
|
3952
3980
|
"index": false
|
|
3953
3981
|
}
|
|
3954
3982
|
]
|
|
3983
|
+
},
|
|
3984
|
+
{
|
|
3985
|
+
"name": "SettlePnlRecord",
|
|
3986
|
+
"fields": [
|
|
3987
|
+
{
|
|
3988
|
+
"name": "ts",
|
|
3989
|
+
"type": "i64",
|
|
3990
|
+
"index": false
|
|
3991
|
+
},
|
|
3992
|
+
{
|
|
3993
|
+
"name": "marketIndex",
|
|
3994
|
+
"type": "u64",
|
|
3995
|
+
"index": false
|
|
3996
|
+
},
|
|
3997
|
+
{
|
|
3998
|
+
"name": "pnl",
|
|
3999
|
+
"type": "i128",
|
|
4000
|
+
"index": false
|
|
4001
|
+
},
|
|
4002
|
+
{
|
|
4003
|
+
"name": "baseAssetAmount",
|
|
4004
|
+
"type": "i128",
|
|
4005
|
+
"index": false
|
|
4006
|
+
},
|
|
4007
|
+
{
|
|
4008
|
+
"name": "quoteAssetAmountAfter",
|
|
4009
|
+
"type": "i128",
|
|
4010
|
+
"index": false
|
|
4011
|
+
},
|
|
4012
|
+
{
|
|
4013
|
+
"name": "quoteEntryAmount",
|
|
4014
|
+
"type": "i128",
|
|
4015
|
+
"index": false
|
|
4016
|
+
},
|
|
4017
|
+
{
|
|
4018
|
+
"name": "oraclePrice",
|
|
4019
|
+
"type": "i128",
|
|
4020
|
+
"index": false
|
|
4021
|
+
}
|
|
4022
|
+
]
|
|
3955
4023
|
}
|
|
3956
4024
|
],
|
|
3957
4025
|
"errors": [
|
|
@@ -4457,6 +4525,16 @@
|
|
|
4457
4525
|
},
|
|
4458
4526
|
{
|
|
4459
4527
|
"code": 6100,
|
|
4528
|
+
"name": "InvalidPositionLastFundingRate",
|
|
4529
|
+
"msg": "InvalidPositionLastFundingRate"
|
|
4530
|
+
},
|
|
4531
|
+
{
|
|
4532
|
+
"code": 6101,
|
|
4533
|
+
"name": "InvalidPositionDelta",
|
|
4534
|
+
"msg": "InvalidPositionDelta"
|
|
4535
|
+
},
|
|
4536
|
+
{
|
|
4537
|
+
"code": 6102,
|
|
4460
4538
|
"name": "DefaultError",
|
|
4461
4539
|
"msg": "DefaultError"
|
|
4462
4540
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export * from './math/amm';
|
|
|
34
34
|
export * from './math/trade';
|
|
35
35
|
export * from './math/orders';
|
|
36
36
|
export * from './math/repeg';
|
|
37
|
+
export * from './math/margin';
|
|
37
38
|
export * from './orders';
|
|
38
39
|
export * from './orderParams';
|
|
39
40
|
export * from './slot/SlotSubscriber';
|
package/lib/index.js
CHANGED
|
@@ -57,6 +57,7 @@ __exportStar(require("./math/amm"), exports);
|
|
|
57
57
|
__exportStar(require("./math/trade"), exports);
|
|
58
58
|
__exportStar(require("./math/orders"), exports);
|
|
59
59
|
__exportStar(require("./math/repeg"), exports);
|
|
60
|
+
__exportStar(require("./math/margin"), exports);
|
|
60
61
|
__exportStar(require("./orders"), exports);
|
|
61
62
|
__exportStar(require("./orderParams"), exports);
|
|
62
63
|
__exportStar(require("./slot/SlotSubscriber"), exports);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { BankAccount, BankBalanceType } from '../types';
|
|
2
|
+
import { BankAccount, BankBalanceType, MarginCategory } from '../types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
export declare function getBalance(tokenAmount: BN, bank: BankAccount, balanceType: BankBalanceType): BN;
|
|
5
5
|
export declare function getTokenAmount(balanceAmount: BN, bank: BankAccount, balanceType: BankBalanceType): BN;
|
|
6
|
+
export declare function calculateAssetWeight(balanceAmount: BN, bank: BankAccount, marginCategory: MarginCategory): BN;
|
|
7
|
+
export declare function calculateLiabilityWeight(balanceAmount: BN, bank: BankAccount, marginCategory: MarginCategory): BN;
|
|
6
8
|
export declare function calculateInterestAccumulated(bank: BankAccount, now: BN): {
|
|
7
9
|
borrowInterest: BN;
|
|
8
10
|
depositInterest: BN;
|
package/lib/math/bankBalance.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateInterestAccumulated = exports.getTokenAmount = exports.getBalance = void 0;
|
|
3
|
+
exports.calculateInterestAccumulated = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenAmount = exports.getBalance = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const anchor_1 = require("@project-serum/anchor");
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
7
8
|
function getBalance(tokenAmount, bank, balanceType) {
|
|
8
9
|
const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - bank.decimals));
|
|
9
10
|
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
@@ -24,6 +25,58 @@ function getTokenAmount(balanceAmount, bank, balanceType) {
|
|
|
24
25
|
return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
|
|
25
26
|
}
|
|
26
27
|
exports.getTokenAmount = getTokenAmount;
|
|
28
|
+
function calculateAssetWeight(balanceAmount, bank, marginCategory) {
|
|
29
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(bank.decimals));
|
|
30
|
+
let sizeInAmmReservePrecision;
|
|
31
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
32
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
36
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
37
|
+
.div(sizePrecision);
|
|
38
|
+
}
|
|
39
|
+
let assetWeight;
|
|
40
|
+
switch (marginCategory) {
|
|
41
|
+
case 'Initial':
|
|
42
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.initialAssetWeight);
|
|
43
|
+
break;
|
|
44
|
+
case 'Maintenance':
|
|
45
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.maintenanceAssetWeight);
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
assetWeight = bank.initialAssetWeight;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return assetWeight;
|
|
52
|
+
}
|
|
53
|
+
exports.calculateAssetWeight = calculateAssetWeight;
|
|
54
|
+
function calculateLiabilityWeight(balanceAmount, bank, marginCategory) {
|
|
55
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(bank.decimals));
|
|
56
|
+
let sizeInAmmReservePrecision;
|
|
57
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
58
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
62
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
63
|
+
.div(sizePrecision);
|
|
64
|
+
}
|
|
65
|
+
let assetWeight;
|
|
66
|
+
switch (marginCategory) {
|
|
67
|
+
case 'Initial':
|
|
68
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.initialLiabilityWeight, numericConstants_1.BANK_WEIGHT_PRECISION);
|
|
69
|
+
break;
|
|
70
|
+
case 'Maintenance':
|
|
71
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.maintenanceLiabilityWeight, numericConstants_1.BANK_WEIGHT_PRECISION);
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
assetWeight = bank.initialLiabilityWeight;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
return assetWeight;
|
|
78
|
+
}
|
|
79
|
+
exports.calculateLiabilityWeight = calculateLiabilityWeight;
|
|
27
80
|
function calculateInterestAccumulated(bank, now) {
|
|
28
81
|
const token_deposit_amount = getTokenAmount(bank.depositBalance, bank, types_1.BankBalanceType.DEPOSIT);
|
|
29
82
|
const token_borrow_amount = getTokenAmount(bank.borrowBalance, bank, types_1.BankBalanceType.BORROW);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@project-serum/anchor';
|
|
3
|
+
import { OraclePriceData } from '../oracles/types';
|
|
4
|
+
import { MarketAccount, UserPosition } from '..';
|
|
5
|
+
export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
6
|
+
imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
|
|
7
|
+
export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
8
|
+
imfFactor: BN, assetWeight: BN): BN;
|
|
9
|
+
export declare function calculateOraclePriceForPerpMargin(marketPosition: UserPosition, market: MarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
10
|
+
export declare function calculateMarginBaseAssetValue(market: MarketAccount, marketPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
|
|
11
|
+
export declare function calculateWorstCaseBaseAssetAmount(marketPosition: UserPosition): BN;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateWorstCaseBaseAssetAmount = exports.calculateMarginBaseAssetValue = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
8
|
+
imfFactor, liabilityWeight, precision) {
|
|
9
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
10
|
+
return liabilityWeight;
|
|
11
|
+
}
|
|
12
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
13
|
+
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.BANK_IMF_PRECISION.div(imfFactor))));
|
|
14
|
+
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
|
15
|
+
.mul(imfFactor)
|
|
16
|
+
.div(new anchor_1.BN(100000).mul(numericConstants_1.BANK_IMF_PRECISION).div(precision)) // 1e5
|
|
17
|
+
);
|
|
18
|
+
const maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
|
|
19
|
+
return maxLiabilityWeight;
|
|
20
|
+
}
|
|
21
|
+
exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
|
|
22
|
+
function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
|
|
23
|
+
imfFactor, assetWeight) {
|
|
24
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
25
|
+
return assetWeight;
|
|
26
|
+
}
|
|
27
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
28
|
+
const imfNumerator = numericConstants_1.BANK_IMF_PRECISION.add(numericConstants_1.BANK_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
29
|
+
const sizeDiscountAssetWeight = imfNumerator.mul(numericConstants_1.BANK_WEIGHT_PRECISION).div(numericConstants_1.BANK_IMF_PRECISION.add(sizeSqrt // 1e5
|
|
30
|
+
.mul(imfFactor)
|
|
31
|
+
.div(new anchor_1.BN(100000)) // 1e5
|
|
32
|
+
));
|
|
33
|
+
const minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
34
|
+
return minAssetWeight;
|
|
35
|
+
}
|
|
36
|
+
exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
|
|
37
|
+
function calculateOraclePriceForPerpMargin(marketPosition, market, oraclePriceData) {
|
|
38
|
+
const oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
|
|
39
|
+
.mul(oraclePriceData.price)
|
|
40
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
|
|
41
|
+
.mul(oraclePriceData.price)
|
|
42
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
|
|
43
|
+
let marginPrice;
|
|
44
|
+
if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
45
|
+
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
49
|
+
}
|
|
50
|
+
return marginPrice;
|
|
51
|
+
}
|
|
52
|
+
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
53
|
+
function calculateMarginBaseAssetValue(market, marketPosition, oraclePriceData) {
|
|
54
|
+
const marginPrice = calculateOraclePriceForPerpMargin(marketPosition, market, oraclePriceData);
|
|
55
|
+
const baseAssetValue = marketPosition.baseAssetAmount
|
|
56
|
+
.abs()
|
|
57
|
+
.mul(marginPrice)
|
|
58
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
59
|
+
return baseAssetValue;
|
|
60
|
+
}
|
|
61
|
+
exports.calculateMarginBaseAssetValue = calculateMarginBaseAssetValue;
|
|
62
|
+
function calculateWorstCaseBaseAssetAmount(marketPosition) {
|
|
63
|
+
const allBids = marketPosition.baseAssetAmount.add(marketPosition.openBids);
|
|
64
|
+
const allAsks = marketPosition.baseAssetAmount.add(marketPosition.openAsks);
|
|
65
|
+
if (allBids.abs().gt(allAsks.abs())) {
|
|
66
|
+
return allBids;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return allAsks;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
|
package/lib/math/market.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from '@project-serum/anchor';
|
|
3
|
-
import { MarketAccount, PositionDirection } from '../types';
|
|
3
|
+
import { MarketAccount, PositionDirection, MarginCategory, BankAccount } from '../types';
|
|
4
4
|
import { OraclePriceData } from '../oracles/types';
|
|
5
5
|
/**
|
|
6
6
|
* Calculates market mark price
|
|
@@ -26,3 +26,6 @@ export declare function calculateAskPrice(market: MarketAccount, oraclePriceData
|
|
|
26
26
|
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: MarketAccount): MarketAccount;
|
|
27
27
|
export declare function calculateMarkOracleSpread(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
28
28
|
export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
|
|
29
|
+
export declare function calculateMarketMarginRatio(market: MarketAccount, size: BN, marginCategory: MarginCategory): number;
|
|
30
|
+
export declare function calculateUnsettledAssetWeight(market: MarketAccount, unsettledPnl: BN, marginCategory: MarginCategory): BN;
|
|
31
|
+
export declare function calculateMarketAvailablePNL(market: MarketAccount, bank: BankAccount): BN;
|
package/lib/math/market.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
3
|
+
exports.calculateMarketAvailablePNL = exports.calculateUnsettledAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const amm_1 = require("./amm");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
8
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
9
|
+
const bankBalance_1 = require("./bankBalance");
|
|
6
10
|
/**
|
|
7
11
|
* Calculates market mark price
|
|
8
12
|
*
|
|
@@ -55,3 +59,33 @@ function calculateOracleSpread(price, oraclePriceData) {
|
|
|
55
59
|
return price.sub(oraclePriceData.price);
|
|
56
60
|
}
|
|
57
61
|
exports.calculateOracleSpread = calculateOracleSpread;
|
|
62
|
+
function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
63
|
+
let marginRatio;
|
|
64
|
+
switch (marginCategory) {
|
|
65
|
+
case 'Initial':
|
|
66
|
+
marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
67
|
+
break;
|
|
68
|
+
case 'Maintenance':
|
|
69
|
+
marginRatio = market.marginRatioMaintenance;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
return marginRatio;
|
|
73
|
+
}
|
|
74
|
+
exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
|
|
75
|
+
function calculateUnsettledAssetWeight(market, unsettledPnl, marginCategory) {
|
|
76
|
+
let assetWeight;
|
|
77
|
+
switch (marginCategory) {
|
|
78
|
+
case 'Initial':
|
|
79
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unsettledPnl, market.unsettledImfFactor, new anchor_1.BN(market.unsettledInitialAssetWeight));
|
|
80
|
+
break;
|
|
81
|
+
case 'Maintenance':
|
|
82
|
+
assetWeight = new anchor_1.BN(market.unsettledMaintenanceAssetWeight);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
return assetWeight;
|
|
86
|
+
}
|
|
87
|
+
exports.calculateUnsettledAssetWeight = calculateUnsettledAssetWeight;
|
|
88
|
+
function calculateMarketAvailablePNL(market, bank) {
|
|
89
|
+
return (0, bankBalance_1.getTokenAmount)(market.pnlPool.balance, bank, types_1.BankBalanceType.DEPOSIT);
|
|
90
|
+
}
|
|
91
|
+
exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
|
package/lib/math/position.d.ts
CHANGED
|
@@ -17,9 +17,11 @@ export declare function calculateBaseAssetValue(market: MarketAccount, userPosit
|
|
|
17
17
|
* @param market
|
|
18
18
|
* @param marketPosition
|
|
19
19
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
20
|
+
* @param oraclePriceData
|
|
20
21
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
21
22
|
*/
|
|
22
23
|
export declare function calculatePositionPNL(market: MarketAccount, marketPosition: UserPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
|
|
24
|
+
export declare function calculateUnsettledPnl(market: MarketAccount, marketPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
|
|
23
25
|
/**
|
|
24
26
|
*
|
|
25
27
|
* @param market
|
|
@@ -34,6 +36,12 @@ export declare function positionIsAvailable(position: UserPosition): boolean;
|
|
|
34
36
|
* @returns Precision: MARK_PRICE_PRECISION (10^10)
|
|
35
37
|
*/
|
|
36
38
|
export declare function calculateEntryPrice(userPosition: UserPosition): BN;
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param userPosition
|
|
42
|
+
* @returns Precision: MARK_PRICE_PRECISION (10^10)
|
|
43
|
+
*/
|
|
44
|
+
export declare function calculateCostBasis(userPosition: UserPosition): BN;
|
|
37
45
|
export declare function findDirectionToClose(userPosition: UserPosition): PositionDirection;
|
|
38
46
|
export declare function positionCurrentDirection(userPosition: UserPosition): PositionDirection;
|
|
39
47
|
export declare function isEmptyPosition(userPosition: UserPosition): boolean;
|
package/lib/math/position.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
3
|
+
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateCostBasis = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculateUnsettledPnl = 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 margin_1 = require("./margin");
|
|
8
9
|
/**
|
|
9
10
|
* calculateBaseAssetValue
|
|
10
11
|
* = market value of closing entire position
|
|
@@ -53,20 +54,20 @@ exports.calculateBaseAssetValue = calculateBaseAssetValue;
|
|
|
53
54
|
* @param market
|
|
54
55
|
* @param marketPosition
|
|
55
56
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
57
|
+
* @param oraclePriceData
|
|
56
58
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
57
59
|
*/
|
|
58
60
|
function calculatePositionPNL(market, marketPosition, withFunding = false, oraclePriceData) {
|
|
59
61
|
if (marketPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
const baseAssetValue = calculateBaseAssetValue(market, marketPosition, oraclePriceData);
|
|
63
|
-
let pnl;
|
|
64
|
-
if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
65
|
-
pnl = baseAssetValue.sub(marketPosition.quoteAssetAmount);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
pnl = marketPosition.quoteAssetAmount.sub(baseAssetValue);
|
|
62
|
+
return marketPosition.quoteAssetAmount;
|
|
69
63
|
}
|
|
64
|
+
const baseAssetValue = (0, margin_1.calculateMarginBaseAssetValue)(market, marketPosition, oraclePriceData);
|
|
65
|
+
const baseAssetValueSign = marketPosition.baseAssetAmount.isNeg()
|
|
66
|
+
? new __1.BN(-1)
|
|
67
|
+
: new __1.BN(1);
|
|
68
|
+
let pnl = baseAssetValue
|
|
69
|
+
.mul(baseAssetValueSign)
|
|
70
|
+
.add(marketPosition.quoteAssetAmount);
|
|
70
71
|
if (withFunding) {
|
|
71
72
|
const fundingRatePnL = calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
72
73
|
pnl = pnl.add(fundingRatePnL);
|
|
@@ -74,6 +75,19 @@ function calculatePositionPNL(market, marketPosition, withFunding = false, oracl
|
|
|
74
75
|
return pnl;
|
|
75
76
|
}
|
|
76
77
|
exports.calculatePositionPNL = calculatePositionPNL;
|
|
78
|
+
function calculateUnsettledPnl(market, marketPosition, oraclePriceData) {
|
|
79
|
+
const unrealizedPnl = calculatePositionPNL(market, marketPosition, true, oraclePriceData);
|
|
80
|
+
let unsettledPnl = unrealizedPnl;
|
|
81
|
+
if (unrealizedPnl.gt(numericConstants_1.ZERO)) {
|
|
82
|
+
const fundingPnL = calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
83
|
+
const maxPositivePnl = __1.BN.max(marketPosition.quoteAssetAmount
|
|
84
|
+
.add(marketPosition.quoteEntryAmount)
|
|
85
|
+
.add(fundingPnL), numericConstants_1.ZERO);
|
|
86
|
+
unsettledPnl = __1.BN.min(maxPositivePnl, unrealizedPnl);
|
|
87
|
+
}
|
|
88
|
+
return unsettledPnl;
|
|
89
|
+
}
|
|
90
|
+
exports.calculateUnsettledPnl = calculateUnsettledPnl;
|
|
77
91
|
/**
|
|
78
92
|
*
|
|
79
93
|
* @param market
|
|
@@ -103,7 +117,7 @@ exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
|
|
|
103
117
|
function positionIsAvailable(position) {
|
|
104
118
|
return (position.baseAssetAmount.eq(numericConstants_1.ZERO) &&
|
|
105
119
|
position.openOrders.eq(numericConstants_1.ZERO) &&
|
|
106
|
-
position.
|
|
120
|
+
position.quoteAssetAmount.eq(numericConstants_1.ZERO));
|
|
107
121
|
}
|
|
108
122
|
exports.positionIsAvailable = positionIsAvailable;
|
|
109
123
|
/**
|
|
@@ -115,13 +129,29 @@ function calculateEntryPrice(userPosition) {
|
|
|
115
129
|
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
116
130
|
return numericConstants_1.ZERO;
|
|
117
131
|
}
|
|
118
|
-
return userPosition.
|
|
132
|
+
return userPosition.quoteEntryAmount
|
|
119
133
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
120
134
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
121
135
|
.div(userPosition.baseAssetAmount)
|
|
122
136
|
.abs();
|
|
123
137
|
}
|
|
124
138
|
exports.calculateEntryPrice = calculateEntryPrice;
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @param userPosition
|
|
142
|
+
* @returns Precision: MARK_PRICE_PRECISION (10^10)
|
|
143
|
+
*/
|
|
144
|
+
function calculateCostBasis(userPosition) {
|
|
145
|
+
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
146
|
+
return numericConstants_1.ZERO;
|
|
147
|
+
}
|
|
148
|
+
return userPosition.quoteAssetAmount
|
|
149
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
150
|
+
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
151
|
+
.div(userPosition.baseAssetAmount)
|
|
152
|
+
.abs();
|
|
153
|
+
}
|
|
154
|
+
exports.calculateCostBasis = calculateCostBasis;
|
|
125
155
|
function findDirectionToClose(userPosition) {
|
|
126
156
|
return userPosition.baseAssetAmount.gt(numericConstants_1.ZERO)
|
|
127
157
|
? types_1.PositionDirection.SHORT
|
package/lib/orders.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { MarketAccount, Order
|
|
2
|
+
import { MarketAccount, Order } from './types';
|
|
3
3
|
import { BN } from '.';
|
|
4
4
|
import { OraclePriceData } from '.';
|
|
5
|
-
export declare function calculateNewStateAfterOrder(userAccount: UserAccount, userPosition: UserPosition, market: MarketAccount, order: Order): [UserAccount, UserPosition, MarketAccount] | null;
|
|
6
5
|
export declare function calculateBaseAssetAmountMarketCanExecute(market: MarketAccount, order: Order, oraclePriceData?: OraclePriceData): BN;
|
|
7
6
|
export declare function calculateAmountToTradeForLimit(market: MarketAccount, order: Order, oraclePriceData?: OraclePriceData): BN;
|
|
8
7
|
export declare function calculateAmountToTradeForTriggerLimit(market: MarketAccount, order: Order): BN;
|