@d8x/perpetuals-sdk 2.0.13-alpha → 2.1.1-alpha2
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/dist/cjs/abi/IPerpetualManager.json +154 -4
- package/dist/cjs/abi/OracleFactory.json +94 -25
- package/dist/cjs/abi/PerpetualManagerProxy.json +212 -2
- package/dist/cjs/accountTrade.d.ts +3 -3
- package/dist/cjs/accountTrade.js +1 -1
- package/dist/cjs/accountTrade.js.map +1 -1
- package/dist/cjs/brokerTool.d.ts +5 -1
- package/dist/cjs/brokerTool.js +20 -7
- package/dist/cjs/brokerTool.js.map +1 -1
- package/dist/cjs/config/defaultConfig.json +0 -12
- package/dist/cjs/config/priceFeedConfig.json +1 -19
- package/dist/cjs/constants.d.ts +0 -1
- package/dist/cjs/constants.js +2 -3
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/contracts/IPerpetualManager.d.ts +93 -13
- package/dist/cjs/contracts/OracleFactory.d.ts +69 -20
- package/dist/cjs/contracts/PerpetualManagerProxy.d.ts +109 -4
- package/dist/cjs/contracts/factories/IPerpetualManager__factory.d.ts +118 -4
- package/dist/cjs/contracts/factories/IPerpetualManager__factory.js +154 -4
- package/dist/cjs/contracts/factories/IPerpetualManager__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/OracleFactory__factory.d.ts +75 -20
- package/dist/cjs/contracts/factories/OracleFactory__factory.js +94 -25
- package/dist/cjs/contracts/factories/OracleFactory__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.d.ts +159 -2
- package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.js +212 -2
- package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.js.map +1 -1
- package/dist/cjs/d8XMath.d.ts +59 -1
- package/dist/cjs/d8XMath.js +259 -3
- package/dist/cjs/d8XMath.js.map +1 -1
- package/dist/cjs/liquidatorTool.d.ts +1 -0
- package/dist/cjs/liquidatorTool.js +24 -7
- package/dist/cjs/liquidatorTool.js.map +1 -1
- package/dist/cjs/marketData.d.ts +45 -23
- package/dist/cjs/marketData.js +292 -197
- package/dist/cjs/marketData.js.map +1 -1
- package/dist/cjs/nodeSDKTypes.d.ts +24 -1
- package/dist/cjs/nodeSDKTypes.js.map +1 -1
- package/dist/cjs/orderExecutorTool.d.ts +3 -3
- package/dist/cjs/orderExecutorTool.js +38 -13
- package/dist/cjs/orderExecutorTool.js.map +1 -1
- package/dist/cjs/perpetualDataHandler.d.ts +28 -17
- package/dist/cjs/perpetualDataHandler.js +71 -45
- package/dist/cjs/perpetualDataHandler.js.map +1 -1
- package/dist/cjs/perpetualEventHandler.d.ts +1 -1
- package/dist/cjs/perpetualEventHandler.js +6 -7
- package/dist/cjs/perpetualEventHandler.js.map +1 -1
- package/dist/cjs/polyMktsPxFeed.d.ts +5 -3
- package/dist/cjs/polyMktsPxFeed.js +34 -2
- package/dist/cjs/polyMktsPxFeed.js.map +1 -1
- package/dist/cjs/priceFeeds.d.ts +6 -7
- package/dist/cjs/priceFeeds.js +36 -14
- package/dist/cjs/priceFeeds.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/writeAccessHandler.js +1 -1
- package/dist/cjs/writeAccessHandler.js.map +1 -1
- package/dist/esm/abi/IPerpetualManager.json +154 -4
- package/dist/esm/abi/OracleFactory.json +94 -25
- package/dist/esm/abi/PerpetualManagerProxy.json +212 -2
- package/dist/esm/accountTrade.d.ts +3 -3
- package/dist/esm/accountTrade.js +1 -1
- package/dist/esm/accountTrade.js.map +1 -1
- package/dist/esm/brokerTool.d.ts +5 -1
- package/dist/esm/brokerTool.js +21 -8
- package/dist/esm/brokerTool.js.map +1 -1
- package/dist/esm/config/defaultConfig.json +0 -12
- package/dist/esm/config/priceFeedConfig.json +1 -19
- package/dist/esm/constants.d.ts +0 -1
- package/dist/esm/constants.js +1 -2
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/contracts/IPerpetualManager.d.ts +93 -13
- package/dist/esm/contracts/OracleFactory.d.ts +69 -20
- package/dist/esm/contracts/PerpetualManagerProxy.d.ts +109 -4
- package/dist/esm/contracts/factories/IPerpetualManager__factory.d.ts +118 -4
- package/dist/esm/contracts/factories/IPerpetualManager__factory.js +154 -4
- package/dist/esm/contracts/factories/IPerpetualManager__factory.js.map +1 -1
- package/dist/esm/contracts/factories/OracleFactory__factory.d.ts +75 -20
- package/dist/esm/contracts/factories/OracleFactory__factory.js +94 -25
- package/dist/esm/contracts/factories/OracleFactory__factory.js.map +1 -1
- package/dist/{cjs/contracts/factories/MockToken__factory.d.ts → esm/contracts/factories/PerpStorage__factory.d.ts} +115 -128
- package/dist/esm/contracts/factories/{MockToken__factory.js → PerpStorage__factory.js} +128 -139
- package/dist/esm/contracts/factories/PerpStorage__factory.js.map +1 -0
- package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.d.ts +159 -2
- package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.js +212 -2
- package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.js.map +1 -1
- package/dist/esm/d8XMath.d.ts +59 -1
- package/dist/esm/d8XMath.js +251 -2
- package/dist/esm/d8XMath.js.map +1 -1
- package/dist/esm/liquidatorTool.d.ts +1 -0
- package/dist/esm/liquidatorTool.js +25 -8
- package/dist/esm/liquidatorTool.js.map +1 -1
- package/dist/esm/marketData.d.ts +45 -23
- package/dist/esm/marketData.js +295 -200
- package/dist/esm/marketData.js.map +1 -1
- package/dist/esm/nodeSDKTypes.d.ts +24 -1
- package/dist/esm/nodeSDKTypes.js.map +1 -1
- package/dist/esm/orderExecutorTool.d.ts +3 -3
- package/dist/esm/orderExecutorTool.js +38 -13
- package/dist/esm/orderExecutorTool.js.map +1 -1
- package/dist/esm/perpetualDataHandler.d.ts +28 -17
- package/dist/esm/perpetualDataHandler.js +74 -48
- package/dist/esm/perpetualDataHandler.js.map +1 -1
- package/dist/esm/perpetualEventHandler.d.ts +1 -1
- package/dist/esm/perpetualEventHandler.js +6 -7
- package/dist/esm/perpetualEventHandler.js.map +1 -1
- package/dist/esm/polyMktsPxFeed.d.ts +5 -3
- package/dist/esm/polyMktsPxFeed.js +34 -2
- package/dist/esm/polyMktsPxFeed.js.map +1 -1
- package/dist/esm/priceFeeds.d.ts +6 -7
- package/dist/esm/priceFeeds.js +36 -14
- package/dist/esm/priceFeeds.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/writeAccessHandler.js +3 -3
- package/dist/esm/writeAccessHandler.js.map +1 -1
- package/doc/brokerTool.md +3 -1
- package/doc/d8x-perpetuals-sdk.md +804 -132
- package/doc/marketData.md +813 -0
- package/doc/perpetualDataHandler.md +76 -7
- package/package.json +1 -1
- package/src/abi/IPerpetualManager.json +154 -4
- package/src/abi/OracleFactory.json +523 -454
- package/src/abi/PerpetualManagerProxy.json +1596 -1386
- package/src/accountTrade.ts +3 -3
- package/src/brokerTool.ts +22 -8
- package/src/config/defaultConfig.json +0 -13
- package/src/config/priceFeedConfig.json +1 -19
- package/src/constants.ts +1 -2
- package/src/contracts/IPerpetualManager.ts +140 -10
- package/src/contracts/OracleFactory.ts +100 -26
- package/src/contracts/PerpetualManagerProxy.ts +192 -3
- package/src/contracts/factories/IPerpetualManager__factory.ts +154 -4
- package/src/contracts/factories/OracleFactory__factory.ts +94 -25
- package/src/contracts/factories/PerpetualManagerProxy__factory.ts +212 -2
- package/src/d8XMath.ts +327 -2
- package/src/liquidatorTool.ts +29 -14
- package/src/marketData.ts +448 -250
- package/src/nodeSDKTypes.ts +30 -1
- package/src/orderExecutorTool.ts +48 -20
- package/src/perpetualDataHandler.ts +108 -55
- package/src/perpetualEventHandler.ts +6 -7
- package/src/polyMktsPxFeed.ts +40 -4
- package/src/priceFeeds.ts +41 -17
- package/src/version.ts +1 -1
- package/src/writeAccessHandler.ts +2 -2
- package/dist/cjs/abi/BeaconProxy.json +0 -71
- package/dist/cjs/abi/Maintainer.json +0 -774
- package/dist/cjs/abi/MockToken.json +0 -347
- package/dist/cjs/abi/UUPSUpgradeable.json +0 -104
- package/dist/cjs/abi/WeETH.json +0 -310
- package/dist/cjs/abi-zkevm/LimitOrderBook.json +0 -910
- package/dist/cjs/abi-zkevm/LimitOrderBookFactory.json +0 -236
- package/dist/cjs/contracts/BeaconProxy.d.ts +0 -63
- package/dist/cjs/contracts/BeaconProxy.js +0 -3
- package/dist/cjs/contracts/BeaconProxy.js.map +0 -1
- package/dist/cjs/contracts/Maintainer.d.ts +0 -799
- package/dist/cjs/contracts/Maintainer.js +0 -3
- package/dist/cjs/contracts/Maintainer.js.map +0 -1
- package/dist/cjs/contracts/MockToken.d.ts +0 -263
- package/dist/cjs/contracts/MockToken.js +0 -3
- package/dist/cjs/contracts/MockToken.js.map +0 -1
- package/dist/cjs/contracts/UUPSUpgradeable.d.ts +0 -118
- package/dist/cjs/contracts/UUPSUpgradeable.js +0 -3
- package/dist/cjs/contracts/UUPSUpgradeable.js.map +0 -1
- package/dist/cjs/contracts/WeETH.d.ts +0 -503
- package/dist/cjs/contracts/WeETH.js +0 -3
- package/dist/cjs/contracts/WeETH.js.map +0 -1
- package/dist/cjs/contracts/factories/BeaconProxy__factory.d.ts +0 -61
- package/dist/cjs/contracts/factories/BeaconProxy__factory.js +0 -89
- package/dist/cjs/contracts/factories/BeaconProxy__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/Maintainer__factory.d.ts +0 -609
- package/dist/cjs/contracts/factories/Maintainer__factory.js +0 -792
- package/dist/cjs/contracts/factories/Maintainer__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/MockToken__factory.js +0 -365
- package/dist/cjs/contracts/factories/MockToken__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
- package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js +0 -122
- package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/WeETH__factory.d.ts +0 -545
- package/dist/cjs/contracts/factories/WeETH__factory.js +0 -721
- package/dist/cjs/contracts/factories/WeETH__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
- package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5324
- package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
- package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -254
- package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
- package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js +0 -928
- package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
- package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js +0 -456
- package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
- package/dist/cjs/contracts/factories/lean0/index.d.ts +0 -4
- package/dist/cjs/contracts/factories/lean0/index.js +0 -15
- package/dist/cjs/contracts/factories/lean0/index.js.map +0 -1
- package/dist/cjs/contracts/lean0/IPerpetualManager.d.ts +0 -2821
- package/dist/cjs/contracts/lean0/IPerpetualManager.js +0 -3
- package/dist/cjs/contracts/lean0/IPerpetualManager.js.map +0 -1
- package/dist/cjs/contracts/lean0/LimitOrderBook.d.ts +0 -533
- package/dist/cjs/contracts/lean0/LimitOrderBook.js +0 -3
- package/dist/cjs/contracts/lean0/LimitOrderBook.js.map +0 -1
- package/dist/cjs/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
- package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js +0 -3
- package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
- package/dist/cjs/contracts/lean0/ShareToken.d.ts +0 -320
- package/dist/cjs/contracts/lean0/ShareToken.js +0 -3
- package/dist/cjs/contracts/lean0/ShareToken.js.map +0 -1
- package/dist/cjs/contracts/lean0/index.d.ts +0 -4
- package/dist/cjs/contracts/lean0/index.js +0 -3
- package/dist/cjs/contracts/lean0/index.js.map +0 -1
- package/dist/esm/abi/BeaconProxy.json +0 -71
- package/dist/esm/abi/Maintainer.json +0 -774
- package/dist/esm/abi/MockToken.json +0 -347
- package/dist/esm/abi/UUPSUpgradeable.json +0 -104
- package/dist/esm/abi/WeETH.json +0 -310
- package/dist/esm/abi/lean0/IPerpetualManager.json +0 -5306
- package/dist/esm/abi/lean0/LimitOrderBook.json +0 -910
- package/dist/esm/abi/lean0/LimitOrderBookFactory.json +0 -236
- package/dist/esm/abi/lean0/ShareToken.json +0 -438
- package/dist/esm/abi-zkevm/LimitOrderBook.json +0 -910
- package/dist/esm/abi-zkevm/LimitOrderBookFactory.json +0 -236
- package/dist/esm/contracts/BeaconProxy.d.ts +0 -63
- package/dist/esm/contracts/BeaconProxy.js +0 -2
- package/dist/esm/contracts/BeaconProxy.js.map +0 -1
- package/dist/esm/contracts/Maintainer.d.ts +0 -799
- package/dist/esm/contracts/Maintainer.js +0 -2
- package/dist/esm/contracts/Maintainer.js.map +0 -1
- package/dist/esm/contracts/MockToken.d.ts +0 -263
- package/dist/esm/contracts/MockToken.js +0 -2
- package/dist/esm/contracts/MockToken.js.map +0 -1
- package/dist/esm/contracts/UUPSUpgradeable.d.ts +0 -118
- package/dist/esm/contracts/UUPSUpgradeable.js +0 -2
- package/dist/esm/contracts/UUPSUpgradeable.js.map +0 -1
- package/dist/esm/contracts/WeETH.d.ts +0 -503
- package/dist/esm/contracts/WeETH.js +0 -2
- package/dist/esm/contracts/WeETH.js.map +0 -1
- package/dist/esm/contracts/factories/BeaconProxy__factory.d.ts +0 -61
- package/dist/esm/contracts/factories/BeaconProxy__factory.js +0 -85
- package/dist/esm/contracts/factories/BeaconProxy__factory.js.map +0 -1
- package/dist/esm/contracts/factories/Maintainer__factory.d.ts +0 -609
- package/dist/esm/contracts/factories/Maintainer__factory.js +0 -788
- package/dist/esm/contracts/factories/Maintainer__factory.js.map +0 -1
- package/dist/esm/contracts/factories/MockToken__factory.d.ts +0 -273
- package/dist/esm/contracts/factories/MockToken__factory.js.map +0 -1
- package/dist/esm/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
- package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js +0 -118
- package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
- package/dist/esm/contracts/factories/WeETH__factory.d.ts +0 -545
- package/dist/esm/contracts/factories/WeETH__factory.js +0 -717
- package/dist/esm/contracts/factories/WeETH__factory.js.map +0 -1
- package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
- package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5320
- package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
- package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
- package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -250
- package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
- package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
- package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js +0 -924
- package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
- package/dist/esm/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
- package/dist/esm/contracts/factories/lean0/ShareToken__factory.js +0 -452
- package/dist/esm/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
- package/dist/esm/contracts/factories/lean0/index.d.ts +0 -4
- package/dist/esm/contracts/factories/lean0/index.js +0 -8
- package/dist/esm/contracts/factories/lean0/index.js.map +0 -1
- package/dist/esm/contracts/lean0/IPerpetualManager.d.ts +0 -2821
- package/dist/esm/contracts/lean0/IPerpetualManager.js +0 -2
- package/dist/esm/contracts/lean0/IPerpetualManager.js.map +0 -1
- package/dist/esm/contracts/lean0/LimitOrderBook.d.ts +0 -533
- package/dist/esm/contracts/lean0/LimitOrderBook.js +0 -2
- package/dist/esm/contracts/lean0/LimitOrderBook.js.map +0 -1
- package/dist/esm/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
- package/dist/esm/contracts/lean0/LimitOrderBookFactory.js +0 -2
- package/dist/esm/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
- package/dist/esm/contracts/lean0/ShareToken.d.ts +0 -320
- package/dist/esm/contracts/lean0/ShareToken.js +0 -2
- package/dist/esm/contracts/lean0/ShareToken.js.map +0 -1
- package/dist/esm/contracts/lean0/index.d.ts +0 -4
- package/dist/esm/contracts/lean0/index.js +0 -2
- package/dist/esm/contracts/lean0/index.js.map +0 -1
- package/src/abi-zkevm/IPerpetualManager.json +0 -5366
package/src/marketData.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "./constants";
|
|
17
17
|
import {
|
|
18
18
|
ERC20__factory,
|
|
19
|
+
IPerpetualManager__factory,
|
|
19
20
|
LimitOrderBook__factory,
|
|
20
21
|
Multicall3__factory,
|
|
21
22
|
type LimitOrderBook,
|
|
@@ -34,6 +35,10 @@ import {
|
|
|
34
35
|
floatToABK64x64,
|
|
35
36
|
getDepositAmountForLvgTrade,
|
|
36
37
|
getMaxSignedPositionSize,
|
|
38
|
+
entropy,
|
|
39
|
+
expectedLoss,
|
|
40
|
+
pmExchangeFee,
|
|
41
|
+
pmFindMaxTradeSize,
|
|
37
42
|
} from "./d8XMath";
|
|
38
43
|
import {
|
|
39
44
|
type ExchangeInfo,
|
|
@@ -45,6 +50,7 @@ import {
|
|
|
45
50
|
type PoolState,
|
|
46
51
|
type PoolStaticInfo,
|
|
47
52
|
type SmartContractOrder,
|
|
53
|
+
type IdxPriceInfo,
|
|
48
54
|
} from "./nodeSDKTypes";
|
|
49
55
|
import PerpetualDataHandler from "./perpetualDataHandler";
|
|
50
56
|
import PriceFeeds from "./priceFeeds";
|
|
@@ -109,7 +115,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
109
115
|
const mktData = providerOrMarketData;
|
|
110
116
|
this.nodeURL = mktData.config.nodeURL;
|
|
111
117
|
this.provider = new JsonRpcProvider(mktData.config.nodeURL, mktData.network, { staticNetwork: true });
|
|
112
|
-
this.proxyContract =
|
|
118
|
+
this.proxyContract = IPerpetualManager__factory.connect(mktData.getProxyAddress(), this.provider);
|
|
113
119
|
this.multicall = Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, this.provider);
|
|
114
120
|
({
|
|
115
121
|
nestedPerpetualIDs: this.nestedPerpetualIDs,
|
|
@@ -174,9 +180,9 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
174
180
|
* }
|
|
175
181
|
* main();
|
|
176
182
|
*
|
|
177
|
-
* @returns
|
|
183
|
+
* @returns read-only proxy instance
|
|
178
184
|
*/
|
|
179
|
-
public getReadOnlyProxyInstance()
|
|
185
|
+
public getReadOnlyProxyInstance() {
|
|
180
186
|
if (this.proxyContract == null) {
|
|
181
187
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
182
188
|
}
|
|
@@ -405,12 +411,14 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
405
411
|
overrides?: Overrides
|
|
406
412
|
): Promise<MarginAccount> {
|
|
407
413
|
let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
414
|
+
const isPred = this.isPredictionMarket(symbol);
|
|
408
415
|
let mgnAcct = await PerpetualDataHandler.getMarginAccount(
|
|
409
416
|
traderAddr,
|
|
410
417
|
symbol,
|
|
411
418
|
this.symbolToPerpStaticInfo,
|
|
412
419
|
new Contract(this.proxyAddr, this.config.proxyABI!, provider),
|
|
413
|
-
|
|
420
|
+
obj,
|
|
421
|
+
isPred,
|
|
414
422
|
overrides
|
|
415
423
|
);
|
|
416
424
|
return mgnAcct;
|
|
@@ -430,142 +438,86 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
430
438
|
overrides?: Overrides
|
|
431
439
|
): Promise<MarginAccount[]> {
|
|
432
440
|
const MAX_SYMBOLS_PER_CALL = 10;
|
|
433
|
-
const
|
|
441
|
+
const pxInfo = new Array<IdxPriceInfo>();
|
|
434
442
|
for (let i = 0; i < symbols.length; i++) {
|
|
435
443
|
let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbols[i]);
|
|
436
|
-
|
|
444
|
+
pxInfo.push(obj);
|
|
437
445
|
}
|
|
438
446
|
let mgnAcct: MarginAccount[] = [];
|
|
439
447
|
let callSymbols = symbols.slice(0, MAX_SYMBOLS_PER_CALL);
|
|
440
|
-
let
|
|
448
|
+
let _px = pxInfo.slice(0, MAX_SYMBOLS_PER_CALL);
|
|
441
449
|
while (callSymbols.length > 0) {
|
|
450
|
+
const isPred = callSymbols.map((_sym) => this.isPredictionMarket(_sym));
|
|
442
451
|
let acc = await PerpetualDataHandler.getMarginAccounts(
|
|
443
452
|
Array(callSymbols.length).fill(traderAddr),
|
|
444
453
|
callSymbols,
|
|
445
454
|
this.symbolToPerpStaticInfo,
|
|
446
455
|
Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, provider),
|
|
447
456
|
new Contract(this.proxyAddr, this.config.proxyABI!, provider),
|
|
448
|
-
|
|
457
|
+
_px,
|
|
458
|
+
isPred,
|
|
449
459
|
overrides
|
|
450
460
|
);
|
|
451
461
|
mgnAcct = mgnAcct.concat(acc);
|
|
452
462
|
callSymbols = symbols.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
|
|
453
|
-
|
|
463
|
+
_px = pxInfo.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
|
|
454
464
|
}
|
|
455
465
|
return mgnAcct;
|
|
456
466
|
}
|
|
457
467
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
* @param traderAddr Address of trader
|
|
461
|
-
* @param order Order to be submitted
|
|
462
|
-
* @param account Position risk before trade. Defaults to current position if not given.
|
|
463
|
-
* @param indexPriceInfo Index prices and market status (open/closed). Defaults to current market status if not given.
|
|
464
|
-
* @returns Position risk after trade, including order cost and maximal trade sizes for position
|
|
465
|
-
* @example
|
|
466
|
-
* import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
|
|
467
|
-
* async function main() {
|
|
468
|
-
* console.log(MarketData);
|
|
469
|
-
* // setup
|
|
470
|
-
* const config = PerpetualDataHandler.readSDKConfig("cardona");
|
|
471
|
-
* const mktData = new MarketData(config);
|
|
472
|
-
* await mktData.createProxyInstance();
|
|
473
|
-
* const order: Order = {
|
|
474
|
-
* symbol: "MATIC-USD-MATIC",
|
|
475
|
-
* side: "BUY",
|
|
476
|
-
* type: "MARKET",
|
|
477
|
-
* quantity: 100,
|
|
478
|
-
* leverage: 2,
|
|
479
|
-
* executionTimestamp: Date.now()/1000,
|
|
480
|
-
* };
|
|
481
|
-
* // Get position risk conditional on this order being executed
|
|
482
|
-
* const posRisk = await mktData.positionRiskOnTrade("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", order);
|
|
483
|
-
* console.log(posRisk);
|
|
484
|
-
* }
|
|
485
|
-
* main();
|
|
486
|
-
*/
|
|
487
|
-
public async positionRiskOnTrade(
|
|
468
|
+
private async dataForPositionRiskOnTrade(
|
|
469
|
+
symbol: string,
|
|
488
470
|
traderAddr: string,
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
overrides?: Overrides
|
|
493
|
-
): Promise<{
|
|
471
|
+
tradeAmountBC: number,
|
|
472
|
+
indexPriceInfo: IdxPriceInfo,
|
|
473
|
+
signedPositionNotionalBaseCCY: number,
|
|
474
|
+
overrides?: Overrides
|
|
475
|
+
): Promise<{ account: MarginAccount; ammPrice: number; maxShortTrade: number; maxLongTrade: number }> {
|
|
494
476
|
if (this.proxyContract == null || this.multicall == null) {
|
|
495
477
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
496
478
|
}
|
|
497
|
-
|
|
498
|
-
// fetch prices
|
|
499
|
-
if (indexPriceInfo == undefined) {
|
|
500
|
-
let obj = await this.priceFeedGetter.fetchPricesForPerpetual(order.symbol);
|
|
501
|
-
indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// override total fee
|
|
505
|
-
let tradingFeeTbps: number | undefined;
|
|
506
|
-
if (overrides) {
|
|
507
|
-
({ tradingFeeTbps, ...overrides } = overrides);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// signed trade amount
|
|
511
|
-
let tradeAmountBC = Math.abs(order.quantity) * (order.side == BUY_SIDE ? 1 : -1);
|
|
512
|
-
|
|
513
|
-
const accountGiven = account !== undefined;
|
|
514
|
-
|
|
479
|
+
const isPredMkt = this.isPredictionMarket(symbol);
|
|
515
480
|
// create all calls
|
|
516
|
-
const
|
|
517
|
-
const
|
|
518
|
-
|
|
481
|
+
const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
|
|
482
|
+
const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
|
|
483
|
+
floatToABK64x64(x)
|
|
484
|
+
) as [bigint, bigint, bigint];
|
|
519
485
|
const proxyCalls: Multicall3.Call3Struct[] = [
|
|
520
486
|
// 0: traderState
|
|
521
487
|
{
|
|
522
488
|
target: this.proxyContract.target,
|
|
523
489
|
allowFailure: true,
|
|
524
|
-
callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr,
|
|
525
|
-
},
|
|
526
|
-
// 1: ammState
|
|
527
|
-
{
|
|
528
|
-
target: this.proxyContract.target,
|
|
529
|
-
allowFailure: true,
|
|
530
|
-
callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, fS2S3]),
|
|
531
|
-
},
|
|
532
|
-
// 2: exchangeFee
|
|
533
|
-
{
|
|
534
|
-
target: this.proxyContract.target,
|
|
535
|
-
allowFailure: false,
|
|
536
|
-
callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
|
|
537
|
-
poolId,
|
|
538
|
-
traderAddr,
|
|
539
|
-
order.brokerAddr ?? ZERO_ADDRESS,
|
|
540
|
-
]),
|
|
490
|
+
callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
|
|
541
491
|
},
|
|
542
|
-
//
|
|
492
|
+
// 1: perpetual price
|
|
543
493
|
{
|
|
544
494
|
target: this.proxyContract.target,
|
|
545
495
|
allowFailure: true,
|
|
546
496
|
callData: this.proxyContract.interface.encodeFunctionData("queryPerpetualPrice", [
|
|
547
497
|
perpId,
|
|
548
498
|
floatToABK64x64(tradeAmountBC),
|
|
549
|
-
|
|
499
|
+
[fS2, fS3],
|
|
500
|
+
indexPriceInfo.conf,
|
|
501
|
+
indexPriceInfo.predMktCLOBParams,
|
|
550
502
|
]),
|
|
551
503
|
},
|
|
552
|
-
//
|
|
504
|
+
// 2: max long pos
|
|
553
505
|
{
|
|
554
506
|
target: this.proxyContract.target,
|
|
555
507
|
allowFailure: false,
|
|
556
508
|
callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
|
|
557
509
|
perpId,
|
|
558
|
-
|
|
510
|
+
floatToABK64x64(signedPositionNotionalBaseCCY),
|
|
559
511
|
true,
|
|
560
512
|
]),
|
|
561
513
|
},
|
|
562
|
-
//
|
|
514
|
+
// 3: max short pos
|
|
563
515
|
{
|
|
564
516
|
target: this.proxyContract.target,
|
|
565
517
|
allowFailure: false,
|
|
566
518
|
callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
|
|
567
519
|
perpId,
|
|
568
|
-
|
|
520
|
+
floatToABK64x64(signedPositionNotionalBaseCCY),
|
|
569
521
|
false,
|
|
570
522
|
]),
|
|
571
523
|
},
|
|
@@ -575,58 +527,126 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
575
527
|
const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, (overrides || {}) as Overrides);
|
|
576
528
|
|
|
577
529
|
// positionRisk to apply this trade on: if not given, defaults to the current trader's position
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
)[0];
|
|
585
|
-
} else {
|
|
586
|
-
traderState = await this.proxyContract.getTraderState(perpId, traderAddr, fS2S3);
|
|
587
|
-
}
|
|
588
|
-
account = MarketData.buildMarginAccountFromState(order.symbol, traderState, this.symbolToPerpStaticInfo, [
|
|
589
|
-
indexPriceInfo[0],
|
|
590
|
-
indexPriceInfo[1],
|
|
591
|
-
]);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// perpetualState, for prices
|
|
595
|
-
let ammState: bigint[];
|
|
596
|
-
if (encodedResults[1].success) {
|
|
597
|
-
ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[1].returnData)[0];
|
|
530
|
+
let traderState: bigint[];
|
|
531
|
+
if (encodedResults[0].success) {
|
|
532
|
+
traderState = this.proxyContract.interface.decodeFunctionResult(
|
|
533
|
+
"getTraderState",
|
|
534
|
+
encodedResults[0].returnData
|
|
535
|
+
)[0];
|
|
598
536
|
} else {
|
|
599
|
-
|
|
537
|
+
traderState = await this.proxyContract.getTraderState(perpId, traderAddr, [fEma, fS3]);
|
|
600
538
|
}
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
indexPriceInfo
|
|
606
|
-
|
|
539
|
+
const account = MarketData.buildMarginAccountFromState(
|
|
540
|
+
symbol,
|
|
541
|
+
traderState,
|
|
542
|
+
this.symbolToPerpStaticInfo,
|
|
543
|
+
indexPriceInfo!,
|
|
544
|
+
isPredMkt
|
|
607
545
|
);
|
|
608
|
-
let [S2, S3, Sm] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice, perpetualState.markPrice];
|
|
609
|
-
|
|
610
|
-
// exchange fee based on this trader's address (volume, token holding, etc) and his broker address (if any)
|
|
611
|
-
const exchangeFeeTbps = this.proxyContract.interface.decodeFunctionResult(
|
|
612
|
-
"queryExchangeFee",
|
|
613
|
-
encodedResults[2].returnData
|
|
614
|
-
)[0] as bigint;
|
|
615
546
|
|
|
616
547
|
// amm price for this trade amount
|
|
617
548
|
let ammPrice: number;
|
|
618
549
|
{
|
|
619
550
|
let fPrice: bigint;
|
|
620
|
-
if (encodedResults[
|
|
551
|
+
if (encodedResults[1].success) {
|
|
621
552
|
fPrice = this.proxyContract.interface.decodeFunctionResult(
|
|
622
553
|
"queryPerpetualPrice",
|
|
623
|
-
encodedResults[
|
|
554
|
+
encodedResults[1].returnData
|
|
624
555
|
)[0];
|
|
625
556
|
} else {
|
|
626
|
-
fPrice = await this.proxyContract.queryPerpetualPrice(
|
|
557
|
+
fPrice = await this.proxyContract.queryPerpetualPrice(
|
|
558
|
+
perpId,
|
|
559
|
+
floatToABK64x64(tradeAmountBC),
|
|
560
|
+
[floatToABK64x64(indexPriceInfo.s2), floatToABK64x64(indexPriceInfo.s3 ?? 0)],
|
|
561
|
+
indexPriceInfo.conf,
|
|
562
|
+
indexPriceInfo.predMktCLOBParams
|
|
563
|
+
);
|
|
627
564
|
}
|
|
628
565
|
ammPrice = ABK64x64ToFloat(fPrice);
|
|
629
566
|
}
|
|
567
|
+
|
|
568
|
+
// max buy
|
|
569
|
+
const fMaxLong = this.proxyContract.interface.decodeFunctionResult(
|
|
570
|
+
"getMaxSignedOpenTradeSizeForPos",
|
|
571
|
+
encodedResults[2].returnData
|
|
572
|
+
)[0] as bigint;
|
|
573
|
+
const maxLongTrade = Math.max(0, ABK64x64ToFloat(fMaxLong) - signedPositionNotionalBaseCCY);
|
|
574
|
+
// max sell
|
|
575
|
+
const fMaxShort = this.proxyContract.interface.decodeFunctionResult(
|
|
576
|
+
"getMaxSignedOpenTradeSizeForPos",
|
|
577
|
+
encodedResults[3].returnData
|
|
578
|
+
)[0] as bigint;
|
|
579
|
+
const maxShortTrade = Math.max(0, Math.abs(ABK64x64ToFloat(fMaxShort)) - signedPositionNotionalBaseCCY);
|
|
580
|
+
return { account: account, ammPrice: ammPrice, maxShortTrade: maxShortTrade, maxLongTrade: maxLongTrade };
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Estimates what the position risk will be if a given order is executed.
|
|
585
|
+
* @param traderAddr Address of trader
|
|
586
|
+
* @param order Order to be submitted
|
|
587
|
+
* @param signedPositionNotionalBaseCCY signed position notional of current position (before trade)
|
|
588
|
+
* @param tradingFeeTbps trading fee in tenth of basis points (exchange fee and broker fee)
|
|
589
|
+
* @param indexPriceInfo Index prices and market status (open/closed). Defaults to current market status if not given.
|
|
590
|
+
* @returns Position risk after trade, including order cost and maximal trade sizes for position
|
|
591
|
+
* @example
|
|
592
|
+
* import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
|
|
593
|
+
* async function main() {
|
|
594
|
+
* console.log(MarketData);
|
|
595
|
+
* // setup
|
|
596
|
+
* const config = PerpetualDataHandler.readSDKConfig("cardona");
|
|
597
|
+
* const mktData = new MarketData(config);
|
|
598
|
+
* await mktData.createProxyInstance();
|
|
599
|
+
* const order: Order = {
|
|
600
|
+
* symbol: "MATIC-USD-MATIC",
|
|
601
|
+
* side: "BUY",
|
|
602
|
+
* type: "MARKET",
|
|
603
|
+
* quantity: 100,
|
|
604
|
+
* leverage: 2,
|
|
605
|
+
* executionTimestamp: Date.now()/1000,
|
|
606
|
+
* };
|
|
607
|
+
* // Get position risk conditional on this order being executed
|
|
608
|
+
* const posRisk = await mktData.positionRiskOnTrade("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", order, 0, 60);
|
|
609
|
+
* console.log(posRisk);
|
|
610
|
+
* }
|
|
611
|
+
* main();
|
|
612
|
+
*/
|
|
613
|
+
public async positionRiskOnTrade(
|
|
614
|
+
traderAddr: string,
|
|
615
|
+
order: Order,
|
|
616
|
+
signedPositionNotionalBaseCCY: number,
|
|
617
|
+
tradingFeeTbps: number,
|
|
618
|
+
indexPriceInfo?: IdxPriceInfo,
|
|
619
|
+
overrides?: Overrides
|
|
620
|
+
): Promise<{ newPositionRisk: MarginAccount; orderCost: number; maxLongTrade: number; maxShortTrade: number }> {
|
|
621
|
+
if (this.proxyContract == null || this.multicall == null) {
|
|
622
|
+
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
623
|
+
}
|
|
624
|
+
const isPredMkt = this.isPredictionMarket(order.symbol);
|
|
625
|
+
// fetch prices
|
|
626
|
+
if (indexPriceInfo == undefined) {
|
|
627
|
+
indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(order.symbol);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// signed trade amount
|
|
631
|
+
let tradeAmountBC = Math.abs(order.quantity) * (order.side == BUY_SIDE ? 1 : -1);
|
|
632
|
+
const symbol = order.symbol;
|
|
633
|
+
|
|
634
|
+
let obj = await this.dataForPositionRiskOnTrade(
|
|
635
|
+
symbol,
|
|
636
|
+
traderAddr,
|
|
637
|
+
tradeAmountBC,
|
|
638
|
+
indexPriceInfo,
|
|
639
|
+
signedPositionNotionalBaseCCY,
|
|
640
|
+
overrides
|
|
641
|
+
);
|
|
642
|
+
const account = obj.account;
|
|
643
|
+
const maxLongTrade = obj.maxLongTrade;
|
|
644
|
+
const maxShortTrade = obj.maxShortTrade;
|
|
645
|
+
const ammPrice = obj.ammPrice;
|
|
646
|
+
let Sm = account.markPrice;
|
|
647
|
+
let S2 = indexPriceInfo.s2;
|
|
648
|
+
let S3 = account.collToQuoteConversion;
|
|
649
|
+
|
|
630
650
|
// price for this order = amm price if no limit given, else conservatively adjusted
|
|
631
651
|
let tradePrice: number;
|
|
632
652
|
if (order.limitPrice == undefined) {
|
|
@@ -660,27 +680,6 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
660
680
|
}
|
|
661
681
|
}
|
|
662
682
|
}
|
|
663
|
-
// max buy
|
|
664
|
-
const fMaxLong = this.proxyContract.interface.decodeFunctionResult(
|
|
665
|
-
"getMaxSignedOpenTradeSizeForPos",
|
|
666
|
-
encodedResults[4].returnData
|
|
667
|
-
)[0] as bigint;
|
|
668
|
-
const maxLongTrade =
|
|
669
|
-
account.side == BUY_SIDE
|
|
670
|
-
? Math.max(0, ABK64x64ToFloat(fMaxLong) - (accountGiven ? 0 : account.positionNotionalBaseCCY))
|
|
671
|
-
: ABK64x64ToFloat(fMaxLong) + account.positionNotionalBaseCCY;
|
|
672
|
-
// max sell
|
|
673
|
-
const fMaxShort = this.proxyContract.interface.decodeFunctionResult(
|
|
674
|
-
"getMaxSignedOpenTradeSizeForPos",
|
|
675
|
-
encodedResults[5].returnData
|
|
676
|
-
)[0] as bigint;
|
|
677
|
-
const maxShortTrade =
|
|
678
|
-
account.side == SELL_SIDE
|
|
679
|
-
? Math.max(
|
|
680
|
-
0,
|
|
681
|
-
Math.abs(ABK64x64ToFloat(fMaxShort)) - (accountGiven ? 0 : Math.abs(account.positionNotionalBaseCCY))
|
|
682
|
-
)
|
|
683
|
-
: Math.abs(ABK64x64ToFloat(fMaxShort)) + Math.abs(account.positionNotionalBaseCCY);
|
|
684
683
|
|
|
685
684
|
// Current state:
|
|
686
685
|
let lotSizeBC = MarketData._getLotSize(order.symbol, this.symbolToPerpStaticInfo);
|
|
@@ -705,10 +704,6 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
705
704
|
}
|
|
706
705
|
let newSide = newPositionBC > 0 ? BUY_SIDE : newPositionBC < 0 ? SELL_SIDE : CLOSED_SIDE;
|
|
707
706
|
|
|
708
|
-
if (tradingFeeTbps === undefined) {
|
|
709
|
-
// use usual input if not overriden
|
|
710
|
-
tradingFeeTbps = Number(exchangeFeeTbps) + (order.brokerFeeTbps ?? 0);
|
|
711
|
-
}
|
|
712
707
|
let tradingFeeCC = (Math.abs(tradeAmountBC) * tradingFeeTbps * 1e-5 * S2) / S3;
|
|
713
708
|
let referralFeeCC = this.symbolToPerpStaticInfo.get(account.symbol)!.referralRebate;
|
|
714
709
|
// Trade type:
|
|
@@ -733,7 +728,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
733
728
|
let initialMarginRate = this.symbolToPerpStaticInfo.get(account.symbol)!.initialMarginRate;
|
|
734
729
|
targetLvg = isFlip || isOpen ? order.leverage ?? 1 / initialMarginRate : 0;
|
|
735
730
|
let [b0, pos0] = isOpen ? [0, 0] : [account.collateralCC, currentPositionBC];
|
|
736
|
-
traderDepositCC = getDepositAmountForLvgTrade(pos0, b0, tradeAmountBC, targetLvg, tradePrice, S3, Sm);
|
|
731
|
+
traderDepositCC = getDepositAmountForLvgTrade(pos0, b0, tradeAmountBC, targetLvg, tradePrice, S3, Sm, isPredMkt);
|
|
737
732
|
// fees are paid from wallet in this case
|
|
738
733
|
traderDepositCC += tradingFeeCC + referralFeeCC;
|
|
739
734
|
}
|
|
@@ -754,12 +749,20 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
754
749
|
let newMarginCashCC = currentMarginCashCC + deltaCashCC + traderDepositCC;
|
|
755
750
|
let newEntryPrice = newPositionBC == 0 ? 0 : Math.abs(newLockedInValueQC / newPositionBC);
|
|
756
751
|
let newMarginBalanceCC = newMarginCashCC + (newPositionBC * Sm - newLockedInValueQC) / S3;
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
752
|
+
|
|
753
|
+
let newLeverage: number;
|
|
754
|
+
if (newPositionBC === 0) {
|
|
755
|
+
newLeverage = 0;
|
|
756
|
+
} else if (newMarginBalanceCC <= 0) {
|
|
757
|
+
newLeverage = Infinity;
|
|
758
|
+
} else {
|
|
759
|
+
let p = Sm;
|
|
760
|
+
if (isPredMkt) {
|
|
761
|
+
p -= 1;
|
|
762
|
+
p = newPositionBC > 0 ? p : 1 - p;
|
|
763
|
+
}
|
|
764
|
+
newLeverage = Math.abs(newPositionBC * p) / S3 / newMarginBalanceCC;
|
|
765
|
+
}
|
|
763
766
|
|
|
764
767
|
// Liquidation params
|
|
765
768
|
let [S2Liq, S3Liq, tau] = MarketData._getLiquidationParams(
|
|
@@ -769,6 +772,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
769
772
|
newMarginCashCC,
|
|
770
773
|
Sm,
|
|
771
774
|
S3,
|
|
775
|
+
S2,
|
|
772
776
|
this.symbolToPerpStaticInfo
|
|
773
777
|
);
|
|
774
778
|
|
|
@@ -795,6 +799,25 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
795
799
|
};
|
|
796
800
|
}
|
|
797
801
|
|
|
802
|
+
/**
|
|
803
|
+
* Fee is relative to base-currency amount (=trade amount)
|
|
804
|
+
* @param state current perpetual state (need longBC and shortBC)
|
|
805
|
+
* @param maxMaintMgnRate maintenance margin rate param for pred mkts
|
|
806
|
+
* @param Sm Mark price
|
|
807
|
+
* @param tradeAmtBC signed trade amount
|
|
808
|
+
* @param tradeMgnRate margin rate param from perpetual
|
|
809
|
+
* @returns relative exchange fee in decimals
|
|
810
|
+
*/
|
|
811
|
+
public static exchangeFeePrdMkts(
|
|
812
|
+
state: PerpetualState,
|
|
813
|
+
maxMaintMgnRate: number,
|
|
814
|
+
Sm: number,
|
|
815
|
+
tradeAmtBC: number,
|
|
816
|
+
tradeMgnRate: number
|
|
817
|
+
): number {
|
|
818
|
+
return pmExchangeFee(Sm - 1, maxMaintMgnRate, state.shortBC, state.longBC, tradeAmtBC, tradeMgnRate);
|
|
819
|
+
}
|
|
820
|
+
|
|
798
821
|
/**
|
|
799
822
|
* Estimates what the position risk will be if given amount of collateral is added/removed from the account.
|
|
800
823
|
* @param {number} deltaCollateral Amount of collateral to add or remove (signed)
|
|
@@ -819,7 +842,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
819
842
|
public async positionRiskOnCollateralAction(
|
|
820
843
|
deltaCollateral: number,
|
|
821
844
|
account: MarginAccount,
|
|
822
|
-
indexPriceInfo?:
|
|
845
|
+
indexPriceInfo?: IdxPriceInfo,
|
|
823
846
|
overrides?: Overrides
|
|
824
847
|
): Promise<MarginAccount> {
|
|
825
848
|
if (this.proxyContract == null) {
|
|
@@ -829,11 +852,17 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
829
852
|
throw new Error("not enough margin to remove");
|
|
830
853
|
}
|
|
831
854
|
if (indexPriceInfo == undefined) {
|
|
832
|
-
|
|
833
|
-
indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
|
|
855
|
+
indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
|
|
834
856
|
}
|
|
835
857
|
let perpetualState = await this.getPerpetualState(account.symbol, indexPriceInfo, overrides);
|
|
836
|
-
let
|
|
858
|
+
let Sm; //mark price
|
|
859
|
+
if (this.isPredictionMarket(account.symbol)) {
|
|
860
|
+
Sm = indexPriceInfo.ema + perpetualState.markPremium;
|
|
861
|
+
} else {
|
|
862
|
+
Sm = perpetualState.indexPrice * (1 + perpetualState.markPremium);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
let [S2, S3] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice];
|
|
837
866
|
|
|
838
867
|
// no position: just increase collateral and kill liquidation vars
|
|
839
868
|
if (account.positionNotionalBaseCCY == 0) {
|
|
@@ -884,6 +913,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
884
913
|
newMarginCashCC,
|
|
885
914
|
Sm,
|
|
886
915
|
S3,
|
|
916
|
+
S2,
|
|
887
917
|
this.symbolToPerpStaticInfo
|
|
888
918
|
);
|
|
889
919
|
|
|
@@ -906,13 +936,15 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
906
936
|
}
|
|
907
937
|
|
|
908
938
|
/**
|
|
909
|
-
* Calculates liquidation prices for a
|
|
939
|
+
* Calculates liquidation prices for a position
|
|
940
|
+
* constructed in positionRiskOnTrade/positionRiskOnCollateralAction
|
|
910
941
|
* @param symbol Perpetual symbol
|
|
911
942
|
* @param lockedInQC Locked in value
|
|
912
943
|
* @param signedPositionBC Signed position size
|
|
913
|
-
* @param marginCashCC
|
|
944
|
+
* @param marginCashCC Available cash in margin account (includes unpaid funding)
|
|
914
945
|
* @param markPrice Mark price
|
|
915
|
-
* @param collToQuoteConversion Collateral index price
|
|
946
|
+
* @param collToQuoteConversion Collateral index price (S3)
|
|
947
|
+
* @param S2 index price
|
|
916
948
|
* @param symbolToPerpStaticInfo Symbol-to-perp static info mapping
|
|
917
949
|
* @returns [Base index price, Collateral index price, Maintenance margin rate]
|
|
918
950
|
* @ignore
|
|
@@ -924,30 +956,35 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
924
956
|
marginCashCC: number,
|
|
925
957
|
markPrice: number,
|
|
926
958
|
collToQuoteConversion: number,
|
|
959
|
+
S2: number,
|
|
927
960
|
symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>
|
|
928
961
|
): [number, number | undefined, number] {
|
|
929
962
|
let S2Liq: number, S3Liq: number | undefined;
|
|
930
|
-
|
|
931
|
-
let
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
963
|
+
const staticInfo = symbolToPerpStaticInfo.get(symbol)!;
|
|
964
|
+
let tau = staticInfo.maintenanceMarginRate;
|
|
965
|
+
let ccyType = staticInfo.collateralCurrencyType;
|
|
966
|
+
const isPred = MarketData.isPredictionMarketStatic(staticInfo);
|
|
967
|
+
const idx_availableCashCC = 2;
|
|
968
|
+
const idx_cash = 3;
|
|
969
|
+
const idx_notional = 4;
|
|
970
|
+
const idx_locked_in = 5;
|
|
971
|
+
const idx_mark_price = 8;
|
|
972
|
+
const idx_s3 = 9;
|
|
973
|
+
let traderState = new Array<bigint>(10);
|
|
974
|
+
traderState[idx_availableCashCC] = floatToABK64x64(marginCashCC);
|
|
975
|
+
traderState[idx_cash] = traderState[idx_availableCashCC];
|
|
976
|
+
traderState[idx_notional] = floatToABK64x64(signedPositionBC);
|
|
977
|
+
traderState[idx_locked_in] = floatToABK64x64(lockedInQC);
|
|
978
|
+
traderState[idx_mark_price] = floatToABK64x64(markPrice);
|
|
979
|
+
traderState[idx_s3] = floatToABK64x64(collToQuoteConversion);
|
|
980
|
+
|
|
981
|
+
[S2Liq, S3Liq, tau, ,] = MarketData._calculateLiquidationPrice(
|
|
982
|
+
symbol,
|
|
983
|
+
traderState,
|
|
984
|
+
S2,
|
|
985
|
+
symbolToPerpStaticInfo,
|
|
986
|
+
isPred
|
|
987
|
+
);
|
|
951
988
|
return [S2Liq, S3Liq, tau];
|
|
952
989
|
}
|
|
953
990
|
|
|
@@ -1137,23 +1174,35 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1137
1174
|
if (!this.proxyContract || !this.multicall) {
|
|
1138
1175
|
throw new Error("proxy contract not initialized");
|
|
1139
1176
|
}
|
|
1177
|
+
if (this.isPredictionMarket(symbol)) {
|
|
1178
|
+
// prediction markets
|
|
1179
|
+
return this.pmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
|
|
1180
|
+
}
|
|
1181
|
+
// regular markets
|
|
1182
|
+
return this.rmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
private async pmMaxOrderSizeForTrader(
|
|
1186
|
+
traderAddr: string,
|
|
1187
|
+
symbol: string,
|
|
1188
|
+
overrides?: Overrides
|
|
1189
|
+
): Promise<{ buy: number; sell: number }> {
|
|
1190
|
+
if (!this.proxyContract || !this.multicall) {
|
|
1191
|
+
throw new Error("proxy contract not initialized");
|
|
1192
|
+
}
|
|
1193
|
+
const IERC20 = new Interface(ERC20_ABI) as ERC20Interface;
|
|
1140
1194
|
const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
|
|
1141
|
-
const poolId = this.getPoolIdFromSymbol(symbol);
|
|
1142
1195
|
const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
|
|
1143
|
-
const
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
.fetchPricesForPerpetual(symbol)
|
|
1148
|
-
.then((obj) => [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]]);
|
|
1149
|
-
const fS2S3 = [indexPriceInfo[0], indexPriceInfo[1]].map((x) => floatToABK64x64(x)) as [bigint, bigint];
|
|
1150
|
-
let coll2SettlePromise = this.fetchCollateralToSettlementConversion(symbol);
|
|
1196
|
+
const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1197
|
+
const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
|
|
1198
|
+
floatToABK64x64(x)
|
|
1199
|
+
) as [bigint, bigint, bigint];
|
|
1151
1200
|
const proxyCalls: Multicall3.Call3Struct[] = [
|
|
1152
1201
|
// 0: traderState
|
|
1153
1202
|
{
|
|
1154
1203
|
target: this.proxyContract.target,
|
|
1155
1204
|
allowFailure: false,
|
|
1156
|
-
callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr,
|
|
1205
|
+
callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
|
|
1157
1206
|
},
|
|
1158
1207
|
|
|
1159
1208
|
// 1: wallet balance
|
|
@@ -1162,46 +1211,100 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1162
1211
|
allowFailure: false,
|
|
1163
1212
|
callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
|
|
1164
1213
|
},
|
|
1165
|
-
// 2:
|
|
1214
|
+
// 2: amm state
|
|
1166
1215
|
{
|
|
1167
1216
|
target: this.proxyContract.target,
|
|
1168
1217
|
allowFailure: false,
|
|
1169
|
-
callData: this.proxyContract.interface.encodeFunctionData("
|
|
1170
|
-
poolId,
|
|
1171
|
-
traderAddr,
|
|
1172
|
-
ZERO_ADDRESS,
|
|
1173
|
-
]),
|
|
1218
|
+
callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, [fS2, fS3]]),
|
|
1174
1219
|
},
|
|
1175
1220
|
];
|
|
1176
1221
|
|
|
1177
1222
|
// multicall
|
|
1178
1223
|
const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, overrides || {});
|
|
1179
|
-
|
|
1180
|
-
// position risk
|
|
1181
|
-
const idxNotional = 4;
|
|
1182
1224
|
const traderState = this.proxyContract.interface.decodeFunctionResult(
|
|
1183
1225
|
"getTraderState",
|
|
1184
1226
|
encodedResults[0].returnData
|
|
1185
1227
|
)[0];
|
|
1186
|
-
const account = MarketData.buildMarginAccountFromState(symbol, traderState, this.symbolToPerpStaticInfo, [
|
|
1187
|
-
indexPriceInfo[0],
|
|
1188
|
-
indexPriceInfo[1],
|
|
1189
|
-
]);
|
|
1190
|
-
|
|
1191
|
-
// fee rate
|
|
1192
|
-
const feeRateTbps = this.proxyContract.interface.decodeFunctionResult(
|
|
1193
|
-
"queryExchangeFee",
|
|
1194
|
-
encodedResults[2].returnData
|
|
1195
|
-
)[0] as bigint;
|
|
1196
|
-
|
|
1197
|
-
const feeRate = 1e-5 * Number(feeRateTbps);
|
|
1198
|
-
|
|
1199
|
-
// Max based on margin requirements:
|
|
1200
1228
|
const walletBalance = decNToFloat(
|
|
1201
1229
|
IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0],
|
|
1202
1230
|
poolInfo.poolSettleTokenDecimals
|
|
1203
1231
|
);
|
|
1232
|
+
const ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[2].returnData)[0];
|
|
1204
1233
|
|
|
1234
|
+
const account = MarketData.buildMarginAccountFromState(
|
|
1235
|
+
symbol,
|
|
1236
|
+
traderState,
|
|
1237
|
+
this.symbolToPerpStaticInfo,
|
|
1238
|
+
indexPriceInfo,
|
|
1239
|
+
true //isPredMkt
|
|
1240
|
+
);
|
|
1241
|
+
const openInterestBC = ABK64x64ToFloat(ammState[11]);
|
|
1242
|
+
const net = -ABK64x64ToFloat(ammState[1]);
|
|
1243
|
+
let totLong, totShort;
|
|
1244
|
+
if (net < 0) {
|
|
1245
|
+
totLong = openInterestBC;
|
|
1246
|
+
totShort = openInterestBC - Math.abs(net);
|
|
1247
|
+
} else {
|
|
1248
|
+
totLong = openInterestBC - net;
|
|
1249
|
+
totShort = openInterestBC;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
let currentPositionBC = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
|
|
1253
|
+
const Sm = ABK64x64ToFloat(traderState[8]);
|
|
1254
|
+
// settlement token must be equal to collateral token for walletBalance to be correct
|
|
1255
|
+
const availCashCC = account.collateralCC + walletBalance + account.unrealizedFundingCollateralCCY;
|
|
1256
|
+
const idxNotional = 4;
|
|
1257
|
+
const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(
|
|
1258
|
+
perpId,
|
|
1259
|
+
traderState[idxNotional],
|
|
1260
|
+
overrides
|
|
1261
|
+
);
|
|
1262
|
+
|
|
1263
|
+
const maxShort = pmFindMaxTradeSize(
|
|
1264
|
+
-1,
|
|
1265
|
+
currentPositionBC,
|
|
1266
|
+
availCashCC,
|
|
1267
|
+
account.entryPrice * currentPositionBC,
|
|
1268
|
+
Sm,
|
|
1269
|
+
Sm,
|
|
1270
|
+
indexPriceInfo.s3 ?? 0,
|
|
1271
|
+
totLong,
|
|
1272
|
+
totShort,
|
|
1273
|
+
maxShortPosPerp,
|
|
1274
|
+
maxLongPosPerp
|
|
1275
|
+
);
|
|
1276
|
+
const maxLong = pmFindMaxTradeSize(
|
|
1277
|
+
1,
|
|
1278
|
+
currentPositionBC,
|
|
1279
|
+
availCashCC,
|
|
1280
|
+
account.entryPrice * currentPositionBC,
|
|
1281
|
+
Sm,
|
|
1282
|
+
Sm,
|
|
1283
|
+
indexPriceInfo.s3 ?? 0,
|
|
1284
|
+
totLong,
|
|
1285
|
+
totShort,
|
|
1286
|
+
maxShortPosPerp,
|
|
1287
|
+
maxLongPosPerp
|
|
1288
|
+
);
|
|
1289
|
+
return { buy: maxLong, sell: maxShort };
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
/**
|
|
1293
|
+
* Returns the maximal allowed short pos and long pos (signed) for a trader
|
|
1294
|
+
* with given notional (in ABDK format) in the perpetual, ignoring the traders wallet balance
|
|
1295
|
+
* @param perpId
|
|
1296
|
+
* @param currentTraderPos ABDK64x64 notional position of trader
|
|
1297
|
+
* @param overrides
|
|
1298
|
+
* @returns [maxShortPos, maxLongPos] signed maximal position sizes
|
|
1299
|
+
*/
|
|
1300
|
+
public async getMaxShortLongPos(
|
|
1301
|
+
perpId: number,
|
|
1302
|
+
currentTraderPos: bigint,
|
|
1303
|
+
overrides?: Overrides
|
|
1304
|
+
): Promise<[number, number]> {
|
|
1305
|
+
if (!this.proxyContract || !this.multicall) {
|
|
1306
|
+
throw new Error("proxy contract not initialized");
|
|
1307
|
+
}
|
|
1205
1308
|
const proxyCalls2: Multicall3.Call3Struct[] = [
|
|
1206
1309
|
// 0: max long
|
|
1207
1310
|
{
|
|
@@ -1209,7 +1312,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1209
1312
|
allowFailure: false,
|
|
1210
1313
|
callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
|
|
1211
1314
|
perpId,
|
|
1212
|
-
|
|
1315
|
+
currentTraderPos,
|
|
1213
1316
|
true,
|
|
1214
1317
|
]),
|
|
1215
1318
|
},
|
|
@@ -1219,7 +1322,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1219
1322
|
allowFailure: false,
|
|
1220
1323
|
callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
|
|
1221
1324
|
perpId,
|
|
1222
|
-
|
|
1325
|
+
currentTraderPos,
|
|
1223
1326
|
false,
|
|
1224
1327
|
]),
|
|
1225
1328
|
},
|
|
@@ -1236,7 +1339,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1236
1339
|
encodedResults2[0].returnData
|
|
1237
1340
|
)[0] as bigint
|
|
1238
1341
|
);
|
|
1239
|
-
const maxLongPosPerp = maxLongOrderPerp + ABK64x64ToFloat(
|
|
1342
|
+
const maxLongPosPerp = maxLongOrderPerp + ABK64x64ToFloat(currentTraderPos);
|
|
1240
1343
|
// max short
|
|
1241
1344
|
const maxShortOrderPerp = ABK64x64ToFloat(
|
|
1242
1345
|
this.proxyContract.interface.decodeFunctionResult(
|
|
@@ -1244,8 +1347,91 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1244
1347
|
encodedResults2[1].returnData
|
|
1245
1348
|
)[0] as bigint
|
|
1246
1349
|
);
|
|
1247
|
-
const maxShortPosPerp = maxShortOrderPerp + ABK64x64ToFloat(
|
|
1350
|
+
const maxShortPosPerp = maxShortOrderPerp + ABK64x64ToFloat(currentTraderPos);
|
|
1351
|
+
return [maxShortPosPerp, maxLongPosPerp];
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
private async rmMaxOrderSizeForTrader(
|
|
1355
|
+
traderAddr: string,
|
|
1356
|
+
symbol: string,
|
|
1357
|
+
overrides?: Overrides
|
|
1358
|
+
): Promise<{ buy: number; sell: number }> {
|
|
1359
|
+
const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
|
|
1360
|
+
const poolId = this.getPoolIdFromSymbol(symbol);
|
|
1361
|
+
const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
|
|
1362
|
+
const perpInfo = this.getPerpetualStaticInfo(symbol);
|
|
1363
|
+
const IERC20 = new Interface(ERC20_ABI) as ERC20Interface;
|
|
1364
|
+
const isPredMkt = false;
|
|
1365
|
+
const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1366
|
+
let coll2SettlePromise = this.fetchCollateralToSettlementConversion(symbol);
|
|
1367
|
+
const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
|
|
1368
|
+
floatToABK64x64(x)
|
|
1369
|
+
) as [bigint, bigint, bigint];
|
|
1370
|
+
if (!this.proxyContract || !this.multicall) {
|
|
1371
|
+
throw new Error("proxy contract not initialized");
|
|
1372
|
+
}
|
|
1373
|
+
const proxyCalls: Multicall3.Call3Struct[] = [
|
|
1374
|
+
// 0: traderState
|
|
1375
|
+
{
|
|
1376
|
+
target: this.proxyContract.target,
|
|
1377
|
+
allowFailure: false,
|
|
1378
|
+
callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
|
|
1379
|
+
},
|
|
1248
1380
|
|
|
1381
|
+
// 1: wallet balance
|
|
1382
|
+
{
|
|
1383
|
+
target: poolInfo.poolSettleTokenAddr,
|
|
1384
|
+
allowFailure: false,
|
|
1385
|
+
callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
|
|
1386
|
+
},
|
|
1387
|
+
// 2: exchange fee
|
|
1388
|
+
{
|
|
1389
|
+
target: this.proxyContract.target,
|
|
1390
|
+
allowFailure: false,
|
|
1391
|
+
callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
|
|
1392
|
+
poolId,
|
|
1393
|
+
traderAddr,
|
|
1394
|
+
ZERO_ADDRESS,
|
|
1395
|
+
]),
|
|
1396
|
+
},
|
|
1397
|
+
];
|
|
1398
|
+
|
|
1399
|
+
// multicall
|
|
1400
|
+
const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, overrides || {});
|
|
1401
|
+
|
|
1402
|
+
// position risk
|
|
1403
|
+
const idxNotional = 4;
|
|
1404
|
+
const traderState = this.proxyContract.interface.decodeFunctionResult(
|
|
1405
|
+
"getTraderState",
|
|
1406
|
+
encodedResults[0].returnData
|
|
1407
|
+
)[0];
|
|
1408
|
+
const account = MarketData.buildMarginAccountFromState(
|
|
1409
|
+
symbol,
|
|
1410
|
+
traderState,
|
|
1411
|
+
this.symbolToPerpStaticInfo,
|
|
1412
|
+
indexPriceInfo,
|
|
1413
|
+
isPredMkt
|
|
1414
|
+
);
|
|
1415
|
+
|
|
1416
|
+
// fee rate
|
|
1417
|
+
const feeRateTbps = this.proxyContract.interface.decodeFunctionResult(
|
|
1418
|
+
"queryExchangeFee",
|
|
1419
|
+
encodedResults[2].returnData
|
|
1420
|
+
)[0] as bigint;
|
|
1421
|
+
|
|
1422
|
+
const feeRate = 1e-5 * Number(feeRateTbps);
|
|
1423
|
+
|
|
1424
|
+
// Max based on margin requirements:
|
|
1425
|
+
const walletBalance = decNToFloat(
|
|
1426
|
+
IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0],
|
|
1427
|
+
poolInfo.poolSettleTokenDecimals
|
|
1428
|
+
);
|
|
1429
|
+
|
|
1430
|
+
const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(
|
|
1431
|
+
perpId,
|
|
1432
|
+
traderState[idxNotional],
|
|
1433
|
+
overrides
|
|
1434
|
+
);
|
|
1249
1435
|
const curPos = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
|
|
1250
1436
|
|
|
1251
1437
|
const px: number = await coll2SettlePromise;
|
|
@@ -1259,7 +1445,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1259
1445
|
perpInfo.initialMarginRate,
|
|
1260
1446
|
feeRate,
|
|
1261
1447
|
account.markPrice,
|
|
1262
|
-
indexPriceInfo
|
|
1448
|
+
indexPriceInfo.s2,
|
|
1263
1449
|
account.collToQuoteConversion
|
|
1264
1450
|
);
|
|
1265
1451
|
const maxShortPosAccount = getMaxSignedPositionSize(
|
|
@@ -1271,7 +1457,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1271
1457
|
perpInfo.initialMarginRate,
|
|
1272
1458
|
feeRate,
|
|
1273
1459
|
account.markPrice,
|
|
1274
|
-
indexPriceInfo
|
|
1460
|
+
indexPriceInfo.s2,
|
|
1275
1461
|
account.collToQuoteConversion
|
|
1276
1462
|
);
|
|
1277
1463
|
|
|
@@ -1339,12 +1525,11 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1339
1525
|
*
|
|
1340
1526
|
* @returns {number} Price of index in given currency.
|
|
1341
1527
|
*/
|
|
1342
|
-
public async getOraclePrice(base: string, quote: string, overrides?: Overrides)
|
|
1528
|
+
public async getOraclePrice(base: string, quote: string, overrides?: Overrides) {
|
|
1343
1529
|
if (!this.proxyContract) {
|
|
1344
1530
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1345
1531
|
}
|
|
1346
|
-
|
|
1347
|
-
return px == undefined ? undefined : ABK64x64ToFloat(px);
|
|
1532
|
+
return await this.proxyContract.getOraclePrice([toBytes4(base), toBytes4(quote)], overrides || {});
|
|
1348
1533
|
}
|
|
1349
1534
|
|
|
1350
1535
|
/**
|
|
@@ -1420,6 +1605,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1420
1605
|
/**
|
|
1421
1606
|
* Get the current mark price
|
|
1422
1607
|
* @param symbol symbol of the form ETH-USD-MATIC
|
|
1608
|
+
* @param indexPrices optional. IdxPriceInfo
|
|
1423
1609
|
* @example
|
|
1424
1610
|
* import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
|
|
1425
1611
|
* async function main() {
|
|
@@ -1436,19 +1622,19 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1436
1622
|
*
|
|
1437
1623
|
* @returns {number} mark price
|
|
1438
1624
|
*/
|
|
1439
|
-
public async getMarkPrice(symbol: string, indexPrices?:
|
|
1625
|
+
public async getMarkPrice(symbol: string, indexPrices?: IdxPriceInfo): Promise<number> {
|
|
1440
1626
|
if (this.proxyContract == null) {
|
|
1441
1627
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1442
1628
|
}
|
|
1443
1629
|
if (indexPrices == undefined) {
|
|
1444
|
-
|
|
1445
|
-
indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
|
|
1630
|
+
indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1446
1631
|
}
|
|
1447
1632
|
return await PerpetualDataHandler._queryPerpetualMarkPrice(
|
|
1448
1633
|
symbol,
|
|
1449
1634
|
this.symbolToPerpStaticInfo,
|
|
1450
1635
|
this.proxyContract,
|
|
1451
|
-
indexPrices
|
|
1636
|
+
indexPrices,
|
|
1637
|
+
this.isPredictionMarket(symbol)
|
|
1452
1638
|
);
|
|
1453
1639
|
}
|
|
1454
1640
|
|
|
@@ -1456,6 +1642,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1456
1642
|
* get the current price for a given quantity
|
|
1457
1643
|
* @param symbol symbol of the form ETH-USD-MATIC
|
|
1458
1644
|
* @param quantity quantity to be traded, negative if short
|
|
1645
|
+
* @param priceInfo [s2, s3, conf, params]; for non-prediction markets conf/params can be 0
|
|
1459
1646
|
* @example
|
|
1460
1647
|
* import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
|
|
1461
1648
|
* async function main() {
|
|
@@ -1475,23 +1662,24 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1475
1662
|
public async getPerpetualPrice(
|
|
1476
1663
|
symbol: string,
|
|
1477
1664
|
quantity: number,
|
|
1478
|
-
|
|
1665
|
+
priceInfo?: IdxPriceInfo,
|
|
1479
1666
|
overrides?: Overrides
|
|
1480
1667
|
): Promise<number> {
|
|
1481
1668
|
if (this.proxyContract == null) {
|
|
1482
1669
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1483
1670
|
}
|
|
1484
|
-
if (
|
|
1671
|
+
if (priceInfo == undefined) {
|
|
1485
1672
|
// fetch from API
|
|
1486
|
-
|
|
1487
|
-
indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
|
|
1673
|
+
priceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1488
1674
|
}
|
|
1489
1675
|
return await PerpetualDataHandler._queryPerpetualPrice(
|
|
1490
1676
|
symbol,
|
|
1491
1677
|
quantity,
|
|
1492
1678
|
this.symbolToPerpStaticInfo,
|
|
1493
1679
|
this.proxyContract,
|
|
1494
|
-
|
|
1680
|
+
[priceInfo.s2, priceInfo.s3 ?? 0], //s2,s3
|
|
1681
|
+
priceInfo.conf, //conf
|
|
1682
|
+
priceInfo.predMktCLOBParams, //params
|
|
1495
1683
|
overrides
|
|
1496
1684
|
);
|
|
1497
1685
|
}
|
|
@@ -1503,15 +1691,14 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1503
1691
|
*/
|
|
1504
1692
|
public async getPerpetualState(
|
|
1505
1693
|
symbol: string,
|
|
1506
|
-
indexPriceInfo?:
|
|
1694
|
+
indexPriceInfo?: IdxPriceInfo,
|
|
1507
1695
|
overrides?: Overrides
|
|
1508
1696
|
): Promise<PerpetualState> {
|
|
1509
1697
|
if (this.proxyContract == null || this.multicall == null) {
|
|
1510
1698
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1511
1699
|
}
|
|
1512
1700
|
if (indexPriceInfo == undefined) {
|
|
1513
|
-
|
|
1514
|
-
indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
|
|
1701
|
+
indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1515
1702
|
}
|
|
1516
1703
|
let state: PerpetualState = await PerpetualDataHandler._queryPerpetualState(
|
|
1517
1704
|
symbol,
|
|
@@ -1743,7 +1930,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1743
1930
|
* Result is in collateral currency
|
|
1744
1931
|
* @param {string} traderAddr address of the trader
|
|
1745
1932
|
* @param {string} symbol perpetual symbol of the form BTC-USD-MATIC
|
|
1746
|
-
* @param indexPrices optional
|
|
1933
|
+
* @param indexPrices optional indexPriceInfo
|
|
1747
1934
|
* @returns available margin in collateral currency
|
|
1748
1935
|
* @example
|
|
1749
1936
|
* import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
|
|
@@ -1762,7 +1949,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1762
1949
|
public async getAvailableMargin(
|
|
1763
1950
|
traderAddr: string,
|
|
1764
1951
|
symbol: string,
|
|
1765
|
-
indexPrices?:
|
|
1952
|
+
indexPrices?: IdxPriceInfo,
|
|
1766
1953
|
overrides?: Overrides
|
|
1767
1954
|
): Promise<number> {
|
|
1768
1955
|
if (!this.proxyContract) {
|
|
@@ -1771,14 +1958,16 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1771
1958
|
|
|
1772
1959
|
if (indexPrices == undefined) {
|
|
1773
1960
|
// fetch from API
|
|
1774
|
-
|
|
1775
|
-
indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
|
|
1961
|
+
indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1776
1962
|
}
|
|
1777
1963
|
let perpID = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
|
|
1778
1964
|
let traderState = await this.proxyContract.getTraderState(
|
|
1779
1965
|
perpID,
|
|
1780
1966
|
traderAddr,
|
|
1781
|
-
indexPrices.map((x) => floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x)) as [
|
|
1967
|
+
[indexPrices.s2, indexPrices.s3].map((x) => floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x)) as [
|
|
1968
|
+
bigint,
|
|
1969
|
+
bigint
|
|
1970
|
+
],
|
|
1782
1971
|
overrides || {}
|
|
1783
1972
|
);
|
|
1784
1973
|
const idx_availableMargin = 1;
|
|
@@ -2111,7 +2300,8 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2111
2300
|
quoteCurrency: contractSymbolToSymbol(perp.S2QuoteCCY!, _symbolList)!,
|
|
2112
2301
|
indexPrice: 0, //fill later
|
|
2113
2302
|
collToQuoteIndexPrice: 0, //fill later
|
|
2114
|
-
|
|
2303
|
+
markPremium: ABK64x64ToFloat(perp.currentMarkPremiumRate!.fPrice),
|
|
2304
|
+
markPrice: 0, //fill later
|
|
2115
2305
|
midPrice: 0, // fill later
|
|
2116
2306
|
currentFundingRateBps: 1e4 * ABK64x64ToFloat(perp.fCurrentFundingRate!),
|
|
2117
2307
|
openInterestBC: ABK64x64ToFloat(perp.fOpenInterest!),
|
|
@@ -2188,7 +2378,6 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2188
2378
|
perp.isMarketClosed = perp.isMarketClosed || idxPriceS3Pair![1];
|
|
2189
2379
|
}
|
|
2190
2380
|
perp.indexPrice = idxPriceS2Pair![0];
|
|
2191
|
-
perp.markPrice = idxPriceS2Pair![0] * (1 + perp.markPrice); // currently filled with mark premium rate
|
|
2192
2381
|
let indexS3 = 1;
|
|
2193
2382
|
if (info!.collateralCurrencyType == COLLATERAL_CURRENCY_BASE) {
|
|
2194
2383
|
indexS3 = idxPriceS2Pair![0];
|
|
@@ -2196,6 +2385,18 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2196
2385
|
indexS3 = idxPriceS3Pair[0];
|
|
2197
2386
|
}
|
|
2198
2387
|
perp.collToQuoteIndexPrice = indexS3;
|
|
2388
|
+
|
|
2389
|
+
const emaKey = info!.S2Symbol + ":ema";
|
|
2390
|
+
let markPrice: number;
|
|
2391
|
+
if (idxPriceMap.has(emaKey)) {
|
|
2392
|
+
let ema: number;
|
|
2393
|
+
let res = idxPriceMap.get(emaKey);
|
|
2394
|
+
ema = res![0];
|
|
2395
|
+
markPrice = ema + perp.markPremium;
|
|
2396
|
+
} else {
|
|
2397
|
+
markPrice = perp.indexPrice * (1 + perp.markPremium);
|
|
2398
|
+
}
|
|
2399
|
+
perp.markPrice = markPrice;
|
|
2199
2400
|
perp.midPrice = midPriceMap.get(symbol3s!)!;
|
|
2200
2401
|
// which pool?
|
|
2201
2402
|
const poolId = info!.poolId;
|
|
@@ -2293,10 +2494,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2293
2494
|
* @param symbol Perpetual symbol of the form BTC-USDc-USDC
|
|
2294
2495
|
* @returns Prices and market-closed information
|
|
2295
2496
|
*/
|
|
2296
|
-
public async fetchPricesForPerpetual(symbol: string): Promise<{
|
|
2297
|
-
idxPrices: number[];
|
|
2298
|
-
mktClosed: boolean[];
|
|
2299
|
-
}> {
|
|
2497
|
+
public async fetchPricesForPerpetual(symbol: string): Promise<IdxPriceInfo> {
|
|
2300
2498
|
return this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
2301
2499
|
}
|
|
2302
2500
|
}
|