@drift-labs/sdk 0.2.0-master.1 → 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/accounts/types.d.ts +1 -0
- package/lib/admin.d.ts +8 -5
- package/lib/admin.js +43 -11
- package/lib/clearingHouse.d.ts +35 -20
- package/lib/clearingHouse.js +497 -154
- package/lib/clearingHouseUser.d.ts +12 -17
- package/lib/clearingHouseUser.js +97 -88
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +12 -4
- package/lib/constants/numericConstants.d.ts +4 -0
- package/lib/constants/numericConstants.js +5 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +9 -2
- package/lib/factory/bigNum.js +50 -16
- package/lib/idl/clearing_house.json +858 -177
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +4 -2
- package/lib/index.js +8 -2
- package/lib/math/amm.d.ts +6 -1
- package/lib/math/amm.js +124 -41
- package/lib/math/auction.js +4 -1
- 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/orders.d.ts +2 -2
- package/lib/math/orders.js +18 -11
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +44 -12
- package/lib/math/repeg.js +1 -1
- package/lib/math/trade.d.ts +1 -1
- package/lib/math/trade.js +7 -10
- package/lib/orderParams.d.ts +14 -5
- package/lib/orderParams.js +8 -96
- package/lib/orders.d.ts +2 -4
- package/lib/orders.js +7 -161
- 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.js +9 -2
- package/lib/tx/utils.js +1 -1
- package/lib/types.d.ts +159 -15
- package/lib/types.js +59 -1
- 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 +3 -3
- package/src/accounts/bulkAccountLoader.js +197 -0
- package/src/accounts/bulkUserSubscription.js +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
- package/src/accounts/pollingOracleSubscriber.js +93 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
- package/src/accounts/pollingUserAccountSubscriber.js +132 -0
- package/src/accounts/types.js +10 -0
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +93 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
- package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
- package/src/addresses/marketAddresses.js +26 -0
- package/src/admin.ts +66 -14
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +836 -254
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +219 -121
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +14 -4
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +5 -0
- package/src/events/eventList.js +77 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/eventSubscriber.js +139 -0
- package/src/events/fetchLogs.js +50 -0
- package/src/events/pollingLogProvider.js +64 -0
- package/src/events/sort.js +44 -0
- package/src/events/txEventCache.js +71 -0
- package/src/events/types.js +20 -0
- package/src/events/types.ts +2 -0
- package/src/events/webSocketLogProvider.js +41 -0
- package/src/examples/makeTradeExample.js +80 -0
- package/src/factory/bigNum.js +390 -0
- package/src/factory/bigNum.ts +65 -18
- package/src/factory/oracleClient.js +20 -0
- package/src/idl/clearing_house.json +858 -177
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.js +69 -0
- package/src/index.ts +4 -2
- package/src/math/amm.js +369 -0
- package/src/math/amm.ts +207 -52
- package/src/math/auction.js +42 -0
- package/src/math/auction.ts +5 -1
- package/src/math/bankBalance.ts +98 -1
- package/src/math/conversion.js +11 -0
- package/src/math/funding.js +248 -0
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/oracles.js +26 -0
- package/src/math/orders.ts +17 -13
- package/src/math/position.ts +63 -9
- package/src/math/repeg.js +128 -0
- package/src/math/repeg.ts +2 -1
- package/src/math/state.js +15 -0
- package/src/math/trade.js +253 -0
- package/src/math/trade.ts +23 -25
- package/src/math/utils.js +0 -1
- package/src/mockUSDCFaucet.js +280 -0
- package/src/oracles/oracleClientCache.js +19 -0
- package/src/oracles/pythClient.js +46 -0
- package/src/oracles/quoteAssetOracleClient.js +32 -0
- package/src/oracles/switchboardClient.js +69 -0
- package/src/oracles/types.js +2 -0
- package/src/orderParams.js +20 -0
- package/src/orderParams.ts +20 -141
- package/src/orders.ts +10 -287
- package/src/slot/SlotSubscriber.js +39 -0
- package/src/slot/SlotSubscriber.ts +11 -1
- package/src/token/index.js +38 -0
- package/src/tokenFaucet.js +189 -0
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
- package/src/tx/retryTxSender.ts +11 -3
- package/src/tx/types.js +2 -0
- package/src/tx/utils.js +17 -0
- package/src/tx/utils.ts +1 -1
- package/src/types.js +125 -0
- package/src/types.ts +155 -17
- package/src/userName.js +20 -0
- package/src/util/computeUnits.js +21 -11
- package/src/util/computeUnits.ts +1 -1
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/src/wallet.js +35 -0
- package/tests/bn/test.ts +2 -0
- package/src/util/computeUnits.js.map +0 -1
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
3
|
-
"name": "
|
|
2
|
+
"version": "0.1.0",
|
|
3
|
+
"name": "token_faucet",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
6
6
|
"name": "initialize",
|
|
7
7
|
"accounts": [
|
|
8
8
|
{
|
|
9
|
-
"name": "
|
|
9
|
+
"name": "faucetConfig",
|
|
10
10
|
"isMut": true,
|
|
11
11
|
"isSigner": false
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
"name": "admin",
|
|
15
|
-
"isMut":
|
|
15
|
+
"isMut": true,
|
|
16
16
|
"isSigner": true
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"name": "mintAccount",
|
|
20
|
-
"isMut":
|
|
20
|
+
"isMut": true,
|
|
21
21
|
"isSigner": false
|
|
22
22
|
},
|
|
23
23
|
{
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
"name": "systemProgram",
|
|
30
30
|
"isMut": false,
|
|
31
31
|
"isSigner": false
|
|
32
|
-
}
|
|
33
|
-
],
|
|
34
|
-
"args": [
|
|
32
|
+
},
|
|
35
33
|
{
|
|
36
|
-
"name": "
|
|
37
|
-
"
|
|
34
|
+
"name": "tokenProgram",
|
|
35
|
+
"isMut": false,
|
|
36
|
+
"isSigner": false
|
|
38
37
|
}
|
|
39
|
-
]
|
|
38
|
+
],
|
|
39
|
+
"args": []
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"name": "mintToUser",
|
|
43
43
|
"accounts": [
|
|
44
44
|
{
|
|
45
|
-
"name": "
|
|
45
|
+
"name": "faucetConfig",
|
|
46
46
|
"isMut": false,
|
|
47
47
|
"isSigner": false
|
|
48
48
|
},
|
|
@@ -73,11 +73,42 @@
|
|
|
73
73
|
"type": "u64"
|
|
74
74
|
}
|
|
75
75
|
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "transferMintAuthority",
|
|
79
|
+
"accounts": [
|
|
80
|
+
{
|
|
81
|
+
"name": "faucetConfig",
|
|
82
|
+
"isMut": false,
|
|
83
|
+
"isSigner": false
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "admin",
|
|
87
|
+
"isMut": true,
|
|
88
|
+
"isSigner": true
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "mintAccount",
|
|
92
|
+
"isMut": true,
|
|
93
|
+
"isSigner": false
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "mintAuthority",
|
|
97
|
+
"isMut": false,
|
|
98
|
+
"isSigner": false
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "tokenProgram",
|
|
102
|
+
"isMut": false,
|
|
103
|
+
"isSigner": false
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"args": []
|
|
76
107
|
}
|
|
77
108
|
],
|
|
78
109
|
"accounts": [
|
|
79
110
|
{
|
|
80
|
-
"name": "
|
|
111
|
+
"name": "FaucetConfig",
|
|
81
112
|
"type": {
|
|
82
113
|
"kind": "struct",
|
|
83
114
|
"fields": [
|
|
@@ -103,17 +134,9 @@
|
|
|
103
134
|
],
|
|
104
135
|
"errors": [
|
|
105
136
|
{
|
|
106
|
-
"code":
|
|
137
|
+
"code": 6000,
|
|
107
138
|
"name": "InvalidMintAccountAuthority",
|
|
108
139
|
"msg": "Program not mint authority"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"code": 301,
|
|
112
|
-
"name": "Unauthorized",
|
|
113
|
-
"msg": "Signer must be MockUSDCFaucet admin"
|
|
114
140
|
}
|
|
115
|
-
]
|
|
116
|
-
"metadata": {
|
|
117
|
-
"address": "2z2DLVD3tBWc86pbvvy5qN31v1NXprM6zA5MDr2FMx64"
|
|
118
|
-
}
|
|
141
|
+
]
|
|
119
142
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BN } from '@project-serum/anchor';
|
|
2
2
|
import { PublicKey } from '@solana/web3.js';
|
|
3
|
-
|
|
3
|
+
import pyth from '@pythnetwork/client';
|
|
4
|
+
export * from './tokenFaucet';
|
|
4
5
|
export * from './oracles/types';
|
|
5
6
|
export * from './oracles/pythClient';
|
|
6
7
|
export * from './oracles/switchboardClient';
|
|
@@ -33,6 +34,7 @@ export * from './math/amm';
|
|
|
33
34
|
export * from './math/trade';
|
|
34
35
|
export * from './math/orders';
|
|
35
36
|
export * from './math/repeg';
|
|
37
|
+
export * from './math/margin';
|
|
36
38
|
export * from './orders';
|
|
37
39
|
export * from './orderParams';
|
|
38
40
|
export * from './slot/SlotSubscriber';
|
|
@@ -47,4 +49,4 @@ export * from './util/tps';
|
|
|
47
49
|
export * from './math/bankBalance';
|
|
48
50
|
export * from './constants/banks';
|
|
49
51
|
export * from './clearingHouseConfig';
|
|
50
|
-
export { BN, PublicKey };
|
|
52
|
+
export { BN, PublicKey, pyth };
|
package/lib/index.js
CHANGED
|
@@ -13,13 +13,18 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
13
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
16
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PublicKey = exports.BN = void 0;
|
|
20
|
+
exports.pyth = exports.PublicKey = exports.BN = void 0;
|
|
18
21
|
const anchor_1 = require("@project-serum/anchor");
|
|
19
22
|
Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return anchor_1.BN; } });
|
|
20
23
|
const web3_js_1 = require("@solana/web3.js");
|
|
21
24
|
Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return web3_js_1.PublicKey; } });
|
|
22
|
-
|
|
25
|
+
const client_1 = __importDefault(require("@pythnetwork/client"));
|
|
26
|
+
exports.pyth = client_1.default;
|
|
27
|
+
__exportStar(require("./tokenFaucet"), exports);
|
|
23
28
|
__exportStar(require("./oracles/types"), exports);
|
|
24
29
|
__exportStar(require("./oracles/pythClient"), exports);
|
|
25
30
|
__exportStar(require("./oracles/switchboardClient"), exports);
|
|
@@ -52,6 +57,7 @@ __exportStar(require("./math/amm"), exports);
|
|
|
52
57
|
__exportStar(require("./math/trade"), exports);
|
|
53
58
|
__exportStar(require("./math/orders"), exports);
|
|
54
59
|
__exportStar(require("./math/repeg"), exports);
|
|
60
|
+
__exportStar(require("./math/margin"), exports);
|
|
55
61
|
__exportStar(require("./orders"), exports);
|
|
56
62
|
__exportStar(require("./orderParams"), exports);
|
|
57
63
|
__exportStar(require("./slot/SlotSubscriber"), exports);
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { BN } from '@project-serum/anchor';
|
|
3
3
|
import { AMM, PositionDirection, SwapDirection, MarketAccount } from '../types';
|
|
4
4
|
import { OraclePriceData } from '../oracles/types';
|
|
5
|
+
export declare function calculatePegFromTargetPrice(targetPrice: BN, baseAssetReserve: BN, quoteAssetReserve: BN): BN;
|
|
6
|
+
export declare function calculateOptimalPegAndBudget(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN, BN, boolean];
|
|
5
7
|
export declare function calculateNewAmm(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN, BN, BN];
|
|
6
8
|
export declare function calculateUpdatedAMM(amm: AMM, oraclePriceData: OraclePriceData): AMM;
|
|
7
9
|
export declare function calculateUpdatedAMMSpreadReserves(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData): {
|
|
@@ -10,7 +12,7 @@ export declare function calculateUpdatedAMMSpreadReserves(amm: AMM, direction: P
|
|
|
10
12
|
sqrtK: BN;
|
|
11
13
|
newPeg: BN;
|
|
12
14
|
};
|
|
13
|
-
export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN];
|
|
15
|
+
export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePriceData, withUpdate?: boolean): [BN, BN];
|
|
14
16
|
/**
|
|
15
17
|
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
16
18
|
*
|
|
@@ -31,6 +33,9 @@ export declare type AssetType = 'quote' | 'base';
|
|
|
31
33
|
* @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
|
|
32
34
|
*/
|
|
33
35
|
export declare function calculateAmmReservesAfterSwap(amm: Pick<AMM, 'pegMultiplier' | 'quoteAssetReserve' | 'sqrtK' | 'baseAssetReserve'>, inputAssetType: AssetType, swapAmount: BN, swapDirection: SwapDirection): [BN, BN];
|
|
36
|
+
export declare function calculateEffectiveLeverage(baseSpread: number, quoteAssetReserve: BN, terminalQuoteAssetReserve: BN, pegMultiplier: BN, netBaseAssetAmount: BN, markPrice: BN, totalFeeMinusDistributions: BN): number;
|
|
37
|
+
export declare function calculateMaxSpread(marginRatioInitial: number): number;
|
|
38
|
+
export declare function calculateSpreadBN(baseSpread: number, lastOracleMarkSpreadPct: BN, lastOracleConfPct: BN, maxSpread: number, quoteAssetReserve: BN, terminalQuoteAssetReserve: BN, pegMultiplier: BN, netBaseAssetAmount: BN, markPrice: BN, totalFeeMinusDistributions: BN): [number, number];
|
|
34
39
|
export declare function calculateSpread(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData): number;
|
|
35
40
|
export declare function calculateSpreadReserves(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData): {
|
|
36
41
|
baseAssetReserve: BN;
|
package/lib/math/amm.js
CHANGED
|
@@ -1,25 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = void 0;
|
|
3
|
+
exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
7
7
|
const assert_1 = require("../assert/assert");
|
|
8
8
|
const __1 = require("..");
|
|
9
9
|
const repeg_1 = require("./repeg");
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
function calculatePegFromTargetPrice(targetPrice, baseAssetReserve, quoteAssetReserve) {
|
|
11
|
+
return targetPrice
|
|
12
|
+
.mul(baseAssetReserve)
|
|
13
|
+
.div(quoteAssetReserve)
|
|
14
|
+
.add(numericConstants_1.PRICE_DIV_PEG.div(new anchor_1.BN(2)))
|
|
15
|
+
.div(numericConstants_1.PRICE_DIV_PEG);
|
|
16
|
+
}
|
|
17
|
+
exports.calculatePegFromTargetPrice = calculatePegFromTargetPrice;
|
|
18
|
+
function calculateOptimalPegAndBudget(amm, oraclePriceData) {
|
|
19
|
+
const markPriceBefore = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
|
|
13
20
|
const targetPrice = oraclePriceData.price;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.div(amm.quoteAssetReserve)
|
|
17
|
-
.add(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.PEG_PRECISION).div(new anchor_1.BN(2)))
|
|
18
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.PEG_PRECISION));
|
|
19
|
-
let prePegCost = (0, repeg_1.calculateRepegCost)(amm, newPeg);
|
|
21
|
+
const newPeg = calculatePegFromTargetPrice(targetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
|
|
22
|
+
const prePegCost = (0, repeg_1.calculateRepegCost)(amm, newPeg);
|
|
20
23
|
const totalFeeLB = amm.totalExchangeFee.div(new anchor_1.BN(2));
|
|
21
24
|
const budget = anchor_1.BN.max(numericConstants_1.ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
|
|
22
|
-
if (
|
|
25
|
+
if (budget.lt(prePegCost)) {
|
|
26
|
+
const maxPriceSpread = new anchor_1.BN(amm.maxSpread)
|
|
27
|
+
.mul(targetPrice)
|
|
28
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION);
|
|
29
|
+
let newTargetPrice;
|
|
30
|
+
let newOptimalPeg;
|
|
31
|
+
let newBudget;
|
|
32
|
+
const targetPriceGap = markPriceBefore.sub(targetPrice);
|
|
33
|
+
if (targetPriceGap.abs().gt(maxPriceSpread)) {
|
|
34
|
+
const markAdj = targetPriceGap.abs().sub(maxPriceSpread);
|
|
35
|
+
if (targetPriceGap.lt(new anchor_1.BN(0))) {
|
|
36
|
+
newTargetPrice = markPriceBefore.add(markAdj);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
newTargetPrice = markPriceBefore.sub(markAdj);
|
|
40
|
+
}
|
|
41
|
+
newOptimalPeg = calculatePegFromTargetPrice(newTargetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
|
|
42
|
+
newBudget = (0, repeg_1.calculateRepegCost)(amm, newOptimalPeg);
|
|
43
|
+
return [newTargetPrice, newOptimalPeg, newBudget, false];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return [targetPrice, newPeg, budget, true];
|
|
47
|
+
}
|
|
48
|
+
exports.calculateOptimalPegAndBudget = calculateOptimalPegAndBudget;
|
|
49
|
+
function calculateNewAmm(amm, oraclePriceData) {
|
|
50
|
+
let pKNumer = new anchor_1.BN(1);
|
|
51
|
+
let pKDenom = new anchor_1.BN(1);
|
|
52
|
+
const [targetPrice, _newPeg, budget, checkLowerBound] = calculateOptimalPegAndBudget(amm, oraclePriceData);
|
|
53
|
+
let prePegCost = (0, repeg_1.calculateRepegCost)(amm, _newPeg);
|
|
54
|
+
let newPeg = _newPeg;
|
|
55
|
+
if (prePegCost.gt(budget) && checkLowerBound) {
|
|
23
56
|
[pKNumer, pKDenom] = [new anchor_1.BN(999), new anchor_1.BN(1000)];
|
|
24
57
|
const deficitMadeup = (0, repeg_1.calculateAdjustKCost)(amm, pKNumer, pKDenom);
|
|
25
58
|
(0, assert_1.assert)(deficitMadeup.lte(new anchor_1.BN(0)));
|
|
@@ -73,8 +106,14 @@ function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
|
|
|
73
106
|
return result;
|
|
74
107
|
}
|
|
75
108
|
exports.calculateUpdatedAMMSpreadReserves = calculateUpdatedAMMSpreadReserves;
|
|
76
|
-
function calculateBidAskPrice(amm, oraclePriceData) {
|
|
77
|
-
|
|
109
|
+
function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true) {
|
|
110
|
+
let newAmm;
|
|
111
|
+
if (withUpdate) {
|
|
112
|
+
newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
newAmm = amm;
|
|
116
|
+
}
|
|
78
117
|
const askReserves = calculateSpreadReserves(newAmm, types_1.PositionDirection.LONG, oraclePriceData);
|
|
79
118
|
const bidReserves = calculateSpreadReserves(newAmm, types_1.PositionDirection.SHORT, oraclePriceData);
|
|
80
119
|
const askPrice = calculatePrice(askReserves.baseAssetReserve, askReserves.quoteAssetReserve, newAmm.pegMultiplier);
|
|
@@ -126,44 +165,88 @@ function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDire
|
|
|
126
165
|
return [newQuoteAssetReserve, newBaseAssetReserve];
|
|
127
166
|
}
|
|
128
167
|
exports.calculateAmmReservesAfterSwap = calculateAmmReservesAfterSwap;
|
|
168
|
+
function calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions) {
|
|
169
|
+
// inventory skew
|
|
170
|
+
const netBaseAssetValue = quoteAssetReserve
|
|
171
|
+
.sub(terminalQuoteAssetReserve)
|
|
172
|
+
.mul(pegMultiplier)
|
|
173
|
+
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
174
|
+
const localBaseAssetValue = netBaseAssetAmount
|
|
175
|
+
.mul(markPrice)
|
|
176
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
177
|
+
const effectiveLeverage = localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
|
|
178
|
+
(Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
|
|
179
|
+
1 / numericConstants_1.QUOTE_PRECISION.toNumber();
|
|
180
|
+
return effectiveLeverage;
|
|
181
|
+
}
|
|
182
|
+
exports.calculateEffectiveLeverage = calculateEffectiveLeverage;
|
|
183
|
+
function calculateMaxSpread(marginRatioInitial) {
|
|
184
|
+
const maxTargetSpread = new anchor_1.BN(marginRatioInitial)
|
|
185
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(numericConstants_1.MARGIN_PRECISION))
|
|
186
|
+
.toNumber();
|
|
187
|
+
return maxTargetSpread;
|
|
188
|
+
}
|
|
189
|
+
exports.calculateMaxSpread = calculateMaxSpread;
|
|
190
|
+
function calculateSpreadBN(baseSpread, lastOracleMarkSpreadPct, lastOracleConfPct, maxSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions) {
|
|
191
|
+
let longSpread = baseSpread / 2;
|
|
192
|
+
let shortSpread = baseSpread / 2;
|
|
193
|
+
if (lastOracleMarkSpreadPct.gt(numericConstants_1.ZERO)) {
|
|
194
|
+
shortSpread = Math.max(shortSpread, lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber());
|
|
195
|
+
}
|
|
196
|
+
else if (lastOracleMarkSpreadPct.lt(numericConstants_1.ZERO)) {
|
|
197
|
+
longSpread = Math.max(longSpread, lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber());
|
|
198
|
+
}
|
|
199
|
+
const maxTargetSpread = maxSpread;
|
|
200
|
+
const MAX_INVENTORY_SKEW = 5;
|
|
201
|
+
const effectiveLeverage = calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions);
|
|
202
|
+
if (totalFeeMinusDistributions.gt(numericConstants_1.ZERO)) {
|
|
203
|
+
const spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
|
|
204
|
+
if (netBaseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
205
|
+
longSpread *= spreadScale;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
shortSpread *= spreadScale;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
longSpread *= MAX_INVENTORY_SKEW;
|
|
213
|
+
shortSpread *= MAX_INVENTORY_SKEW;
|
|
214
|
+
}
|
|
215
|
+
const totalSpread = longSpread + shortSpread;
|
|
216
|
+
if (totalSpread > maxTargetSpread) {
|
|
217
|
+
if (longSpread > shortSpread) {
|
|
218
|
+
longSpread = Math.min(longSpread, maxTargetSpread);
|
|
219
|
+
shortSpread = maxTargetSpread - longSpread;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
shortSpread = Math.min(shortSpread, maxTargetSpread);
|
|
223
|
+
longSpread = maxTargetSpread - shortSpread;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return [longSpread, shortSpread];
|
|
227
|
+
}
|
|
228
|
+
exports.calculateSpreadBN = calculateSpreadBN;
|
|
129
229
|
function calculateSpread(amm, direction, oraclePriceData) {
|
|
130
|
-
let spread = amm.baseSpread / 2;
|
|
131
230
|
if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
|
|
132
|
-
return
|
|
231
|
+
return amm.baseSpread / 2;
|
|
133
232
|
}
|
|
134
233
|
const markPrice = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
|
|
135
234
|
const targetPrice = (oraclePriceData === null || oraclePriceData === void 0 ? void 0 : oraclePriceData.price) || markPrice;
|
|
235
|
+
const confInterval = oraclePriceData.confidence || numericConstants_1.ZERO;
|
|
136
236
|
const targetMarkSpreadPct = markPrice
|
|
137
237
|
.sub(targetPrice)
|
|
138
238
|
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
139
239
|
.div(markPrice);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
240
|
+
const confIntervalPct = confInterval
|
|
241
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
242
|
+
.div(markPrice);
|
|
243
|
+
const [longSpread, shortSpread] = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.netBaseAssetAmount, markPrice, amm.totalFeeMinusDistributions);
|
|
244
|
+
let spread;
|
|
245
|
+
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
246
|
+
spread = longSpread;
|
|
144
247
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if ((amm.netBaseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(direction, 'long')) ||
|
|
148
|
-
(amm.netBaseAssetAmount.lt(numericConstants_1.ZERO) && (0, types_1.isVariant)(direction, 'short')) ||
|
|
149
|
-
amm.totalFeeMinusDistributions.eq(numericConstants_1.ZERO)) {
|
|
150
|
-
const netCostBasis = amm.quoteAssetAmountLong.sub(amm.quoteAssetAmountShort);
|
|
151
|
-
const netBaseAssetValue = amm.quoteAssetReserve
|
|
152
|
-
.sub(amm.terminalQuoteAssetReserve)
|
|
153
|
-
.mul(amm.pegMultiplier)
|
|
154
|
-
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
155
|
-
const localBaseAssetValue = amm.netBaseAssetAmount
|
|
156
|
-
.mul(markPrice)
|
|
157
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
158
|
-
const netPnl = netBaseAssetValue.sub(netCostBasis);
|
|
159
|
-
const localPnl = localBaseAssetValue.sub(netCostBasis);
|
|
160
|
-
let effectiveLeverage = MAX_INVENTORY_SKEW;
|
|
161
|
-
if (amm.totalFeeMinusDistributions.gt(numericConstants_1.ZERO)) {
|
|
162
|
-
effectiveLeverage =
|
|
163
|
-
localPnl.sub(netPnl).toNumber() /
|
|
164
|
-
amm.totalFeeMinusDistributions.toNumber();
|
|
165
|
-
}
|
|
166
|
-
spread *= Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
|
|
248
|
+
else {
|
|
249
|
+
spread = shortSpread;
|
|
167
250
|
}
|
|
168
251
|
return spread;
|
|
169
252
|
}
|
package/lib/math/auction.js
CHANGED
|
@@ -4,7 +4,10 @@ exports.getAuctionPrice = exports.isAuctionComplete = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const _1 = require("../.");
|
|
6
6
|
function isAuctionComplete(order, slot) {
|
|
7
|
-
|
|
7
|
+
if (order.auctionDuration === 0) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return new _1.BN(slot).sub(order.slot).gt(new _1.BN(order.auctionDuration));
|
|
8
11
|
}
|
|
9
12
|
exports.isAuctionComplete = isAuctionComplete;
|
|
10
13
|
function getAuctionPrice(order, slot) {
|
|
@@ -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;
|