@d8x/perpetuals-sdk 2.1.27-alpha2 → 2.1.29-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/constants.d.ts +0 -1
- package/dist/cjs/constants.js +4 -3
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/d8XMath.d.ts +17 -34
- package/dist/cjs/d8XMath.js +24 -92
- package/dist/cjs/d8XMath.js.map +1 -1
- package/dist/cjs/marketData.d.ts +10 -1
- package/dist/cjs/marketData.js +17 -37
- package/dist/cjs/marketData.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/constants.d.ts +0 -1
- package/dist/esm/constants.js +3 -2
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/d8XMath.d.ts +17 -34
- package/dist/esm/d8XMath.js +23 -90
- package/dist/esm/d8XMath.js.map +1 -1
- package/dist/esm/marketData.d.ts +10 -1
- package/dist/esm/marketData.js +18 -38
- package/dist/esm/marketData.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/doc/d8x-perpetuals-sdk.md +52 -43
- package/doc/marketData.md +18 -1
- package/package.json +1 -1
- package/src/constants.ts +3 -2
- package/src/d8XMath.ts +22 -99
- package/src/marketData.ts +17 -65
- package/src/version.ts +1 -1
package/src/constants.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { NodeSDKConfig } from "./nodeSDKTypes";
|
|
|
4
4
|
export const ERC20_ABI = require("./abi/ERC20.json");
|
|
5
5
|
export const MOCK_TOKEN_SWAP_ABI = require("./abi/MockTokenSwap.json");
|
|
6
6
|
export const PROXY_ABI = require("./abi/IPerpetualManager.json");
|
|
7
|
-
export const PROXY_ZKEVM_ABI = require("./abi-zkevm/IPerpetualManager.json");
|
|
7
|
+
//export const PROXY_ZKEVM_ABI = require("./abi-zkevm/IPerpetualManager.json");
|
|
8
8
|
export const LOB_FACTORY_ABI = require("./abi/LimitOrderBookFactory.json");
|
|
9
9
|
export const LOB_ABI = require("./abi/LimitOrderBook.json");
|
|
10
10
|
export const SHARE_TOKEN_ABI = require("./abi/ShareToken.json");
|
|
@@ -58,7 +58,8 @@ export const DEFAULT_CONFIG_TESTNET_NAME = "testnet";
|
|
|
58
58
|
|
|
59
59
|
let defaultConfigs = require("./config/defaultConfig.json") as NodeSDKConfig[];
|
|
60
60
|
defaultConfigs.map((config) => {
|
|
61
|
-
config.proxyABI = config.proxyABILocation.includes("abi-zkevm") ? PROXY_ZKEVM_ABI : PROXY_ABI;
|
|
61
|
+
//config.proxyABI = config.proxyABILocation.includes("abi-zkevm") ? PROXY_ZKEVM_ABI : PROXY_ABI;
|
|
62
|
+
config.proxyABI = PROXY_ABI;
|
|
62
63
|
config.lobABI = LOB_ABI;
|
|
63
64
|
config.lobFactoryABI = LOB_FACTORY_ABI;
|
|
64
65
|
config.shareTokenABI = SHARE_TOKEN_ABI;
|
package/src/d8XMath.ts
CHANGED
|
@@ -778,23 +778,24 @@ function pmExcessCashAtLvg(
|
|
|
778
778
|
}
|
|
779
779
|
|
|
780
780
|
/**
|
|
781
|
-
* Find maximal trade size (short dir=-1 or long dir=1) for prediction
|
|
781
|
+
* Find maximal *affordable* trade size (short dir=-1 or long dir=1) for prediction
|
|
782
782
|
* markets at provided leverage and incorporating the current position
|
|
783
783
|
* and wallet balance.
|
|
784
784
|
* Factors in lot size and global max short/long
|
|
785
|
-
* @param dir
|
|
786
|
-
* @param lvg
|
|
787
|
-
* @param walletBalCC
|
|
788
|
-
* @param slippage slippage percent
|
|
789
|
-
* @param currentPosition
|
|
790
|
-
* @param currentCashCC
|
|
791
|
-
* @param currentLockedInValue
|
|
792
|
-
* @param S2
|
|
793
|
-
* @param Sm
|
|
794
|
-
* @param S3
|
|
795
|
-
* @param
|
|
796
|
-
*
|
|
797
|
-
*
|
|
785
|
+
* @param dir direction of trade (-1 sell, 1 buy)
|
|
786
|
+
* @param lvg leverage of the trade
|
|
787
|
+
* @param walletBalCC wallet balance of the trader (collateral currency)
|
|
788
|
+
* @param slippage slippage percent used to estimate a traded price
|
|
789
|
+
* @param currentPosition position in base currency of the trader
|
|
790
|
+
* @param currentCashCC this is the cash available net of unpaid funding (often called available cash)
|
|
791
|
+
* @param currentLockedInValue average entry price * signed position size in base currency, in margin account
|
|
792
|
+
* @param S2 current index price of the form 1+p (regardless whether short or long)
|
|
793
|
+
* @param Sm current mark price (not just the mark price index but including the ema-premium from the contract)
|
|
794
|
+
* @param S3 current collateral to quote index price
|
|
795
|
+
* @param glblMaxTrade global max short or long order size that we retreive, e.g., from position risk (sign irrelevant)
|
|
796
|
+
* based on long: (*ℓ+n) * (1-p) - m (1-p) s = F → n = (F+m*(1-p)*s)/(1-p)-ℓ*
|
|
797
|
+
* short: (s+n)*p - m p *ℓ* = F →n = (F+m*p**ℓ*)/p-s
|
|
798
|
+
* @returns max *signed* trade size
|
|
798
799
|
*/
|
|
799
800
|
export function pmFindMaxPersonalTradeSizeAtLeverage(
|
|
800
801
|
dir: number,
|
|
@@ -807,8 +808,7 @@ export function pmFindMaxPersonalTradeSizeAtLeverage(
|
|
|
807
808
|
S2: number,
|
|
808
809
|
Sm: number,
|
|
809
810
|
S3: number,
|
|
810
|
-
|
|
811
|
-
maxLong: number
|
|
811
|
+
glblMaxTrade: number
|
|
812
812
|
): number {
|
|
813
813
|
if (dir < 0) {
|
|
814
814
|
dir = -1;
|
|
@@ -880,94 +880,17 @@ export function pmFindMaxPersonalTradeSizeAtLeverage(
|
|
|
880
880
|
// Newton algorithm failed,
|
|
881
881
|
// choose new starting value
|
|
882
882
|
if (dir > 0) {
|
|
883
|
-
sNew = Math.random() * (
|
|
884
|
-
} else {
|
|
885
|
-
sNew = -Math.random() * (Math.abs(maxShort) + currentPosition);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
// ensure trade maximal trade sNew does not exceed
|
|
889
|
-
// the contract limits
|
|
890
|
-
if (sNew < -Math.abs(maxShort)) {
|
|
891
|
-
sNew = -Math.abs(maxShort);
|
|
892
|
-
} else if (sNew > maxLong) {
|
|
893
|
-
sNew = maxLong;
|
|
894
|
-
}
|
|
895
|
-
// round trade size down to lot
|
|
896
|
-
sNew = Math.sign(sNew) * Math.floor(Math.abs(sNew) / lot) * lot;
|
|
897
|
-
return sNew;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
/**
|
|
901
|
-
* Find maximal trade size (short dir=-1 or long dir=1) for prediction
|
|
902
|
-
* markets at maximal leverage and incorporating the current position.
|
|
903
|
-
* Agnostic about wallet balance.
|
|
904
|
-
* @param dir
|
|
905
|
-
* @param currentPosition
|
|
906
|
-
* @param currentCashCC
|
|
907
|
-
* @param currentLockedInValue
|
|
908
|
-
* @param limitPrice
|
|
909
|
-
* @param Sm
|
|
910
|
-
* @param S3
|
|
911
|
-
* @param totLong
|
|
912
|
-
* @param totShort
|
|
913
|
-
* @param maxShort
|
|
914
|
-
* @param maxLong
|
|
915
|
-
* @returns signed max trade size
|
|
916
|
-
*/
|
|
917
|
-
export function pmFindMaxTradeSize(
|
|
918
|
-
dir: number,
|
|
919
|
-
currentPosition: number,
|
|
920
|
-
currentCashCC: number,
|
|
921
|
-
currentLockedInValue: number,
|
|
922
|
-
limitPrice: number,
|
|
923
|
-
Sm: number,
|
|
924
|
-
S3: number,
|
|
925
|
-
maxShort: number,
|
|
926
|
-
maxLong: number
|
|
927
|
-
): number {
|
|
928
|
-
if (dir < 0) {
|
|
929
|
-
dir = -1;
|
|
930
|
-
} else {
|
|
931
|
-
dir = 1;
|
|
932
|
-
}
|
|
933
|
-
const lot = 10;
|
|
934
|
-
const deltaS = 1; //for derivative
|
|
935
|
-
const f0 = excessMargin(dir * deltaS, currentCashCC, currentPosition, currentLockedInValue, limitPrice, Sm, S3);
|
|
936
|
-
if (f0 < lot) {
|
|
937
|
-
// no trade possible
|
|
938
|
-
return 0;
|
|
939
|
-
}
|
|
940
|
-
// numerically find maximal trade size
|
|
941
|
-
let sNew = dir * lot * 10;
|
|
942
|
-
let s = 2 * sNew;
|
|
943
|
-
while (true) {
|
|
944
|
-
let count = 0;
|
|
945
|
-
while (Math.abs(sNew - s) > 1 && count < 100) {
|
|
946
|
-
s = sNew;
|
|
947
|
-
const f = excessMargin(s, currentCashCC, currentPosition, currentLockedInValue, limitPrice, Sm, S3) ** 2;
|
|
948
|
-
const f2 =
|
|
949
|
-
excessMargin(s + deltaS, currentCashCC, currentPosition, currentLockedInValue, limitPrice, Sm, S3) ** 2;
|
|
950
|
-
let ds = (f2 - f) / deltaS;
|
|
951
|
-
sNew = s - f / ds;
|
|
952
|
-
count += 1;
|
|
953
|
-
}
|
|
954
|
-
if (count < 100) {
|
|
955
|
-
break;
|
|
956
|
-
}
|
|
957
|
-
// Newton algorithm failed,
|
|
958
|
-
// choose new starting value
|
|
959
|
-
if (dir > 0) {
|
|
960
|
-
sNew = Math.random() * (maxLong - currentPosition);
|
|
883
|
+
sNew = Math.random() * (glblMaxTrade - currentPosition);
|
|
961
884
|
} else {
|
|
962
|
-
sNew = -Math.random() * (Math.abs(
|
|
885
|
+
sNew = -Math.random() * (Math.abs(glblMaxTrade) + currentPosition);
|
|
963
886
|
}
|
|
964
887
|
}
|
|
965
888
|
// ensure trade maximal trade sNew does not exceed
|
|
966
889
|
// the contract limits
|
|
967
|
-
if (
|
|
968
|
-
sNew =
|
|
969
|
-
} else if (
|
|
970
|
-
sNew =
|
|
890
|
+
if (sNew < -Math.abs(glblMaxTrade)) {
|
|
891
|
+
sNew = -Math.abs(glblMaxTrade);
|
|
892
|
+
} else if (sNew > glblMaxTrade) {
|
|
893
|
+
sNew = glblMaxTrade;
|
|
971
894
|
}
|
|
972
895
|
// round trade size down to lot
|
|
973
896
|
sNew = Math.sign(sNew) * Math.floor(Math.abs(sNew) / lot) * lot;
|
package/src/marketData.ts
CHANGED
|
@@ -38,7 +38,6 @@ import {
|
|
|
38
38
|
entropy,
|
|
39
39
|
expectedLoss,
|
|
40
40
|
pmExchangeFee,
|
|
41
|
-
pmFindMaxTradeSize,
|
|
42
41
|
} from "./d8XMath";
|
|
43
42
|
import {
|
|
44
43
|
type ExchangeInfo,
|
|
@@ -571,13 +570,13 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
571
570
|
"getMaxSignedOpenTradeSizeForPos",
|
|
572
571
|
encodedResults[2].returnData
|
|
573
572
|
)[0] as bigint;
|
|
574
|
-
const maxLongTrade =
|
|
573
|
+
const maxLongTrade = ABK64x64ToFloat(fMaxLong);
|
|
575
574
|
// max sell
|
|
576
575
|
const fMaxShort = this.proxyContract.interface.decodeFunctionResult(
|
|
577
576
|
"getMaxSignedOpenTradeSizeForPos",
|
|
578
577
|
encodedResults[3].returnData
|
|
579
578
|
)[0] as bigint;
|
|
580
|
-
const maxShortTrade =
|
|
579
|
+
const maxShortTrade = ABK64x64ToFloat(fMaxShort);
|
|
581
580
|
return { account: account, ammPrice: ammPrice, maxShortTrade: maxShortTrade, maxLongTrade: maxLongTrade };
|
|
582
581
|
}
|
|
583
582
|
|
|
@@ -1160,7 +1159,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1160
1159
|
* Accounts for user's wallet balance.
|
|
1161
1160
|
* @param {string} traderAddr Address of trader
|
|
1162
1161
|
* @param {symbol} symbol Symbol of the form ETH-USD-MATIC
|
|
1163
|
-
* @returns Maximal trade sizes
|
|
1162
|
+
* @returns Maximal buy and sell trade sizes (positive)
|
|
1164
1163
|
* @example
|
|
1165
1164
|
* import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
|
|
1166
1165
|
* async function main() {
|
|
@@ -1191,6 +1190,15 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1191
1190
|
return this.rmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
|
|
1192
1191
|
}
|
|
1193
1192
|
|
|
1193
|
+
/**
|
|
1194
|
+
* pmMaxOrderSizeForTrader returns the max order size for the
|
|
1195
|
+
* trader that is possible from AMM perspective (agnostic about wallet
|
|
1196
|
+
* balance and leverage)
|
|
1197
|
+
* @param traderAddr address of trader
|
|
1198
|
+
* @param symbol perp symbol
|
|
1199
|
+
* @param overrides optional
|
|
1200
|
+
* @returns buy: number; sell: number absolute
|
|
1201
|
+
*/
|
|
1194
1202
|
private async pmMaxOrderSizeForTrader(
|
|
1195
1203
|
traderAddr: string,
|
|
1196
1204
|
symbol: string,
|
|
@@ -1199,13 +1207,9 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1199
1207
|
if (!this.proxyContract || !this.multicall) {
|
|
1200
1208
|
throw new Error("proxy contract not initialized");
|
|
1201
1209
|
}
|
|
1202
|
-
const IERC20 = new Interface(ERC20_ABI) as ERC20Interface;
|
|
1203
1210
|
const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
|
|
1204
|
-
const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
|
|
1205
1211
|
const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1206
|
-
const [
|
|
1207
|
-
floatToABK64x64(x)
|
|
1208
|
-
) as [bigint, bigint, bigint];
|
|
1212
|
+
const [fS3, fEma] = [indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) => floatToABK64x64(x)) as [bigint, bigint];
|
|
1209
1213
|
const proxyCalls: Multicall3.Call3Struct[] = [
|
|
1210
1214
|
// 0: traderState
|
|
1211
1215
|
{
|
|
@@ -1213,19 +1217,6 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1213
1217
|
allowFailure: false,
|
|
1214
1218
|
callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
|
|
1215
1219
|
},
|
|
1216
|
-
|
|
1217
|
-
// 1: wallet balance
|
|
1218
|
-
{
|
|
1219
|
-
target: poolInfo.poolSettleTokenAddr,
|
|
1220
|
-
allowFailure: false,
|
|
1221
|
-
callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
|
|
1222
|
-
},
|
|
1223
|
-
// 2: amm state
|
|
1224
|
-
{
|
|
1225
|
-
target: this.proxyContract.target,
|
|
1226
|
-
allowFailure: false,
|
|
1227
|
-
callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, [fS2, fS3]]),
|
|
1228
|
-
},
|
|
1229
1220
|
];
|
|
1230
1221
|
|
|
1231
1222
|
// multicall
|
|
@@ -1234,11 +1225,6 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1234
1225
|
"getTraderState",
|
|
1235
1226
|
encodedResults[0].returnData
|
|
1236
1227
|
)[0];
|
|
1237
|
-
const walletBalance = decNToFloat(
|
|
1238
|
-
IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0],
|
|
1239
|
-
poolInfo.poolSettleTokenDecimals
|
|
1240
|
-
);
|
|
1241
|
-
const ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[2].returnData)[0];
|
|
1242
1228
|
|
|
1243
1229
|
const account = MarketData.buildMarginAccountFromState(
|
|
1244
1230
|
symbol,
|
|
@@ -1247,51 +1233,17 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1247
1233
|
indexPriceInfo,
|
|
1248
1234
|
true //isPredMkt
|
|
1249
1235
|
);
|
|
1250
|
-
const openInterestBC = ABK64x64ToFloat(ammState[11]);
|
|
1251
|
-
const net = -ABK64x64ToFloat(ammState[1]);
|
|
1252
|
-
let totLong, totShort;
|
|
1253
|
-
if (net < 0) {
|
|
1254
|
-
totLong = openInterestBC;
|
|
1255
|
-
totShort = openInterestBC - Math.abs(net);
|
|
1256
|
-
} else {
|
|
1257
|
-
totLong = openInterestBC - net;
|
|
1258
|
-
totShort = openInterestBC;
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
1236
|
let currentPositionBC = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
|
|
1262
|
-
const Sm = ABK64x64ToFloat(traderState[8]);
|
|
1263
|
-
// settlement token must be equal to collateral token for walletBalance to be correct
|
|
1264
|
-
const availCashCC = account.collateralCC + walletBalance + account.unrealizedFundingCollateralCCY;
|
|
1265
1237
|
const idxNotional = 4;
|
|
1266
1238
|
const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(
|
|
1267
1239
|
perpId,
|
|
1268
1240
|
traderState[idxNotional],
|
|
1269
1241
|
overrides
|
|
1270
1242
|
);
|
|
1271
|
-
|
|
1272
|
-
const
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
availCashCC,
|
|
1276
|
-
account.entryPrice * currentPositionBC,
|
|
1277
|
-
Sm,
|
|
1278
|
-
Sm,
|
|
1279
|
-
indexPriceInfo.s3 ?? 0,
|
|
1280
|
-
maxShortPosPerp,
|
|
1281
|
-
maxLongPosPerp
|
|
1282
|
-
);
|
|
1283
|
-
const maxLong = pmFindMaxTradeSize(
|
|
1284
|
-
1,
|
|
1285
|
-
currentPositionBC,
|
|
1286
|
-
availCashCC,
|
|
1287
|
-
account.entryPrice * currentPositionBC,
|
|
1288
|
-
Sm,
|
|
1289
|
-
Sm,
|
|
1290
|
-
indexPriceInfo.s3 ?? 0,
|
|
1291
|
-
maxShortPosPerp,
|
|
1292
|
-
maxLongPosPerp
|
|
1293
|
-
);
|
|
1294
|
-
return { buy: maxLong, sell: maxShort };
|
|
1243
|
+
// max trade size from position; return positive value
|
|
1244
|
+
const maxLongTrade = Math.abs(maxLongPosPerp - currentPositionBC);
|
|
1245
|
+
const maxShortTrade = Math.abs(maxShortPosPerp - currentPositionBC);
|
|
1246
|
+
return { buy: maxLongTrade, sell: maxShortTrade };
|
|
1295
1247
|
}
|
|
1296
1248
|
|
|
1297
1249
|
/**
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const D8X_SDK_VERSION = "2.1.
|
|
1
|
+
export const D8X_SDK_VERSION = "2.1.29-alpha2";
|