@imbingox/acex 0.3.1-beta.0 → 0.4.0-beta.2

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.
@@ -15,6 +15,7 @@ import type {
15
15
  PrivateSubscriptionState,
16
16
  } from "../client/context.ts";
17
17
  import { AsyncEventBus } from "../internal/async-event-bus.ts";
18
+ import { toCanonical } from "../internal/decimal.ts";
18
19
  import { matchesAccountFilter } from "../internal/filters.ts";
19
20
  import type {
20
21
  AccountDataStatus,
@@ -56,6 +57,10 @@ function getBigNumber(
56
57
  return value === undefined ? fallback : new BigNumber(value);
57
58
  }
58
59
 
60
+ function isZeroDecimal(value: string): boolean {
61
+ return new BigNumber(value).isZero();
62
+ }
63
+
59
64
  export class AccountManagerImpl
60
65
  implements
61
66
  AccountManager,
@@ -322,7 +327,7 @@ export class AccountManagerImpl
322
327
  positions.get(key),
323
328
  );
324
329
 
325
- if (nextPosition.size.isZero()) {
330
+ if (isZeroDecimal(nextPosition.size)) {
326
331
  positions.delete(key);
327
332
  } else {
328
333
  positions.set(key, nextPosition);
@@ -461,7 +466,7 @@ export class AccountManagerImpl
461
466
  );
462
467
  const positions = bootstrap.positions
463
468
  .map((position) => this.createPosition(accountId, venue, position))
464
- .filter((position) => !position.size.isZero());
469
+ .filter((position) => !isZeroDecimal(position.size));
465
470
  const risk = bootstrap.risk
466
471
  ? this.createRisk(accountId, venue, bootstrap.risk)
467
472
  : undefined;
@@ -499,9 +504,12 @@ export class AccountManagerImpl
499
504
  input: RawBalanceUpdate,
500
505
  previous?: BalanceSnapshot,
501
506
  ): BalanceSnapshot {
502
- const previousFree = previous?.free ?? new BigNumber(0);
503
- const previousUsed = previous?.used ?? new BigNumber(0);
504
- const previousTotal = previous?.total ?? previousFree.plus(previousUsed);
507
+ const previousFree = new BigNumber(previous?.free ?? 0);
508
+ const previousUsed = new BigNumber(previous?.used ?? 0);
509
+ const previousTotal =
510
+ previous?.total === undefined
511
+ ? previousFree.plus(previousUsed)
512
+ : new BigNumber(previous.total);
505
513
  const free = getBigNumber(input.free, previousFree);
506
514
  const total = getBigNumber(input.total, previousTotal);
507
515
  const used =
@@ -515,27 +523,27 @@ export class AccountManagerImpl
515
523
  accountId,
516
524
  venue,
517
525
  asset: input.asset,
518
- free,
519
- used,
520
- total,
526
+ free: toCanonical(free),
527
+ used: toCanonical(used),
528
+ total: toCanonical(total),
521
529
  exchangeTs: input.exchangeTs,
522
530
  receivedAt: input.receivedAt,
523
531
  updatedAt: input.receivedAt,
524
532
  seq: (previous?.seq ?? 0) + 1,
525
533
  lending: input.lending
526
534
  ? {
527
- supplied: new BigNumber(input.lending.supplied),
528
- borrowed: new BigNumber(input.lending.borrowed),
529
- interest: new BigNumber(input.lending.interest),
530
- netAsset: new BigNumber(input.lending.netAsset),
535
+ supplied: toCanonical(input.lending.supplied),
536
+ borrowed: toCanonical(input.lending.borrowed),
537
+ interest: toCanonical(input.lending.interest),
538
+ netAsset: toCanonical(input.lending.netAsset),
531
539
  supplyAPY:
532
540
  input.lending.supplyAPY === undefined
533
541
  ? undefined
534
- : new BigNumber(input.lending.supplyAPY),
542
+ : toCanonical(input.lending.supplyAPY),
535
543
  borrowAPY:
536
544
  input.lending.borrowAPY === undefined
537
545
  ? undefined
538
- : new BigNumber(input.lending.borrowAPY),
546
+ : toCanonical(input.lending.borrowAPY),
539
547
  }
540
548
  : previous?.lending,
541
549
  };
@@ -552,27 +560,27 @@ export class AccountManagerImpl
552
560
  venue,
553
561
  symbol: input.symbol,
554
562
  side: input.side,
555
- size: new BigNumber(input.size),
563
+ size: toCanonical(input.size),
556
564
  entryPrice:
557
565
  input.entryPrice === undefined
