@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/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 maxShort global max short order size (sign irrelevant)
796
- * @param maxLong global max long order size (positive)
797
- * @returns max trade size
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
- maxShort: number,
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() * (maxLong - currentPosition);
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(maxShort) + currentPosition);
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 (currentPosition + sNew < maxShort) {
968
- sNew = maxShort - currentPosition;
969
- } else if (currentPosition + sNew > maxLong) {
970
- sNew = maxLong - currentPosition;
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 = Math.max(0, ABK64x64ToFloat(fMaxLong) - signedPositionNotionalBaseCCY);
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 = Math.max(0, Math.abs(ABK64x64ToFloat(fMaxShort)) - signedPositionNotionalBaseCCY);
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 [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3 ?? 0, indexPriceInfo.ema].map((x) =>
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 maxShort = pmFindMaxTradeSize(
1273
- -1,
1274
- currentPositionBC,
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.27-alpha2";
1
+ export const D8X_SDK_VERSION = "2.1.29-alpha2";