Skip to content

Commit 759d811

Browse files
authored
Merge pull request #436 from Ghadaffijr/feat/compute-price-change
feat: add computePriceChange helper for key price percentage change
2 parents 27cb9a8 + 56f7157 commit 759d811

2 files changed

Lines changed: 101 additions & 0 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// src/utils/__tests__/priceChange.utils.test.ts
2+
import { describe, expect, it } from 'vitest';
3+
import { computePriceChange } from '../priceChange.utils';
4+
5+
describe('computePriceChange', () => {
6+
describe('price up', () => {
7+
it('returns positive percent and direction up when price increases', () => {
8+
const result = computePriceChange(112n, 100n);
9+
expect(result.direction).toBe('up');
10+
expect(result.percent).toBeCloseTo(12);
11+
});
12+
13+
it('handles a large price increase', () => {
14+
const result = computePriceChange(200n, 100n);
15+
expect(result.direction).toBe('up');
16+
expect(result.percent).toBeCloseTo(100);
17+
});
18+
});
19+
20+
describe('price down', () => {
21+
it('returns negative percent and direction down when price decreases', () => {
22+
const result = computePriceChange(88n, 100n);
23+
expect(result.direction).toBe('down');
24+
expect(result.percent).toBeCloseTo(-12);
25+
});
26+
27+
it('handles a large price decrease', () => {
28+
const result = computePriceChange(1n, 100n);
29+
expect(result.direction).toBe('down');
30+
expect(result.percent).toBeCloseTo(-99);
31+
});
32+
});
33+
34+
describe('flat — no change', () => {
35+
it('returns flat with 0 percent when current equals previous', () => {
36+
const result = computePriceChange(100n, 100n);
37+
expect(result.direction).toBe('flat');
38+
expect(result.percent).toBe(0);
39+
});
40+
});
41+
42+
describe('flat — zero previous value', () => {
43+
it('returns flat with 0 percent when previous is zero', () => {
44+
const result = computePriceChange(100n, 0n);
45+
expect(result.direction).toBe('flat');
46+
expect(result.percent).toBe(0);
47+
});
48+
49+
it('returns flat when both current and previous are zero', () => {
50+
const result = computePriceChange(0n, 0n);
51+
expect(result.direction).toBe('flat');
52+
expect(result.percent).toBe(0);
53+
});
54+
});
55+
});

src/utils/priceChange.utils.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// src/utils/priceChange.utils.ts
2+
3+
/**
4+
* Result of a price change computation between two key price values.
5+
*/
6+
export interface PriceChangeResult {
7+
/** Percentage change as a number, e.g. 12.4 or -3.1. Always 0 when direction is 'flat'. */
8+
percent: number;
9+
/** Direction of the price movement relative to the previous value. */
10+
direction: 'up' | 'down' | 'flat';
11+
}
12+
13+
/**
14+
* Computes the percentage price change between two key price values expressed
15+
* in stroops (bigint).
16+
*
17+
* Returns `flat` with `percent: 0` when:
18+
* - `previous` is zero (division by zero is undefined)
19+
* - `current` equals `previous` (no change)
20+
*
21+
* @param current - The current key price in stroops
22+
* @param previous - The previous key price in stroops
23+
* @returns PriceChangeResult with percent and direction
24+
*
25+
* @example
26+
* computePriceChange(112n, 100n) // { percent: 12, direction: 'up' }
27+
* computePriceChange(88n, 100n) // { percent: -12, direction: 'down' }
28+
* computePriceChange(100n, 100n) // { percent: 0, direction: 'flat' }
29+
* computePriceChange(100n, 0n) // { percent: 0, direction: 'flat' }
30+
*/
31+
export function computePriceChange(
32+
current: bigint,
33+
previous: bigint
34+
): PriceChangeResult {
35+
if (previous === 0n || current === previous) {
36+
return { percent: 0, direction: 'flat' };
37+
}
38+
39+
const percent =
40+
(Number(current - previous) / Number(previous)) * 100;
41+
42+
return {
43+
percent,
44+
direction: percent > 0 ? 'up' : 'down',
45+
};
46+
}

0 commit comments

Comments
 (0)