558
566
  ? previous?.entryPrice
559
- : new BigNumber(input.entryPrice),
567
+ : toCanonical(input.entryPrice),
560
568
  markPrice:
561
569
  input.markPrice === undefined
562
570
  ? previous?.markPrice
563
- : new BigNumber(input.markPrice),
571
+ : toCanonical(input.markPrice),
564
572
  unrealizedPnl:
565
573
  input.unrealizedPnl === undefined
566
574
  ? previous?.unrealizedPnl
567
- : new BigNumber(input.unrealizedPnl),
575
+ : toCanonical(input.unrealizedPnl),
568
576
  leverage:
569
577
  input.leverage === undefined
570
578
  ? previous?.leverage
571
- : new BigNumber(input.leverage),
579
+ : toCanonical(input.leverage),
572
580
  liquidationPrice:
573
581
  input.liquidationPrice === undefined
574
582
  ? previous?.liquidationPrice
575
- : new BigNumber(input.liquidationPrice),
583
+ : toCanonical(input.liquidationPrice),
576
584
  exchangeTs: input.exchangeTs,
577
585
  receivedAt: input.receivedAt,
578
586
  updatedAt: input.receivedAt,
@@ -592,27 +600,27 @@ export class AccountManagerImpl
592
600
  netEquity:
593
601
  input.netEquity === undefined
594
602
  ? previous?.netEquity
595
- : new BigNumber(input.netEquity),
603
+ : toCanonical(input.netEquity),
596
604
  riskEquity:
597
605
  input.riskEquity === undefined
598
606
  ? previous?.riskEquity
599
- : new BigNumber(input.riskEquity),
607
+ : toCanonical(input.riskEquity),
600
608
  riskRatio:
601
609
  input.riskRatio === undefined
602
610
  ? previous?.riskRatio
603
- : new BigNumber(input.riskRatio),
611
+ : toCanonical(input.riskRatio),
604
612
  riskLeverage:
605
613
  input.riskLeverage === undefined
606
614
  ? previous?.riskLeverage
607
- : new BigNumber(input.riskLeverage),
615
+ : toCanonical(input.riskLeverage),
608
616
  initialMargin:
609
617
  input.initialMargin === undefined
610
618
  ? previous?.initialMargin
611
- : new BigNumber(input.initialMargin),
619
+ : toCanonical(input.initialMargin),
612
620
  maintenanceMargin:
613
621
  input.maintenanceMargin === undefined
614
622
  ? previous?.maintenanceMargin
615
- : new BigNumber(input.maintenanceMargin),
623
+ : toCanonical(input.maintenanceMargin),
616
624
  exchangeTs: input.exchangeTs,
617
625
  receivedAt: input.receivedAt,
618
626
  updatedAt: input.receivedAt,
@@ -622,27 +630,27 @@ export class AccountManagerImpl
622
630
  marginLevel:
623
631
  input.lending.marginLevel === undefined
624
632
  ? undefined
625
- : new BigNumber(input.lending.marginLevel),
633
+ : toCanonical(input.lending.marginLevel),
626
634
  healthFactor:
627
635
  input.lending.healthFactor === undefined
628
636
  ? undefined
629
- : new BigNumber(input.lending.healthFactor),
637
+ : toCanonical(input.lending.healthFactor),
630
638
  ltv:
631
639
  input.lending.ltv === undefined
632
640
  ? undefined
633
- : new BigNumber(input.lending.ltv),
641
+ : toCanonical(input.lending.ltv),
634
642
  liquidationThreshold:
635
643
  input.lending.liquidationThreshold === undefined
636
644
  ? undefined
637
- : new BigNumber(input.lending.liquidationThreshold),
645
+ : toCanonical(input.lending.liquidationThreshold),
638
646
  totalCollateralUSD:
639
647
  input.lending.totalCollateralUSD === undefined
640
648
  ? undefined
641
- : new BigNumber(input.lending.totalCollateralUSD),
649
+ : toCanonical(input.lending.totalCollateralUSD),
642
650
  totalDebtUSD:
643
651
  input.lending.totalDebtUSD === undefined
644
652
  ? undefined
645
- : new BigNumber(input.lending.totalDebtUSD),
653
+ : toCanonical(input.lending.totalDebtUSD),
646
654
  }
647
655
  : previous?.lending,
648
656
  };
@@ -16,6 +16,7 @@ import type {
16
16
  } from "../client/context.ts";
17
17
  import { AcexError } from "../errors.ts";
18
18
  import { AsyncEventBus } from "../internal/async-event-bus.ts";
