@d8x/perpetuals-sdk 0.0.39 → 0.0.40

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.
@@ -253,5 +253,6 @@ export default class MarketData extends PerpetualDataHandler {
253
253
  * @ignore
254
254
  */
255
255
  static orderIdsOfTrader(traderAddr: string, orderBookContract: ethers.Contract): Promise<string[]>;
256
+ getAvailableMargin(traderAddr: string, symbol: string): Promise<number>;
256
257
  static _exchangeInfo(_proxyContract: ethers.Contract, _poolStaticInfos: Array<PoolStaticInfo>, _symbolList: Map<string, string>): Promise<ExchangeInfo>;
257
258
  }
@@ -496,6 +496,19 @@ class MarketData extends perpetualDataHandler_1.default {
496
496
  return digests;
497
497
  });
498
498
  }
499
+ getAvailableMargin(traderAddr, symbol) {
500
+ return __awaiter(this, void 0, void 0, function* () {
501
+ if (this.proxyContract == null) {
502
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
503
+ }
504
+ let mgnAcct = yield perpetualDataHandler_1.default.getMarginAccount(traderAddr, symbol, this.symbolToPerpStaticInfo, this.proxyContract);
505
+ let perpInfo = this.symbolToPerpStaticInfo.get(symbol);
506
+ let balanceCC = mgnAcct.collateralCC + mgnAcct.unrealizedPnlQuoteCCY / mgnAcct.collToQuoteConversion;
507
+ let initalMarginCC = Math.abs((perpInfo.initialMarginRate * mgnAcct.positionNotionalBaseCCY * mgnAcct.markPrice) /
508
+ mgnAcct.collToQuoteConversion);
509
+ return balanceCC - initalMarginCC;
510
+ });
511
+ }
499
512
  static _exchangeInfo(_proxyContract, _poolStaticInfos, _symbolList) {
500
513
  return __awaiter(this, void 0, void 0, function* () {
501
514
  let nestedPerpetualIDs = yield perpetualDataHandler_1.default.getNestedPerpetualIds(_proxyContract);
@@ -284,12 +284,12 @@ class OrderReferrerTool extends writeAccessHandler_1.default {
284
284
  if (order.quantity < perpetualDataHandler_1.default._getLotSize(order.symbol, symbolToPerpInfoMap)) {
285
285
  return false;
286
286
  }
287
- // check limit price, which may be undefined if it's an unrestricted market order
287
+ // check limit price: fromSmartContractOrder will set it to undefined when not tradeable
288
288
  if (order.limitPrice == undefined) {
289
- order.limitPrice = order.side == nodeSDKTypes_1.BUY_SIDE ? Infinity : 0;
289
+ return false;
290
290
  }
291
- if ((order.side == nodeSDKTypes_1.BUY_SIDE && orderPrice > order.limitPrice) ||
292
- (order.side == nodeSDKTypes_1.SELL_SIDE && orderPrice < order.limitPrice)) {
291
+ let limitPrice = order.limitPrice;
292
+ if ((order.side == nodeSDKTypes_1.BUY_SIDE && orderPrice > limitPrice) || (order.side == nodeSDKTypes_1.SELL_SIDE && orderPrice < limitPrice)) {
293
293
  return false;
294
294
  }
295
295
  // do we need to check trigger/stop?
@@ -337,7 +337,8 @@ class PerpetualDataHandler {
337
337
  else {
338
338
  S2Liq = (0, d8XMath_1.calculateLiquidationPriceCollateralQuote)(lockedInValueQC, position, cashCC, tau);
339
339
  }
340
- let pnl = position * Sm - lockedInValueQC - unpaidFunding;
340
+ // account cash + pnl = avail cash + pos Sm - L = margin balance
341
+ let pnl = position * Sm - lockedInValueQC + unpaidFunding;
341
342
  return [S2Liq, S3Liq, tau, pnl, unpaidFundingCC];
342
343
  }
343
344
  /**
@@ -405,8 +406,11 @@ class PerpetualDataHandler {
405
406
  let side = order.fAmount > 0 ? nodeSDKTypes_1.BUY_SIDE : nodeSDKTypes_1.SELL_SIDE;
406
407
  let limitPrice, stopPrice;
407
408
  let fLimitPrice = ethers_1.BigNumber.from(order.fLimitPrice);
408
- if (fLimitPrice.eq(0) || fLimitPrice.eq(nodeSDKTypes_1.MAX_64x64)) {
409
- limitPrice = undefined;
409
+ if (fLimitPrice.eq(0)) {
410
+ limitPrice = side == nodeSDKTypes_1.BUY_SIDE ? undefined : 0;
411
+ }
412
+ else if (fLimitPrice.eq(nodeSDKTypes_1.MAX_64x64)) {
413
+ limitPrice = side == nodeSDKTypes_1.BUY_SIDE ? Infinity : undefined;
410
414
  }
411
415
  else {
412
416
  limitPrice = (0, d8XMath_1.ABK64x64ToFloat)(fLimitPrice);
@@ -49,7 +49,7 @@ class WriteAccessHandler extends perpetualDataHandler_1.default {
49
49
  createProxyInstance(provider) {
50
50
  return __awaiter(this, void 0, void 0, function* () {
51
51
  if (provider == undefined) {
52
- this.provider = new ethers_1.ethers.providers.JsonRpcProvider(this.nodeURL);
52
+ this.provider = new ethers_1.ethers.providers.JsonRpcBatchProvider(this.nodeURL);
53
53
  }
54
54
  else {
55
55
  this.provider = provider;
package/package.json CHANGED
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "name": "@d8x/perpetuals-sdk",
34
34
  "description": "Node TypeScript SDK for D8X Perpetual Futures",
35
- "version": "0.0.39",
35
+ "version": "0.0.40",
36
36
  "main": "./dist/index.js",
37
37
  "types": "./dist/index.d.ts",
38
38
  "directories": {
package/src/marketData.ts CHANGED
@@ -597,6 +597,25 @@ export default class MarketData extends PerpetualDataHandler {
597
597
  return digests;
598
598
  }
599
599
 
600
+ public async getAvailableMargin(traderAddr: string, symbol: string): Promise<number> {
601
+ if (this.proxyContract == null) {
602
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
603
+ }
604
+ let mgnAcct = await PerpetualDataHandler.getMarginAccount(
605
+ traderAddr,
606
+ symbol,
607
+ this.symbolToPerpStaticInfo,
608
+ this.proxyContract
609
+ );
610
+ let perpInfo = this.symbolToPerpStaticInfo.get(symbol);
611
+ let balanceCC = mgnAcct.collateralCC + mgnAcct.unrealizedPnlQuoteCCY / mgnAcct.collToQuoteConversion;
612
+ let initalMarginCC = Math.abs(
613
+ (perpInfo!.initialMarginRate * mgnAcct.positionNotionalBaseCCY * mgnAcct.markPrice) /
614
+ mgnAcct.collToQuoteConversion
615
+ );
616
+ return balanceCC - initalMarginCC;
617
+ }
618
+
600
619
  public static async _exchangeInfo(
601
620
  _proxyContract: ethers.Contract,
602
621
  _poolStaticInfos: Array<PoolStaticInfo>,
@@ -311,15 +311,12 @@ export default class OrderReferrerTool extends WriteAccessHandler {
311
311
  if (order.quantity < PerpetualDataHandler._getLotSize(order.symbol, symbolToPerpInfoMap)) {
312
312
  return false;
313
313
  }
314
- // check limit price, which may be undefined if it's an unrestricted market order
314
+ // check limit price: fromSmartContractOrder will set it to undefined when not tradeable
315
315
  if (order.limitPrice == undefined) {
316
- order.limitPrice = order.side == BUY_SIDE ? Infinity : 0;
316
+ return false;
317
317
  }
318
-
319
- if (
320
- (order.side == BUY_SIDE && orderPrice > order.limitPrice) ||
321
- (order.side == SELL_SIDE && orderPrice < order.limitPrice)
322
- ) {
318
+ let limitPrice = order.limitPrice!;
319
+ if ((order.side == BUY_SIDE && orderPrice > limitPrice) || (order.side == SELL_SIDE && orderPrice < limitPrice)) {
323
320
  return false;
324
321
  }
325
322
  // do we need to check trigger/stop?
@@ -426,7 +426,8 @@ export default class PerpetualDataHandler {
426
426
  } else {
427
427
  S2Liq = calculateLiquidationPriceCollateralQuote(lockedInValueQC, position, cashCC, tau);
428
428
  }
429
- let pnl = position * Sm - lockedInValueQC - unpaidFunding;
429
+ // account cash + pnl = avail cash + pos Sm - L = margin balance
430
+ let pnl = position * Sm - lockedInValueQC + unpaidFunding;
430
431
  return [S2Liq, S3Liq, tau, pnl, unpaidFundingCC];
431
432
  }
432
433
 
@@ -506,8 +507,10 @@ export default class PerpetualDataHandler {
506
507
  let side = order.fAmount > 0 ? BUY_SIDE : SELL_SIDE;
507
508
  let limitPrice, stopPrice;
508
509
  let fLimitPrice: BigNumber | undefined = BigNumber.from(order.fLimitPrice);
509
- if (fLimitPrice.eq(0) || fLimitPrice.eq(MAX_64x64)) {
510
- limitPrice = undefined;
510
+ if (fLimitPrice.eq(0)) {
511
+ limitPrice = side == BUY_SIDE ? undefined : 0;
512
+ } else if (fLimitPrice.eq(MAX_64x64)) {
513
+ limitPrice = side == BUY_SIDE ? Infinity : undefined;
511
514
  } else {
512
515
  limitPrice = ABK64x64ToFloat(fLimitPrice);
513
516
  }
@@ -37,7 +37,7 @@ export default class WriteAccessHandler extends PerpetualDataHandler {
37
37
  */
38
38
  public async createProxyInstance(provider?: ethers.providers.JsonRpcProvider) {
39
39
  if (provider == undefined) {
40
- this.provider = new ethers.providers.JsonRpcProvider(this.nodeURL);
40
+ this.provider = new ethers.providers.JsonRpcBatchProvider(this.nodeURL);
41
41
  } else {
42
42
  this.provider = provider;
43
43
  }