@pear-protocol/utils 0.0.1 → 0.0.3

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,9 +1,12 @@
1
1
  import BigNumber from 'bignumber.js';
2
2
  import type { Fill } from './fill.types';
3
3
  /**
4
- * Compute weighted average entry price for a SINGLE INSTRUMENT.
4
+ * Cost-basis average entry price for a single instrument.
5
5
  *
6
- * - Handles flips automatically
7
- * - Uses ONLY active fills since last flip
6
+ * Processes fills chronologically in a single pass:
7
+ * - Increase position : weighted average of old + new
8
+ * - Reduce position : entry price unchanged
9
+ * - Close to zero : keep last entry price (for tracking purpose)
10
+ * - Flip sign : entry price resets to flip fill's price
8
11
  */
9
12
  export declare function computeEntryPriceForAsset(fills: Fill[]): BigNumber;
@@ -1,18 +1,24 @@
1
1
  import BigNumber from 'bignumber.js';
2
2
  import { ZERO } from '../math';
3
- import { getActiveFillsSinceLastFlip } from './flips';
4
3
 
5
4
  function computeEntryPriceForAsset(fills) {
6
- const activeFills = getActiveFillsSinceLastFlip(fills);
7
- let weightedSum = ZERO;
8
- let totalQty = ZERO;
9
- for (const fill of activeFills) {
5
+ let entryPrice = ZERO;
6
+ let positionSize = ZERO;
7
+ for (const fill of fills) {
10
8
  const price = new BigNumber(fill.price);
11
- const qty = new BigNumber(fill.quantity);
12
- weightedSum = weightedSum.plus(price.times(qty));
13
- totalQty = totalQty.plus(qty);
9
+ const quantity = new BigNumber(fill.quantity);
10
+ const signed = fill.side === "BUY" ? quantity : quantity.negated();
11
+ const newPositionSize = positionSize.plus(signed);
12
+ const isSameDirection = !positionSize.isZero() && positionSize.isPositive() === signed.isPositive();
13
+ const isFlip = !positionSize.isZero() && !newPositionSize.isZero() && newPositionSize.isPositive() !== positionSize.isPositive();
14
+ if (positionSize.isZero() || isFlip) {
15
+ entryPrice = price;
16
+ } else if (isSameDirection) {
17
+ entryPrice = entryPrice.times(positionSize.abs()).plus(price.times(quantity)).div(newPositionSize.abs());
18
+ }
19
+ positionSize = newPositionSize;
14
20
  }
15
- return totalQty.isZero() ? ZERO : weightedSum.div(totalQty);
21
+ return entryPrice;
16
22
  }
17
23
 
18
24
  export { computeEntryPriceForAsset };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pear-protocol/utils",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Pear Protocol Utility functions",
5
5
  "private": false,
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "typecheck": "tsc --noEmit"
26
26
  },
27
27
  "dependencies": {
28
- "@pear-protocol/types": "0.0.1",
28
+ "@pear-protocol/types": "0.0.3",
29
29
  "bignumber.js": "9.3.1"
30
30
  },
31
31
  "devDependencies": {
@@ -1,5 +0,0 @@
1
- import type { Fill } from './fill.types';
2
- /**
3
- * Returns only the fills contributing to the CURRENT exposure.
4
- */
5
- export declare function getActiveFillsSinceLastFlip(fills: Fill[]): Fill[];
@@ -1,23 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { sign } from '../math';
3
-
4
- function getActiveFillsSinceLastFlip(fills) {
5
- const lastFlipIndex = detectLastFlipIndex(fills);
6
- return fills.slice(lastFlipIndex + 1);
7
- }
8
- function detectLastFlipIndex(fills) {
9
- let runningExposure = new BigNumber(0);
10
- let lastFlipIndex = -1;
11
- fills.forEach((fill, i) => {
12
- const qty = new BigNumber(fill.quantity);
13
- const signedQty = fill.side === "BUY" ? qty : qty.negated();
14
- const nextExposure = runningExposure.plus(signedQty);
15
- if (!runningExposure.isZero() && sign(runningExposure) !== sign(nextExposure)) {
16
- lastFlipIndex = i;
17
- }
18
- runningExposure = nextExposure;
19
- });
20
- return lastFlipIndex;
21
- }
22
-
23
- export { getActiveFillsSinceLastFlip };