19
+ import { toCanonical } from "../internal/decimal.ts";
19
20
  import { matchesMarketFilter } from "../internal/filters.ts";
20
21
  import type {
21
22
  FundingRateSnapshot,
@@ -100,10 +101,6 @@ function floorToStep(value: BigNumber, step: BigNumber): BigNumber {
100
101
  return value.dividedToIntegerBy(step).multipliedBy(step);
101
102
  }
102
103
 
103
- function normalizeDecimalInput(value: BigNumber): string {
104
- return value.isFinite() ? value.toFixed() : value.toString();
105
- }
106
-
107
104
  export class MarketManagerImpl
108
105
  implements MarketManager, ManagerLifecycle, HealthReporter<MarketDataStatus>
109
106
  {
@@ -262,20 +259,36 @@ export class MarketManagerImpl
262
259
  const market = this.resolveLoadedMarket(input);
263
260
  const rawPrice = new BigNumber(input.price);
264
261
  const rawAmount = new BigNumber(input.amount);
265
- const price = floorToStep(rawPrice, market.priceStep);
266
- const amount = floorToStep(rawAmount, market.amountStep);
262
+ const priceStep = new BigNumber(market.priceStep);
263
+ const amountStep = new BigNumber(market.amountStep);
264
+ const minAmount =
265
+ market.minAmount === undefined
266
+ ? undefined
267
+ : new BigNumber(market.minAmount);
268
+ const minNotional =
269
+ market.minNotional === undefined
270
+ ? undefined
271
+ : new BigNumber(market.minNotional);
272
+ const price = floorToStep(rawPrice, priceStep);
273
+ const amount = floorToStep(rawAmount, amountStep);
274
+
275
+ // normalizeOrderInput rejects non-finite input gracefully (see the
276
+ // isFinite checks below), so its echoed numeric fields fall back to the
277
+ // raw string instead of throwing the way toCanonical now does.
278
+ const echoDecimal = (value: BigNumber): string =>
279
+ value.isFinite() ? toCanonical(value) : value.toString();
267
280
 
268
281
  const normalized: NormalizedOrderInput = {
269
- price: normalizeDecimalInput(price),
270
- amount: normalizeDecimalInput(amount),
271
- rawPrice: normalizeDecimalInput(rawPrice),
272
- rawAmount: normalizeDecimalInput(rawAmount),
282
+ price: echoDecimal(price),
283
+ amount: echoDecimal(amount),
284
+ rawPrice: echoDecimal(rawPrice),
285
+ rawAmount: echoDecimal(rawAmount),
273
286
  adjusted: !price.isEqualTo(rawPrice) || !amount.isEqualTo(rawAmount),
274
287
  accepted: true,
275
- priceStep: market.priceStep.toFixed(),
276
- amountStep: market.amountStep.toFixed(),
277
- minAmount: market.minAmount?.toFixed(),
278
- minNotional: market.minNotional?.toFixed(),
288
+ priceStep: market.priceStep,
289
+ amountStep: market.amountStep,
290
+ minAmount: market.minAmount,
291
+ minNotional: market.minNotional,
279
292
  };
280
293
 
281
294
  if (!price.isFinite() || price.isLessThanOrEqualTo(0)) {
@@ -294,7 +307,7 @@ export class MarketManagerImpl
294
307
  };
295
308
  }
296
309
 
297
- if (market.minAmount && amount.isLessThan(market.minAmount)) {
310
+ if (minAmount && amount.isLessThan(minAmount)) {
298
311
  return {
299
312
  ...normalized,
300
313
  accepted: false,
@@ -302,9 +315,9 @@ export class MarketManagerImpl
302
315
  };
303
316
  }
304
317
 
305
- if (market.minNotional) {
318
+ if (minNotional) {
306
319
  const notional = amount.multipliedBy(price);
307
- if (notional.isLessThan(market.minNotional)) {
320
+ if (notional.isLessThan(minNotional)) {
308
321
  return {
309
322
  ...normalized,
310
323
  accepted: false,
@@ -774,10 +787,10 @@ export class MarketManagerImpl
774
787
  return {
775
788
  venue,
776
789
  symbol,
777
- bidPrice: new BigNumber(input.bidPrice),
778
- bidSize: new BigNumber(input.bidSize),
779
- askPrice: new BigNumber(input.askPrice),
780
- askSize: new BigNumber(input.askSize),
790
+ bidPrice: toCanonical(input.bidPrice),
791
+ bidSize: toCanonical(input.bidSize),
792
+ askPrice: toCanonical(input.askPrice),
793
+ askSize: toCanonical(input.askSize),
781
794
  exchangeTs: input.exchangeTs,
782
795
  receivedAt: input.receivedAt,
783
796
  updatedAt: input.receivedAt,
@@ -801,12 +814,10 @@ export class MarketManagerImpl
801
814
  return {
802
815
  venue,
803
816
  symbol,
804
- fundingRate: new BigNumber(input.fundingRate),
817
+ fundingRate: toCanonical(input.fundingRate),
805
818
  nextFundingTime: input.nextFundingTime,
806
- markPrice: input.markPrice ? new BigNumber(input.markPrice) : undefined,
807
- indexPrice: input.indexPrice
808
- ? new BigNumber(input.indexPrice)
809
- : undefined,
819
+ markPrice: input.markPrice ? toCanonical(input.markPrice) : undefined,
820
+ indexPrice: input.indexPrice ? toCanonical(input.indexPrice) : undefined,
810
821
  exchangeTs: input.exchangeTs,
811
822
  receivedAt: input.receivedAt,
812
823
  updatedAt: input.receivedAt,
@@ -10,6 +10,7 @@ import type {
10
10
  } from "../client/context.ts";
11
11
  import { AcexError } from "../errors.ts";
12
12
  import { AsyncEventBus } from "../internal/async-event-bus.ts";
13
+ import { toCanonical } from "../internal/decimal.ts";
13
14
  import { matchesOrderFilter } from "../internal/filters.ts";
14
15
  import type {
15
16
  CancelAllOrdersInput,
@@ -546,22 +547,20 @@ export class OrderManagerImpl
546
547
  type: input.type,
547
548
  status: input.status,
548
549
  price:
549
- input.price === undefined
550
- ? previous?.price
551
- : new BigNumber(input.price),
550
+ input.price === undefined ? previous?.price : toCanonical(input.price),
552
551
  triggerPrice:
553
552
  input.triggerPrice === undefined
554
553
  ? previous?.triggerPrice
555
- : new BigNumber(input.triggerPrice),
556
- amount,
557
- filled,
558
- remaining,
554
+ : toCanonical(input.triggerPrice),
555
+ amount: toCanonical(amount),
556
+ filled: toCanonical(filled),
557
+ remaining: toCanonical(remaining),
559
558
  reduceOnly: input.reduceOnly ?? previous?.reduceOnly,
560
559
  positionSide: input.positionSide ?? previous?.positionSide,
561
560
  avgFillPrice:
562
561
  input.avgFillPrice === undefined
563
562
  ? previous?.avgFillPrice
564
- : new BigNumber(input.avgFillPrice),
563
+ : toCanonical(input.avgFillPrice),
565
564
  exchangeTs: input.exchangeTs,
566
565
  receivedAt: input.receivedAt,
567
566
  updatedAt: input.receivedAt,
@@ -1,4 +1,3 @@
1
- import type BigNumber from "bignumber.js";
2
1
  import type {
3
2
  PrivateRuntimeReason,
4
3
  PrivateRuntimeStatus,
@@ -52,9 +51,9 @@ export interface BalanceSnapshot {
52
51
  accountId: string;
53
52
  venue: Venue;
54
53
  asset: string;
55
- free: BigNumber;
56
- used: BigNumber;
57
- total: BigNumber;
54
+ free: string;
55
+ used: string;
56
+ total: string;
58
57
  exchangeTs?: number;
59
58
  receivedAt: number;
60
59
  updatedAt: number;
@@ -63,12 +62,12 @@ export interface BalanceSnapshot {
63
62
  }
64
63
 
65
64
  export interface LendingBalanceFacet {
66
- supplied: BigNumber;
67
- borrowed: BigNumber;
68
- interest: BigNumber;
69
- netAsset: BigNumber;
70
- supplyAPY?: BigNumber;
71
- borrowAPY?: BigNumber;
65
+ supplied: string;
66
+ borrowed: string;
67
+ interest: string;
68
+ netAsset: string;
69
+ supplyAPY?: string;
70
+ borrowAPY?: string;
72
71
  }
73
72
 
74
73
  export interface PositionSnapshot {
@@ -76,12 +75,12 @@ export interface PositionSnapshot {
76
75
  venue: Venue;
77
76
  symbol: string;
78
77
  side: PositionSide;
79
- size: BigNumber;
80
- entryPrice?: BigNumber;
81
- markPrice?: BigNumber;
82
- unrealizedPnl?: BigNumber;
83
- leverage?: BigNumber;
84
- liquidationPrice?: BigNumber;
78
+ size: string;
79
+ entryPrice?: string;
80
+ markPrice?: string;
81
+ unrealizedPnl?: string;
82
+ leverage?: string;
83
+ liquidationPrice?: string;
85
84
  exchangeTs?: number;
86
85
  receivedAt: number;
87
86
  updatedAt: number;
@@ -91,12 +90,12 @@ export interface PositionSnapshot {
91
90
  export interface RiskSnapshot {
92
91
  accountId: string;
93
92
  venue: Venue;
94
- netEquity?: BigNumber;
95
- riskEquity?: BigNumber;
96
- riskRatio?: BigNumber;
97
- riskLeverage?: BigNumber;
98
- initialMargin?: BigNumber;
99
- maintenanceMargin?: BigNumber;
93
+ netEquity?: string;
94
+ riskEquity?: string;
95
+ riskRatio?: string;
96
+ riskLeverage?: string;
97
+ initialMargin?: string;
98
+ maintenanceMargin?: string;
100
99
  exchangeTs?: number;
101
100
  receivedAt: number;
102
101
  updatedAt: number;
@@ -105,12 +104,12 @@ export interface RiskSnapshot {
105
104
  }
106
105
 
107
106
  export interface LendingRiskFacet {
108
- marginLevel?: BigNumber;
109
- healthFactor?: BigNumber;
110
- ltv?: BigNumber;
111
- liquidationThreshold?: BigNumber;
112
- totalCollateralUSD?: BigNumber;
113
- totalDebtUSD?: BigNumber;
107
+ marginLevel?: string;
108
+ healthFactor?: string;
109
+ ltv?: string;
110
+ liquidationThreshold?: string;
111
+ totalCollateralUSD?: string;
112
+ totalDebtUSD?: string;
114
113
  }
115
114
 
116
115
  export interface AccountSnapshot {
@@ -15,13 +15,13 @@ export interface MarketDefinition {
15
15
  contract: boolean;
16
16
  linear?: boolean;
17
17
  inverse?: boolean;
18
- contractSize?: BigNumber;
18
+ contractSize?: string;
19
19
  pricePrecision: number;
20
20
  amountPrecision: number;
21
- priceStep: BigNumber;
22
- amountStep: BigNumber;
23
- minAmount?: BigNumber;
24
- minNotional?: BigNumber;
21
+ priceStep: string;
22
+ amountStep: string;
23
+ minAmount?: string;
24
+ minNotional?: string;
25
25
  expiry?: number;
26
26
  raw: Record<string, unknown>;
27
27
  }
@@ -92,10 +92,10 @@ export interface MarketEventFilter {
92
92
  export interface L1Book {
93
93
  venue: Venue;
94
94
  symbol: string;
95
- bidPrice: BigNumber;
96
- bidSize: BigNumber;
97
- askPrice: BigNumber;
98
- askSize: BigNumber;
95
+ bidPrice: string;
96
+ bidSize: string;
97
+ askPrice: string;
98
+ askSize: string;
99
99
  exchangeTs?: number;
100
100
  receivedAt: number;
101
101
  updatedAt: number;
@@ -106,10 +106,10 @@ export interface L1Book {
106
106
  export interface FundingRateSnapshot {
107
107
  venue: Venue;
108
108
  symbol: string;
109
- fundingRate: BigNumber;
109
+ fundingRate: string;
110
110
  nextFundingTime?: number;
111
- markPrice?: BigNumber;
112
- indexPrice?: BigNumber;
111
+ markPrice?: string;
112
+ indexPrice?: string;
113
113
  exchangeTs?: number;
114
114
  receivedAt: number;
115
115
  updatedAt: number;
@@ -1,4 +1,3 @@
1
- import type BigNumber from "bignumber.js";
2
1
  import type { PositionSide } from "./account.ts";
3
2
  import type {
4
3
  PrivateRuntimeReason,
@@ -102,14 +101,14 @@ export interface OrderSnapshot {
102
101
  side: OrderSide;
103
102
  type: string;
104
103
  status: OrderStatus;
105
- price?: BigNumber;
106
- triggerPrice?: BigNumber;
107
- amount: BigNumber;
108
- filled: BigNumber;
109
- remaining?: BigNumber;
104
+ price?: string;
105
+ triggerPrice?: string;
106
+ amount: string;
107
+ filled: string;
108
+ remaining?: string;
110
109
  reduceOnly?: boolean;
111
110
  positionSide?: PositionSide;
112
- avgFillPrice?: BigNumber;
111
+ avgFillPrice?: string;
113
112
  exchangeTs?: number;
114
113
  receivedAt: number;
115
114
  updatedAt: number;