@pear-protocol/utils 0.6.0 → 0.8.0

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.
@@ -1,5 +1,6 @@
1
1
  import type { InstrumentId } from '@pear-protocol/types';
2
2
  import BigNumber from 'bignumber.js';
3
+ import type { Fill } from '../fills/fill.types';
3
4
  export type AssetUnrealizedPnL = {
4
5
  id: InstrumentId;
5
6
  signedQuantity: BigNumber;
@@ -45,3 +46,4 @@ export type AssetRealizedPnL = {
45
46
  pearFees: BigNumber;
46
47
  closures: AssetClosure[];
47
48
  };
49
+ export type DeployedCapitalFill = Pick<Fill, 'symbol' | 'side' | 'price' | 'quantity'>;
@@ -1,7 +1,7 @@
1
1
  import type { InstrumentId } from '@pear-protocol/types';
2
2
  import BigNumber from 'bignumber.js';
3
3
  import type { Fill } from '../fills/fill.types';
4
- import type { AssetRealizedPnL, AssetUnrealizedPnL } from './asset.types';
4
+ import type { AssetRealizedPnL, AssetUnrealizedPnL, DeployedCapitalFill } from './asset.types';
5
5
  type ExposureMap = Record<InstrumentId, string>;
6
6
  type PriceMap = Record<InstrumentId, string>;
7
7
  /**
@@ -43,4 +43,44 @@ export declare function computeAssetUnrealizedPnLs(exposureMap: ExposureMap, pri
43
43
  * Formula: Σ(realizedPnL)
44
44
  */
45
45
  export declare function computeAssetRealizedPnLs(fills: Fill[]): AssetRealizedPnL[];
46
+ /**
47
+ * The most cash the position's selected legs had committed at one time.
48
+ *
49
+ * Cash, not market value: each opening fill commits what it actually paid, at its own
50
+ * execution price, and each closing fill releases the share of that commitment the quantity
51
+ * it closed was holding. No price beyond the fills' own is read, which matters because there
52
+ * is none to read — this system keeps no historical price series, so a market-value
53
+ * denominator could only ever be sampled at fills anyway.
54
+ *
55
+ * Sampling it that way was the earlier rule, and it failed in the direction that flatters.
56
+ * Revaluing a whole leg at each fill's price lets the denominator fall BELOW the money the
57
+ * trader put in: buy 10 at 200 then 10 more at 100 and the leg's worth never exceeds 2,000
58
+ * though 3,000 went in, so the return comes out 1.5x too large. Averaging down is ordinary
59
+ * trading, and a public board must not pay for it. Counting cash cannot do this — the
60
+ * denominator only ever rises when money goes in.
61
+ *
62
+ * Walked from the fills rather than read off the size stamped at the open, because a
63
+ * position is routinely scaled up long after it opens. Dividing by the opening size measures
64
+ * a return against capital the trader has since multiplied, and overstates it by exactly
65
+ * that factor — a position opened at 73 and grown to 33,499 reported 774% for a trade that
66
+ * made 1.7%.
67
+ *
68
+ * The peak rather than the running total of everything opened, so a position that reduces
69
+ * and rebuilds is charged for the capital it committed, not for the same capital counted
70
+ * twice. Unsigned per leg, because a pair trade's short leg is size the trader put at risk,
71
+ * not a credit against the long.
72
+ *
73
+ * Every loaded fill moves the commitment, an external one included: exposure has no per-fill
74
+ * provenance, so dropping a venue-merged fill would misstate what the position tied up rather
75
+ * than narrow the measure. Read in the chronological order the reader guarantees — unlike
76
+ * the per-asset realized walk, this total spans every leg at once, so a leg out of sequence
77
+ * misstates the basket in either direction: it can show two legs held together that never
78
+ * were, or miss a pairing that was.
79
+ *
80
+ * Fills sharing one timestamp are separated by symbol, which is alphabetical rather than
81
+ * causal: a leg swapped for another in the same instant may be seen committed alongside it.
82
+ * That only ever adds to the peak, so the denominator errs large and the return it produces
83
+ * errs small — the safe direction for a public board.
84
+ */
85
+ export declare function computeDeployedCapital(fills: DeployedCapitalFill[], assets: Set<string> | undefined): BigNumber;
46
86
  export {};
@@ -1,2 +1,2 @@
1
- export type { AssetClosure, AssetRealizedPnL, AssetUnrealizedPnL } from './asset.types';
1
+ export type { AssetClosure, AssetRealizedPnL, AssetUnrealizedPnL, DeployedCapitalFill } from './asset.types';
2
2
  export * from './compute';
@@ -20,26 +20,68 @@ export type MaxBasketSizeInput = {
20
20
  /** What the caller is requesting for the whole basket, before each leg's own venue max caps it. */
21
21
  requestedLeverage: number;
22
22
  };
23
+ /** Same shape as `MaxBasketSizeLeg`, but leverage is requested per leg instead of once for the basket. */
24
+ export type MaxBasketSizePerAssetLeverageLeg = MaxBasketSizeLeg & {
25
+ /** What the caller is requesting for THIS leg, before the venue max caps it. */
26
+ requestedLeverage: number;
27
+ };
28
+ export type MaxBasketSizePerAssetLeverageInput = {
29
+ legs: MaxBasketSizePerAssetLeverageLeg[];
30
+ };
31
+ /**
32
+ * Either shape a caller can size a basket from, tagged by how leverage is requested —
33
+ * once for the whole basket, or once per leg. `sizeBasketByLeverageMode` switches on it.
34
+ */
35
+ export type MaxBasketSizeRequest = ({
36
+ leverageMode: 'shared';
37
+ } & MaxBasketSizeInput) | ({
38
+ leverageMode: 'perAsset';
39
+ } & MaxBasketSizePerAssetLeverageInput);
23
40
  export type MaxBasketSizeResult = {
24
41
  /**
25
42
  * The whole basket's max GROSS notional in USD — Σ leg notional, not per-side and not per-asset.
26
43
  * The basket is atomic, so this is one ceiling for the entire structure, not a per-leg maximum.
27
- * Null when the caller could not supply an available balance, or a leg names an asset the
28
- * caller's max-leverage map does not list.
44
+ * Null when a leg names an asset the caller's instrument catalog does not list, or names a quote
45
+ * currency the caller's `balanceByQuote` map does not fund — either gap leaves the basket unsized.
29
46
  */
30
47
  maxNotional: string | null;
31
48
  /**
32
- * The margin `maxNotional` spends — always the whole `budget`/`availableBalance` the caller
33
- * supplied, since that is exactly the point at which the basket stops growing. Stated explicitly
34
- * rather than left for the caller to infer, and `null` on the same terms as `maxNotional`.
49
+ * The margin `maxNotional` spends, summed across every pool it draws from. For a single budget
50
+ * (`computeMaxBasketSize`) this is always the whole budget supplied, since that is exactly the
51
+ * point at which the basket stops growing. Across several quote-currency pools
52
+ * (`computeMultiQuoteBasketSize`) it is the total actually drawn — the full balance of whichever
53
+ * pool is the tightest constraint, but not necessarily the others. `null` on the same terms as
54
+ * `maxNotional`.
35
55
  */
36
56
  marginRequired: string | null;
57
+ /**
58
+ * `marginRequired` broken out per leg, in the caller's own leg order — `null` when a leg carries
59
+ * no identity to report it under (`computeMaxBasketSize`/`computeMultiQuoteBasketSize` called
60
+ * directly on anonymous `CappedBasketLeg`s), never partial: every leg reports or none does.
61
+ */
62
+ legs: LegMarginRequired[] | null;
63
+ /**
64
+ * `marginRequired` grouped by quote currency instead of by leg, e.g. `{ USDC: '20', USDT: '20' }`
65
+ * — how much of each currency the basket actually needs, not how much each asset draws. Two legs
66
+ * settling in the same currency fold into one entry here, unlike `legs`. Always `null` from
67
+ * `computeMaxBasketSize` — a single budget has no quote to group by.
68
+ */
69
+ marginRequiredByQuote: Record<string, string> | null;
70
+ };
71
+ /** One leg's own share of `marginRequired`, identified so the caller can show it per asset. */
72
+ export type LegMarginRequired = {
73
+ asset: InstrumentId;
74
+ /** The leverage this leg was actually granted — after the venue-max cap, not the raw request. */
75
+ effectiveLeverage: string;
76
+ marginRequired: string;
37
77
  };
38
78
  /** One basket leg with its leverage already capped by the caller. */
39
79
  export type CappedBasketLeg = {
40
80
  /** Unsigned, in the caller's own scale — `computeMaxBasketSize` normalises by Σweight. */
41
81
  weight: number;
42
82
  effectiveLeverage: string;
83
+ /** Identifies this leg in `MaxBasketSizeResult.legs`. Omit to keep the leg anonymous. */
84
+ asset?: InstrumentId;
43
85
  };
44
86
  /** The one margin budget every leg funds out of. */
45
87
  export type MaxBasketSizeCalculation = {
@@ -47,10 +89,21 @@ export type MaxBasketSizeCalculation = {
47
89
  budget: string;
48
90
  legs: CappedBasketLeg[];
49
91
  };
50
- /** What `sizeSinglePoolBasket` needs beyond the legs: the account's balance and the leverage ceilings. */
51
- export type SinglePoolSizingContext = {
52
- /** The account's whole available margin, or `null` when the caller could not read one. */
53
- availableBalance: string | null;
54
- /** Off the core-sdk instrument catalog — only `id` and `leverage` are read. */
55
- instruments: Pick<HttpTypes.Instrument, 'id' | 'leverage'>[];
92
+ /** One capped leg, tagged with the quote-currency pool its margin draws from. */
93
+ export type CappedBasketLegWithQuote = CappedBasketLeg & {
94
+ /** The instrument's quote asset, e.g. `"USDC"` — the key into `MultiQuoteBasketSizeCalculation.balanceByQuote`. */
95
+ quote: string;
96
+ };
97
+ /** The margin budgets a basket whose legs settle in more than one quote currency funds out of. */
98
+ export type MultiQuoteBasketSizeCalculation = {
99
+ /** Available margin per quote currency, e.g. `{ USDC: '500', USDT: '300' }`. */
100
+ balanceByQuote: Record<string, string>;
101
+ legs: CappedBasketLegWithQuote[];
102
+ };
103
+ /** What the sizing functions need beyond the legs: balance per quote pool, and the leverage ceilings. */
104
+ export type BasketSizingContext = {
105
+ /** Available margin per quote currency. A leg whose instrument quotes in a currency absent here can't be sized. */
106
+ balanceByQuote: Record<string, string>;
107
+ /** Off the core-sdk instrument catalog — only `id`, `leverage`, and `quote` are read. */
108
+ instruments: Pick<HttpTypes.Instrument, 'id' | 'leverage' | 'quote'>[];
56
109
  };
@@ -1,4 +1,4 @@
1
- import type { MaxBasketSizeCalculation, MaxBasketSizeInput, MaxBasketSizeResult, SinglePoolSizingContext } from './basket.types';
1
+ import type { BasketSizingContext, MaxBasketSizeCalculation, MaxBasketSizeInput, MaxBasketSizePerAssetLeverageInput, MaxBasketSizeRequest, MaxBasketSizeResult, MultiQuoteBasketSizeCalculation } from './basket.types';
2
2
  /**
3
3
  * The largest gross notional this basket can reach while every leg stays funded at its weight.
4
4
  *
@@ -8,11 +8,33 @@ import type { MaxBasketSizeCalculation, MaxBasketSizeInput, MaxBasketSizeResult,
8
8
  */
9
9
  export declare function computeMaxBasketSize(input: MaxBasketSizeCalculation): MaxBasketSizeResult;
10
10
  /**
11
- * Sizes a basket that funds every leg out of one account-wide balance and caps leverage at nothing
12
- * but the caller-supplied max: `effectiveLeverage = min(requested, catalogMax)`.
11
+ * The largest gross notional this basket can reach when its legs settle in more than one quote
12
+ * currency. Each leg's margin draws from its own quote pool, and the pool that runs out first caps
13
+ * the whole basket — the same "tightest constraint wins" logic `computeMaxBasketSize` applies to
14
+ * leverage, one level up. A basket whose legs all share one quote reduces to exactly one pool, so
15
+ * this is a strict superset of `computeMaxBasketSize`'s single-budget math.
13
16
  *
14
- * A leg naming an asset the caller's catalog does not list leaves its ceiling unknown, and sizing
15
- * against the request alone would overstate the basket — so one unknown leg (or no available
16
- * balance at all) reports no size rather than a wrong one.
17
+ * Takes the caller's figures as given — a malformed balance or leverage is the caller's own
18
+ * responsibility to keep clean, not something this function guards against.
17
19
  */
18
- export declare function sizeSinglePoolBasket(input: MaxBasketSizeInput, context: SinglePoolSizingContext): MaxBasketSizeResult;
20
+ export declare function computeMultiQuoteBasketSize(input: MultiQuoteBasketSizeCalculation): MaxBasketSizeResult;
21
+ /**
22
+ * Sizes a basket that caps leverage at nothing but the caller-supplied max —
23
+ * `effectiveLeverage = min(requested, catalogMax)` — and funds each leg out of its own instrument's
24
+ * quote-currency pool.
25
+ *
26
+ * A leg naming an asset the caller's catalog does not list leaves its ceiling and pool unknown, and
27
+ * a leg naming a quote the caller's balance map does not list leaves its pool's budget unknown —
28
+ * either gap reports no size rather than a wrong one.
29
+ */
30
+ export declare function sizeBasket(input: MaxBasketSizeInput, context: BasketSizingContext): MaxBasketSizeResult;
31
+ /**
32
+ * Sizes a basket the same way `sizeBasket` does, but each leg requests its own leverage
33
+ * instead of the whole basket sharing one figure — still capped at that leg's own venue max.
34
+ */
35
+ export declare function sizeBasketPerAssetLeverage(input: MaxBasketSizePerAssetLeverageInput, context: BasketSizingContext): MaxBasketSizeResult;
36
+ /**
37
+ * Single entry point for sizing a basket regardless of how the caller requests
38
+ * leverage — dispatches on `leverageMode` to the shared-basket or per-asset implementation.
39
+ */
40
+ export declare function sizeBasketByLeverageMode(request: MaxBasketSizeRequest, context: BasketSizingContext): MaxBasketSizeResult;
package/dist/index.js CHANGED
@@ -239,6 +239,35 @@ function computeAssetRealizedPnLs(fills) {
239
239
  return result;
240
240
  }
241
241
  __name(computeAssetRealizedPnLs, "computeAssetRealizedPnLs");
242
+ function computeDeployedCapital(fills, assets) {
243
+ const legs = /* @__PURE__ */ new Map();
244
+ let committed = ZERO;
245
+ let peak = ZERO;
246
+ for (const fill of fills) {
247
+ if (assets && !assets.has(fill.symbol.toUpperCase())) {
248
+ continue;
249
+ }
250
+ const leg = legs.get(fill.symbol) ?? {
251
+ quantity: ZERO,
252
+ basis: ZERO
253
+ };
254
+ const delta = signedBySide(fill.quantity, fill.side);
255
+ const closed = closesAgainstHolding(leg.quantity, delta);
256
+ const opened = subtract(abs(delta), closed);
257
+ const released = isZero(leg.quantity) ? ZERO : divide(multiply(leg.basis, closed), abs(leg.quantity));
258
+ const basis = add(subtract(leg.basis, released), multiply(opened, fill.price));
259
+ committed = add(subtract(committed, leg.basis), basis);
260
+ legs.set(fill.symbol, {
261
+ quantity: add(leg.quantity, delta),
262
+ basis
263
+ });
264
+ if (isGreaterThan(committed, peak)) {
265
+ peak = committed;
266
+ }
267
+ }
268
+ return peak;
269
+ }
270
+ __name(computeDeployedCapital, "computeDeployedCapital");
242
271
  function walkAssetFills(fills) {
243
272
  let entryPrice = ZERO;
244
273
  let positionSize = ZERO;
@@ -297,6 +326,13 @@ function walkAssetFills(fills) {
297
326
  };
298
327
  }
299
328
  __name(walkAssetFills, "walkAssetFills");
329
+ function closesAgainstHolding(held, delta) {
330
+ if (isZero(held) || isPositive(held) === isPositive(delta)) {
331
+ return ZERO;
332
+ }
333
+ return min(abs(delta), abs(held));
334
+ }
335
+ __name(closesAgainstHolding, "closesAgainstHolding");
300
336
 
301
337
  // src/basket/compute.ts
302
338
  function computeBasketWeightedRatioV1(basket, priceMap) {
@@ -335,39 +371,109 @@ function computeMaxBasketSize(input) {
335
371
  if (isZero(weightSum)) {
336
372
  return unsizedResult();
337
373
  }
338
- const shares = input.legs.map((leg) => toLegShare(leg, weightSum));
339
- const size = divide(input.budget, marginPerUnitNotional(shares));
374
+ const demands = input.legs.map((leg) => toLegDemand(leg, weightSum));
375
+ const size = divide(input.budget, sumDemand(demands));
340
376
  return {
341
377
  maxNotional: size.toFixed(),
342
- marginRequired: input.budget
378
+ marginRequired: input.budget,
379
+ legs: legMarginBreakdown(demands, size),
380
+ marginRequiredByQuote: null
343
381
  };
344
382
  }
345
383
  __name(computeMaxBasketSize, "computeMaxBasketSize");
346
- function sizeSinglePoolBasket(input, context) {
347
- if (context.availableBalance === null) {
384
+ function computeMultiQuoteBasketSize(input) {
385
+ const weightSum = sumWeights(input.legs);
386
+ if (isZero(weightSum)) {
387
+ return unsizedResult();
388
+ }
389
+ const demands = input.legs.map((leg) => toLegDemand(leg, weightSum));
390
+ const demandByQuote = demandPerQuote(demands);
391
+ let binding;
392
+ for (const [quote, demand] of demandByQuote) {
393
+ const balance = input.balanceByQuote[quote];
394
+ if (balance === void 0) {
395
+ return unsizedResult();
396
+ }
397
+ if (isZero(demand)) {
398
+ continue;
399
+ }
400
+ const notional = divide(balance, demand);
401
+ if (binding === void 0 || isLessThan(notional, binding.maxNotional)) {
402
+ binding = {
403
+ quote,
404
+ balance,
405
+ maxNotional: notional
406
+ };
407
+ }
408
+ }
409
+ if (binding === void 0) {
410
+ return unsizedResult();
411
+ }
412
+ const marginByQuote = marginRequiredByQuote(demandByQuote, binding);
413
+ const marginRequired = Object.values(marginByQuote).reduce((total, drawn) => add(total, drawn), ZERO);
414
+ return {
415
+ maxNotional: binding.maxNotional.toFixed(),
416
+ marginRequired: marginRequired.toFixed(),
417
+ legs: legMarginBreakdown(demands, binding.maxNotional),
418
+ marginRequiredByQuote: marginByQuote
419
+ };
420
+ }
421
+ __name(computeMultiQuoteBasketSize, "computeMultiQuoteBasketSize");
422
+ function sizeBasket(input, context) {
423
+ const legs = capLegsAgainstCatalog(input.legs.map((leg) => ({
424
+ ...leg,
425
+ requestedLeverage: input.requestedLeverage
426
+ })), context.instruments);
427
+ if (legs === null) {
348
428
  return unsizedResult();
349
429
  }
350
- const maxLeverageById = new Map(context.instruments.map((instrument) => [
430
+ return computeMultiQuoteBasketSize({
431
+ balanceByQuote: context.balanceByQuote,
432
+ legs
433
+ });
434
+ }
435
+ __name(sizeBasket, "sizeBasket");
436
+ function sizeBasketPerAssetLeverage(input, context) {
437
+ const legs = capLegsAgainstCatalog(input.legs, context.instruments);
438
+ if (legs === null) {
439
+ return unsizedResult();
440
+ }
441
+ return computeMultiQuoteBasketSize({
442
+ balanceByQuote: context.balanceByQuote,
443
+ legs
444
+ });
445
+ }
446
+ __name(sizeBasketPerAssetLeverage, "sizeBasketPerAssetLeverage");
447
+ function sizeBasketByLeverageMode(request, context) {
448
+ switch (request.leverageMode) {
449
+ case "shared":
450
+ return sizeBasket(request, context);
451
+ case "perAsset":
452
+ return sizeBasketPerAssetLeverage(request, context);
453
+ }
454
+ }
455
+ __name(sizeBasketByLeverageMode, "sizeBasketByLeverageMode");
456
+ function capLegsAgainstCatalog(legs, instruments) {
457
+ const instrumentById = new Map(instruments.map((instrument) => [
351
458
  instrument.id,
352
- instrument.leverage
459
+ instrument
353
460
  ]));
354
461
  const capped = [];
355
- for (const leg of input.legs) {
356
- const maxLeverage = maxLeverageById.get(leg.asset);
357
- if (maxLeverage === void 0) {
358
- return unsizedResult();
462
+ for (const leg of legs) {
463
+ const instrument = instrumentById.get(leg.asset);
464
+ if (instrument === void 0) {
465
+ return null;
359
466
  }
360
467
  capped.push({
468
+ asset: leg.asset,
361
469
  weight: leg.weight,
362
- effectiveLeverage: cappedLeverage(input.requestedLeverage, maxLeverage)
470
+ effectiveLeverage: cappedLeverage(leg.requestedLeverage, instrument.leverage),
471
+ quote: instrument.quote
363
472
  });
364
473
  }
365
- return computeMaxBasketSize({
366
- budget: context.availableBalance,
367
- legs: capped
368
- });
474
+ return capped;
369
475
  }
370
- __name(sizeSinglePoolBasket, "sizeSinglePoolBasket");
476
+ __name(capLegsAgainstCatalog, "capLegsAgainstCatalog");
371
477
  function cappedLeverage(requested, maxLeverage) {
372
478
  const granted = min(String(requested), String(maxLeverage));
373
479
  return isFiniteDecimal(granted) && granted.isGreaterThan(0) ? granted.toFixed() : "1";
@@ -384,25 +490,61 @@ __name(sumWeights, "sumWeights");
384
490
  function unsizedResult() {
385
491
  return {
386
492
  maxNotional: null,
387
- marginRequired: null
493
+ marginRequired: null,
494
+ legs: null,
495
+ marginRequiredByQuote: null
388
496
  };
389
497
  }
390
498
  __name(unsizedResult, "unsizedResult");
391
- function toLegShare(leg, weightSum) {
499
+ function toLegDemand(leg, weightSum) {
500
+ const share = divide(String(leg.weight), weightSum);
501
+ const marginFraction = divide("1", leg.effectiveLeverage);
392
502
  return {
393
- share: divide(String(leg.weight), weightSum),
394
- imr: divide("1", leg.effectiveLeverage)
503
+ leg,
504
+ demand: multiply(share, marginFraction)
395
505
  };
396
506
  }
397
- __name(toLegShare, "toLegShare");
398
- function marginPerUnitNotional(shares) {
399
- let demand = ZERO;
400
- for (const leg of shares) {
401
- demand = add(demand, multiply(leg.share, leg.imr));
507
+ __name(toLegDemand, "toLegDemand");
508
+ function legMarginBreakdown(demands, maxNotional) {
509
+ const breakdown = [];
510
+ for (const { leg, demand } of demands) {
511
+ if (leg.asset === void 0) {
512
+ return null;
513
+ }
514
+ breakdown.push({
515
+ asset: leg.asset,
516
+ effectiveLeverage: leg.effectiveLeverage,
517
+ marginRequired: multiply(maxNotional, demand).toFixed()
518
+ });
519
+ }
520
+ return breakdown;
521
+ }
522
+ __name(legMarginBreakdown, "legMarginBreakdown");
523
+ function sumDemand(demands) {
524
+ let total = ZERO;
525
+ for (const { demand } of demands) {
526
+ total = add(total, demand);
527
+ }
528
+ return total;
529
+ }
530
+ __name(sumDemand, "sumDemand");
531
+ function demandPerQuote(demands) {
532
+ const demandByQuote = /* @__PURE__ */ new Map();
533
+ for (const { leg, demand } of demands) {
534
+ const current = demandByQuote.get(leg.quote) ?? ZERO;
535
+ demandByQuote.set(leg.quote, add(current, demand));
536
+ }
537
+ return demandByQuote;
538
+ }
539
+ __name(demandPerQuote, "demandPerQuote");
540
+ function marginRequiredByQuote(demandByQuote, binding) {
541
+ const marginByQuote = {};
542
+ for (const [quote, demand] of demandByQuote) {
543
+ marginByQuote[quote] = quote === binding.quote ? parse(binding.balance).toFixed() : multiply(binding.maxNotional, demand).toFixed();
402
544
  }
403
- return demand;
545
+ return marginByQuote;
404
546
  }
405
- __name(marginPerUnitNotional, "marginPerUnitNotional");
547
+ __name(marginRequiredByQuote, "marginRequiredByQuote");
406
548
  function contractsToBase(contracts, contractSize) {
407
549
  return new BigNumber7(contracts).times(contractSize);
408
550
  }
@@ -2210,4 +2352,4 @@ function takeVerifier(handoffId, storage) {
2210
2352
  }
2211
2353
  __name(takeVerifier, "takeVerifier");
2212
2354
 
2213
- export { BIPS, ZERO, abs, add, aggregateRealizedPositionState, baseToContracts, buildApplicables, compareValue, computeAssetEntryNotional, computeAssetGrossRealizedPnL, computeAssetRealizedPnLs, computeAssetUndeterminedSizes, computeAssetUnrealizedPnL, computeAssetUnrealizedPnLs, computeBasketWeightedRatioV1, computeEntryPriceForAsset, computeMaxBasketSize, computePositionEntryPrices, computeRealizedPnlBySymbol, computeRealizedPnlFromFills, computeRealizedPositionState, computeSyncPayload, computeUnrealizedPositionState, computeUnrealizedPositionStateFromEntryPrices, configureProxy, contractsToBase, countDecimals, deriveBasketKey, divide, exponentiate, finishXHandoff, generateDeterministicPositionKey, isEqualTo, isFiniteDecimal, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual, isNegative, isPositive, isZero, min, multiply, negate, parse, precisePrice, preciseQuantity, proxyFetch, sideSign, sign, signed, signedBySide, sizeSinglePoolBasket, startXHandoff, stripXReturn, subtract, toDecimalString, validateLeverage, validateQuantity };
2355
+ export { BIPS, ZERO, abs, add, aggregateRealizedPositionState, baseToContracts, buildApplicables, compareValue, computeAssetEntryNotional, computeAssetGrossRealizedPnL, computeAssetRealizedPnLs, computeAssetUndeterminedSizes, computeAssetUnrealizedPnL, computeAssetUnrealizedPnLs, computeBasketWeightedRatioV1, computeDeployedCapital, computeEntryPriceForAsset, computeMaxBasketSize, computeMultiQuoteBasketSize, computePositionEntryPrices, computeRealizedPnlBySymbol, computeRealizedPnlFromFills, computeRealizedPositionState, computeSyncPayload, computeUnrealizedPositionState, computeUnrealizedPositionStateFromEntryPrices, configureProxy, contractsToBase, countDecimals, deriveBasketKey, divide, exponentiate, finishXHandoff, generateDeterministicPositionKey, isEqualTo, isFiniteDecimal, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual, isNegative, isPositive, isZero, min, multiply, negate, parse, precisePrice, preciseQuantity, proxyFetch, sideSign, sign, signed, signedBySide, sizeBasket, sizeBasketByLeverageMode, sizeBasketPerAssetLeverage, startXHandoff, stripXReturn, subtract, toDecimalString, validateLeverage, validateQuantity };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pear-protocol/utils",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Pear Protocol Utility functions",
5
5
  "private": false,
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@noble/hashes": "^1.3.2",
30
- "@pear-protocol/types": "^1.28.0",
30
+ "@pear-protocol/types": "^1.31.0",
31
31
  "@scure/base": "^2.3.0",
32
32
  "bignumber.js": "9.3.1"
33
33
  },