@pear-protocol/utils 0.2.0 → 0.4.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.
@@ -7,6 +7,10 @@ export type AssetUnrealizedPnL = {
7
7
  currentPrice: BigNumber;
8
8
  upnl: BigNumber;
9
9
  };
10
+ export type AssetRealization = {
11
+ fillId: string;
12
+ gross: BigNumber;
13
+ };
10
14
  export type AssetRealizedPnL = {
11
15
  id: InstrumentId;
12
16
  grossPnl: BigNumber;
@@ -15,4 +19,5 @@ export type AssetRealizedPnL = {
15
19
  totalFees: BigNumber;
16
20
  tradeFees: BigNumber;
17
21
  pearFees: BigNumber;
22
+ realizations: AssetRealization[];
18
23
  };
@@ -1,2 +1,2 @@
1
- export type { AssetRealizedPnL, AssetUnrealizedPnL } from './asset.types';
1
+ export type { AssetRealization, AssetRealizedPnL, AssetUnrealizedPnL } from './asset.types';
2
2
  export * from './compute';
package/dist/index.js CHANGED
@@ -185,7 +185,7 @@ function computeAssetRealizedPnLs(fills) {
185
185
  const tradeFees = assetFills.reduce((acc, fill) => acc.plus(new BigNumber9(fill.tradeFee ?? "0")), ZERO);
186
186
  const pearFees = assetFills.reduce((acc, fill) => acc.plus(new BigNumber9(fill.pearFee ?? "0")), ZERO);
187
187
  const totalFees = tradeFees.plus(pearFees);
188
- const { gross: grossPnl, undeterminedSize } = walkAssetFills(assetFills);
188
+ const { gross: grossPnl, undeterminedSize, realizations } = walkAssetFills(assetFills);
189
189
  const netPnl = grossPnl.minus(totalFees);
190
190
  result.push({
191
191
  id,
@@ -194,7 +194,8 @@ function computeAssetRealizedPnLs(fills) {
194
194
  undeterminedSize,
195
195
  totalFees,
196
196
  tradeFees,
197
- pearFees
197
+ pearFees,
198
+ realizations
198
199
  });
199
200
  }
200
201
  return result;
@@ -205,6 +206,7 @@ function walkAssetFills(fills) {
205
206
  let basisUnpriced = false;
206
207
  let gross = ZERO;
207
208
  let undeterminedSize = ZERO;
209
+ const realizations = [];
208
210
  for (const fill of fills) {
209
211
  const price = parse(fill.price);
210
212
  const quantity = parse(fill.quantity);
@@ -214,10 +216,10 @@ function walkAssetFills(fills) {
214
216
  const closedQty = min(positionSize.abs(), signedQuantity.abs());
215
217
  if (basisUnpriced || isZero(price)) {
216
218
  undeterminedSize = add(undeterminedSize, closedQty);
217
- } else if (isPositive(positionSize)) {
218
- gross = add(gross, multiply(closedQty, subtract(price, entryPrice)));
219
219
  } else {
220
- gross = add(gross, multiply(closedQty, subtract(entryPrice, price)));
220
+ const realized = isPositive(positionSize) ? multiply(closedQty, subtract(price, entryPrice)) : multiply(closedQty, subtract(entryPrice, price));
221
+ gross = add(gross, realized);
222
+ realizations.push({ fillId: fill.id, gross: realized });
221
223
  }
222
224
  }
223
225
  const isSameDirection = !isZero(positionSize) && isPositive(positionSize) === isPositive(signedQuantity);
@@ -231,7 +233,7 @@ function walkAssetFills(fills) {
231
233
  }
232
234
  positionSize = newPositionSize;
233
235
  }
234
- return { gross, undeterminedSize };
236
+ return { gross, undeterminedSize, realizations };
235
237
  }
236
238
  function computeBasketWeightedRatioV1(basket, priceMap) {
237
239
  let logSum = 0;
@@ -820,7 +822,10 @@ var WorkingBook = class _WorkingBook {
820
822
  const book = new _WorkingBook(tradeAccountId);
821
823
  for (const p of openPositions) {
822
824
  const position = {
823
- positionKey: book.keyFor(Object.keys(p.exposure)),
825
+ // Trust the position's own stored key — never recompute it from exposure.
826
+ // A partial fill on the original order leaves exposure short of the
827
+ // symbols the key was hashed from, so a recomputed key would never match.
828
+ positionKey: p.positionKey,
824
829
  exposure: Exposure.fromRecord(p.exposure),
825
830
  parts: [],
826
831
  closed: false,
@@ -1106,7 +1111,7 @@ function assignSyntheticsToPositions(args) {
1106
1111
  let target = positions.find((pos) => !pos.closed && pos.parts.some((part) => part.source.symbol === symbol));
1107
1112
  if (!target) {
1108
1113
  const existing = existingBySymbol.get(symbol);
1109
- const positionKey = existing ? keyOf(Object.keys(existing.exposure)) : keyOf([symbol]);
1114
+ const positionKey = existing ? existing.positionKey : keyOf([symbol]);
1110
1115
  target = positions.find((pos) => pos.positionKey === positionKey) ?? created.find((pos) => pos.positionKey === positionKey);
1111
1116
  if (!target) {
1112
1117
  target = existing ? (
@@ -1747,4 +1752,4 @@ function validateQuantity(quantity, price, precision) {
1747
1752
  return true;
1748
1753
  }
1749
1754
 
1750
- export { BIPS, ZERO, abs, add, baseToContracts, compareValue, computeAssetEntryNotional, computeAssetGrossRealizedPnL, computeAssetRealizedPnLs, computeAssetUndeterminedSizes, computeAssetUnrealizedPnL, computeAssetUnrealizedPnLs, computeBasketWeightedRatioV1, computeEntryPriceForAsset, computePositionEntryPrices, computeRealizedPnlBySymbol, computeRealizedPnlFromFills, computeRealizedPositionState, computeSyncPayload, computeUnrealizedPositionState, computeUnrealizedPositionStateFromEntryPrices, configureProxy, contractsToBase, countDecimals, divide, exponentiate, generateDeterministicPositionKey, isEqualTo, isFiniteDecimal, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual, isNegative, isPositive, isZero, min, multiply, negate, parse, precisePrice, preciseQuantity, proxyFetch, sideSign, sign, signed, signedBySide, subtract, toDecimalString, validateLeverage, validateQuantity };
1755
+ export { BIPS, ZERO, abs, add, baseToContracts, buildApplicables, compareValue, computeAssetEntryNotional, computeAssetGrossRealizedPnL, computeAssetRealizedPnLs, computeAssetUndeterminedSizes, computeAssetUnrealizedPnL, computeAssetUnrealizedPnLs, computeBasketWeightedRatioV1, computeEntryPriceForAsset, computePositionEntryPrices, computeRealizedPnlBySymbol, computeRealizedPnlFromFills, computeRealizedPositionState, computeSyncPayload, computeUnrealizedPositionState, computeUnrealizedPositionStateFromEntryPrices, configureProxy, contractsToBase, countDecimals, divide, exponentiate, generateDeterministicPositionKey, isEqualTo, isFiniteDecimal, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual, isNegative, isPositive, isZero, min, multiply, negate, parse, precisePrice, preciseQuantity, proxyFetch, sideSign, sign, signed, signedBySide, subtract, toDecimalString, validateLeverage, validateQuantity };
@@ -1,2 +1,3 @@
1
+ export { buildApplicables } from './applicables';
1
2
  export { computeSyncPayload } from './compute';
2
3
  export type { ComputeSyncPayloadArgs, ComputeSyncPayloadResult } from './types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pear-protocol/utils",
3
- "version": "0.2.0",
3
+ "version": "0.4.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.9.0",
30
+ "@pear-protocol/types": "^1.15.0",
31
31
  "bignumber.js": "9.3.1"
32
32
  },
33
33
  "devDependencies": {