jg-bignumber 1.0.1 → 1.1.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.
- package/API.md +754 -0
- package/CHANGELOG.md +19 -11
- package/README.md +1 -17
- package/dist/calculations/calculations.d.ts +39 -17
- package/dist/calculations/calculations.js +39 -17
- package/dist/calculations/calculations.js.map +1 -1
- package/dist/processing/processing.d.ts +29 -16
- package/dist/processing/processing.js +35 -19
- package/dist/processing/processing.js.map +1 -1
- package/dist/utils/utils.js +9 -6
- package/dist/utils/utils.js.map +1 -1
- package/dist/validations/validations.js +8 -4
- package/dist/validations/validations.js.map +1 -1
- package/package.json +8 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
A fresh start: breaking changes in a minor version, once, because nothing depended on 1.0.x.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `API.md`, the full API reference, generated from the TSDoc of the version it ships with, so it can be read from `node_modules` without a browser.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Errors are `Exception`s from `jg-exception` 1.1.0: the code, the data, and the cause each have their own field, nothing is encoded into the message, and `toJSON()` and `toString()` follow `jg-exception`.
|
|
14
|
+
- `prettifyValue` passes an `Exception` from the processing step through unchanged, and wraps any other error in `INVALID_BIGNUMBER_FORMAT`.
|
|
15
|
+
- Error messages say what failed at that step and keep the error underneath as `cause`, instead of repeating its message, so `extractMessage` prints each layer of the chain once.
|
|
16
|
+
|
|
3
17
|
## 1.0.1
|
|
4
18
|
|
|
5
19
|
### Changed
|
|
@@ -8,17 +22,11 @@
|
|
|
8
22
|
|
|
9
23
|
## 1.0.0
|
|
10
24
|
|
|
11
|
-
The first release
|
|
25
|
+
The first release.
|
|
12
26
|
|
|
13
27
|
### Added
|
|
14
28
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- `decimalPlaces` applies to every rounding mode, including `*_CEIL` and `*_FLOOR`.
|
|
21
|
-
- `NaN` and `±Infinity` are rejected as `INVALID_VALUE`.
|
|
22
|
-
- `calculateWeightedEntry` returns 0 when the amounts add up to 0.
|
|
23
|
-
- The package no longer changes the global bignumber.js configuration, and it uses bignumber.js 11.
|
|
24
|
-
- Errors are `Exception`s from `jg-exception`.
|
|
29
|
+
- `processValue`, `prettifyValue`, and `getBigNumber`, which round, format, and convert decimal values with bignumber.js 11, with `decimalPlaces` applied to every rounding mode.
|
|
30
|
+
- Calculations, such as `calculateSum`, `calculateMean`, `calculatePercentageChange`, and `calculateWeightedEntry`, which returns 0 when the amounts add up to 0.
|
|
31
|
+
- `BigNumber`, the package's own bignumber.js constructor, so the global bignumber.js configuration is left alone.
|
|
32
|
+
- `ERRORS`, the codes of every error the package throws. `NaN` and `±Infinity` are rejected as `INVALID_VALUE`.
|
package/README.md
CHANGED
|
@@ -43,25 +43,9 @@ calculateWeightedEntry([
|
|
|
43
43
|
|
|
44
44
|
`BigNumber` is the package's own bignumber.js constructor, so creating values with it never changes the global bignumber.js configuration.
|
|
45
45
|
|
|
46
|
-
## Coming from `bignumber-utils`
|
|
47
|
-
|
|
48
|
-
| `bignumber-utils` | `jg-bignumber` |
|
|
49
|
-
| ------------------------------------------------------------------------- | ------------------------------------------ |
|
|
50
|
-
| `import … from 'bignumber-utils'` | `import … from 'jg-bignumber'` |
|
|
51
|
-
| `import { BigNumber } from 'bignumber.js'` for values the package accepts | `import { BigNumber } from 'jg-bignumber'` |
|
|
52
|
-
|
|
53
|
-
Changed behavior:
|
|
54
|
-
|
|
55
|
-
- `decimalPlaces` applies to every rounding mode. The `*_CEIL` and `*_FLOOR` modes used to force 0 decimal places; pass `decimalPlaces: 0` for that.
|
|
56
|
-
- `NaN` and `±Infinity` are rejected: `getBigNumber`, `processValue`, and the calculations throw `INVALID_VALUE`, and `isNumber` returns `false`.
|
|
57
|
-
- Importing the package no longer changes the global bignumber.js configuration.
|
|
58
|
-
- `calculateWeightedEntry` returns 0 when the amounts add up to 0, instead of failing.
|
|
59
|
-
- Errors are `Exception`s from `jg-exception`, with the same codes, exported as `ERRORS`.
|
|
60
|
-
- The package uses bignumber.js 11, whose `IBigNumberFormat` adds `negativeSign` and `positiveSign`.
|
|
61
|
-
|
|
62
46
|
## Documentation
|
|
63
47
|
|
|
64
|
-
The full API reference is at https://jg-packages.jesusgraterol.dev/packages/jg-bignumber/.
|
|
48
|
+
The full API reference ships in the package as `API.md`, generated from its TSDoc for the installed version, and is at https://jg-packages.jesusgraterol.dev/packages/jg-bignumber/.
|
|
65
49
|
|
|
66
50
|
## License
|
|
67
51
|
|
|
@@ -5,8 +5,10 @@ import type { IBigNumberValue, IConfig, IOutput } from '../shared/types.js';
|
|
|
5
5
|
* @param config How the result is processed.
|
|
6
6
|
* @returns The sum.
|
|
7
7
|
* @example
|
|
8
|
-
* calculateSum
|
|
9
|
-
*
|
|
8
|
+
* import { calculateSum } from 'jg-bignumber';
|
|
9
|
+
*
|
|
10
|
+
* calculateSum([0.1, '0.2', 0.3]); // => 0.6
|
|
11
|
+
* calculateSum([0.1, 0.2], { type: 'string' }); // => '0.3'
|
|
10
12
|
* @throws
|
|
11
13
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
12
14
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -21,7 +23,9 @@ export declare const calculateSum: <T extends Partial<IConfig>>(values: IBigNumb
|
|
|
21
23
|
* @param config How the result is processed.
|
|
22
24
|
* @returns The smallest value.
|
|
23
25
|
* @example
|
|
24
|
-
* calculateMin
|
|
26
|
+
* import { calculateMin } from 'jg-bignumber';
|
|
27
|
+
*
|
|
28
|
+
* calculateMin([3, '1.5', 2]); // => 1.5
|
|
25
29
|
* @throws
|
|
26
30
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
27
31
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -36,7 +40,9 @@ export declare const calculateMin: <T extends Partial<IConfig>>(values: IBigNumb
|
|
|
36
40
|
* @param config How the result is processed.
|
|
37
41
|
* @returns The largest value.
|
|
38
42
|
* @example
|
|
39
|
-
* calculateMax
|
|
43
|
+
* import { calculateMax } from 'jg-bignumber';
|
|
44
|
+
*
|
|
45
|
+
* calculateMax([3, '1.5', 2]); // => 3
|
|
40
46
|
* @throws
|
|
41
47
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
42
48
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -51,7 +57,9 @@ export declare const calculateMax: <T extends Partial<IConfig>>(values: IBigNumb
|
|
|
51
57
|
* @param config How the result is processed.
|
|
52
58
|
* @returns The mean.
|
|
53
59
|
* @example
|
|
54
|
-
* calculateMean
|
|
60
|
+
* import { calculateMean } from 'jg-bignumber';
|
|
61
|
+
*
|
|
62
|
+
* calculateMean([1, 2, 4]); // => 2.33
|
|
55
63
|
* @throws
|
|
56
64
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
57
65
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -67,8 +75,10 @@ export declare const calculateMean: <T extends Partial<IConfig>>(values: IBigNum
|
|
|
67
75
|
* @param config How the result is processed.
|
|
68
76
|
* @returns The median.
|
|
69
77
|
* @example
|
|
70
|
-
* calculateMedian
|
|
71
|
-
*
|
|
78
|
+
* import { calculateMedian } from 'jg-bignumber';
|
|
79
|
+
*
|
|
80
|
+
* calculateMedian([5, 1, 3]); // => 3
|
|
81
|
+
* calculateMedian([4, 1, 3, 2]); // => 2.5
|
|
72
82
|
* @throws
|
|
73
83
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
74
84
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -86,9 +96,11 @@ export declare const calculateMedian: <T extends Partial<IConfig>>(values: IBigN
|
|
|
86
96
|
* @param config How the result is processed.
|
|
87
97
|
* @returns The percentage change.
|
|
88
98
|
* @example
|
|
89
|
-
* calculatePercentageChange
|
|
90
|
-
*
|
|
91
|
-
* calculatePercentageChange(100,
|
|
99
|
+
* import { calculatePercentageChange } from 'jg-bignumber';
|
|
100
|
+
*
|
|
101
|
+
* calculatePercentageChange(100, 125); // => 25
|
|
102
|
+
* calculatePercentageChange(100, 80); // => -20
|
|
103
|
+
* calculatePercentageChange(100, 0); // => -100
|
|
92
104
|
* @throws
|
|
93
105
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
94
106
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -105,8 +117,10 @@ export declare const calculatePercentageChange: <T extends Partial<IConfig>>(old
|
|
|
105
117
|
* @param config How the result is processed.
|
|
106
118
|
* @returns The changed value.
|
|
107
119
|
* @example
|
|
108
|
-
* adjustByPercentage
|
|
109
|
-
*
|
|
120
|
+
* import { adjustByPercentage } from 'jg-bignumber';
|
|
121
|
+
*
|
|
122
|
+
* adjustByPercentage(100, 25); // => 125
|
|
123
|
+
* adjustByPercentage(100, -10); // => 90
|
|
110
124
|
* @throws
|
|
111
125
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
112
126
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -122,7 +136,9 @@ export declare const adjustByPercentage: <T extends Partial<IConfig>>(value: IBi
|
|
|
122
136
|
* @param config How the result is processed.
|
|
123
137
|
* @returns The percentage.
|
|
124
138
|
* @example
|
|
125
|
-
* calculatePercentageRepresentation
|
|
139
|
+
* import { calculatePercentageRepresentation } from 'jg-bignumber';
|
|
140
|
+
*
|
|
141
|
+
* calculatePercentageRepresentation(25, 200); // => 12.5
|
|
126
142
|
* @throws
|
|
127
143
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
128
144
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -139,7 +155,9 @@ export declare const calculatePercentageRepresentation: <T extends Partial<IConf
|
|
|
139
155
|
* @param config How the result is processed.
|
|
140
156
|
* @returns The amount received.
|
|
141
157
|
* @example
|
|
142
|
-
*
|
|
158
|
+
* import { calculateExchange } from 'jg-bignumber';
|
|
159
|
+
*
|
|
160
|
+
* calculateExchange(100, 65000, { decimalPlaces: 8 }); // => 0.00153846
|
|
143
161
|
* @throws
|
|
144
162
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
145
163
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -155,7 +173,9 @@ export declare const calculateExchange: <T extends Partial<IConfig>>(value: IBig
|
|
|
155
173
|
* @param config How the result is processed.
|
|
156
174
|
* @returns The fee.
|
|
157
175
|
* @example
|
|
158
|
-
* calculateExchangeFee
|
|
176
|
+
* import { calculateExchangeFee } from 'jg-bignumber';
|
|
177
|
+
*
|
|
178
|
+
* calculateExchangeFee(1000, 0.1); // => 1
|
|
159
179
|
* @throws
|
|
160
180
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
161
181
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -171,8 +191,10 @@ export declare const calculateExchangeFee: <T extends Partial<IConfig>>(value: I
|
|
|
171
191
|
* @param config How the result is processed.
|
|
172
192
|
* @returns The weighted average price.
|
|
173
193
|
* @example
|
|
174
|
-
* calculateWeightedEntry
|
|
175
|
-
*
|
|
194
|
+
* import { calculateWeightedEntry } from 'jg-bignumber';
|
|
195
|
+
*
|
|
196
|
+
* calculateWeightedEntry([[100, 2], [130, 1]]); // => 110
|
|
197
|
+
* calculateWeightedEntry([]); // => 0
|
|
176
198
|
* @throws
|
|
177
199
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
178
200
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -11,8 +11,10 @@ import { validatePositiveValue, validateValuesArray } from '../validations/valid
|
|
|
11
11
|
* @param config How the result is processed.
|
|
12
12
|
* @returns The sum.
|
|
13
13
|
* @example
|
|
14
|
-
* calculateSum
|
|
15
|
-
*
|
|
14
|
+
* import { calculateSum } from 'jg-bignumber';
|
|
15
|
+
*
|
|
16
|
+
* calculateSum([0.1, '0.2', 0.3]); // => 0.6
|
|
17
|
+
* calculateSum([0.1, 0.2], { type: 'string' }); // => '0.3'
|
|
16
18
|
* @throws
|
|
17
19
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
18
20
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -30,7 +32,9 @@ export const calculateSum = (values, config) => {
|
|
|
30
32
|
* @param config How the result is processed.
|
|
31
33
|
* @returns The smallest value.
|
|
32
34
|
* @example
|
|
33
|
-
* calculateMin
|
|
35
|
+
* import { calculateMin } from 'jg-bignumber';
|
|
36
|
+
*
|
|
37
|
+
* calculateMin([3, '1.5', 2]); // => 1.5
|
|
34
38
|
* @throws
|
|
35
39
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
36
40
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -48,7 +52,9 @@ export const calculateMin = (values, config) => {
|
|
|
48
52
|
* @param config How the result is processed.
|
|
49
53
|
* @returns The largest value.
|
|
50
54
|
* @example
|
|
51
|
-
* calculateMax
|
|
55
|
+
* import { calculateMax } from 'jg-bignumber';
|
|
56
|
+
*
|
|
57
|
+
* calculateMax([3, '1.5', 2]); // => 3
|
|
52
58
|
* @throws
|
|
53
59
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
54
60
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -66,7 +72,9 @@ export const calculateMax = (values, config) => {
|
|
|
66
72
|
* @param config How the result is processed.
|
|
67
73
|
* @returns The mean.
|
|
68
74
|
* @example
|
|
69
|
-
* calculateMean
|
|
75
|
+
* import { calculateMean } from 'jg-bignumber';
|
|
76
|
+
*
|
|
77
|
+
* calculateMean([1, 2, 4]); // => 2.33
|
|
70
78
|
* @throws
|
|
71
79
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
72
80
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -88,8 +96,10 @@ export const calculateMean = (values, config) => {
|
|
|
88
96
|
* @param config How the result is processed.
|
|
89
97
|
* @returns The median.
|
|
90
98
|
* @example
|
|
91
|
-
* calculateMedian
|
|
92
|
-
*
|
|
99
|
+
* import { calculateMedian } from 'jg-bignumber';
|
|
100
|
+
*
|
|
101
|
+
* calculateMedian([5, 1, 3]); // => 3
|
|
102
|
+
* calculateMedian([4, 1, 3, 2]); // => 2.5
|
|
93
103
|
* @throws
|
|
94
104
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
95
105
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -120,9 +130,11 @@ export const calculateMedian = (values, config) => {
|
|
|
120
130
|
* @param config How the result is processed.
|
|
121
131
|
* @returns The percentage change.
|
|
122
132
|
* @example
|
|
123
|
-
* calculatePercentageChange
|
|
124
|
-
*
|
|
125
|
-
* calculatePercentageChange(100,
|
|
133
|
+
* import { calculatePercentageChange } from 'jg-bignumber';
|
|
134
|
+
*
|
|
135
|
+
* calculatePercentageChange(100, 125); // => 25
|
|
136
|
+
* calculatePercentageChange(100, 80); // => -20
|
|
137
|
+
* calculatePercentageChange(100, 0); // => -100
|
|
126
138
|
* @throws
|
|
127
139
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
128
140
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -156,8 +168,10 @@ export const calculatePercentageChange = (oldValue, newValue, config) => {
|
|
|
156
168
|
* @param config How the result is processed.
|
|
157
169
|
* @returns The changed value.
|
|
158
170
|
* @example
|
|
159
|
-
* adjustByPercentage
|
|
160
|
-
*
|
|
171
|
+
* import { adjustByPercentage } from 'jg-bignumber';
|
|
172
|
+
*
|
|
173
|
+
* adjustByPercentage(100, 25); // => 125
|
|
174
|
+
* adjustByPercentage(100, -10); // => 90
|
|
161
175
|
* @throws
|
|
162
176
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
163
177
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -190,7 +204,9 @@ export const adjustByPercentage = (value, percentage, config) => {
|
|
|
190
204
|
* @param config How the result is processed.
|
|
191
205
|
* @returns The percentage.
|
|
192
206
|
* @example
|
|
193
|
-
* calculatePercentageRepresentation
|
|
207
|
+
* import { calculatePercentageRepresentation } from 'jg-bignumber';
|
|
208
|
+
*
|
|
209
|
+
* calculatePercentageRepresentation(25, 200); // => 12.5
|
|
194
210
|
* @throws
|
|
195
211
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
196
212
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -216,7 +232,9 @@ export const calculatePercentageRepresentation = (value, total, config) => {
|
|
|
216
232
|
* @param config How the result is processed.
|
|
217
233
|
* @returns The amount received.
|
|
218
234
|
* @example
|
|
219
|
-
*
|
|
235
|
+
* import { calculateExchange } from 'jg-bignumber';
|
|
236
|
+
*
|
|
237
|
+
* calculateExchange(100, 65000, { decimalPlaces: 8 }); // => 0.00153846
|
|
220
238
|
* @throws
|
|
221
239
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
222
240
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -238,7 +256,9 @@ export const calculateExchange = (value, rate, config) => {
|
|
|
238
256
|
* @param config How the result is processed.
|
|
239
257
|
* @returns The fee.
|
|
240
258
|
* @example
|
|
241
|
-
* calculateExchangeFee
|
|
259
|
+
* import { calculateExchangeFee } from 'jg-bignumber';
|
|
260
|
+
*
|
|
261
|
+
* calculateExchangeFee(1000, 0.1); // => 1
|
|
242
262
|
* @throws
|
|
243
263
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
244
264
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -260,8 +280,10 @@ export const calculateExchangeFee = (value, feePercentage, config) => {
|
|
|
260
280
|
* @param config How the result is processed.
|
|
261
281
|
* @returns The weighted average price.
|
|
262
282
|
* @example
|
|
263
|
-
* calculateWeightedEntry
|
|
264
|
-
*
|
|
283
|
+
* import { calculateWeightedEntry } from 'jg-bignumber';
|
|
284
|
+
*
|
|
285
|
+
* calculateWeightedEntry([[100, 2], [130, 1]]); // => 110
|
|
286
|
+
* calculateWeightedEntry([]); // => 0
|
|
265
287
|
* @throws
|
|
266
288
|
* - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error
|
|
267
289
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculations.js","sourceRoot":"","sources":["../../src/calculations/calculations.ts"],"names":[],"mappings":"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","sourcesContent":["import { BigNumber } from '../shared/constants.js';\nimport type { IBigNumber, IBigNumberValue, IConfig, IOutput } from '../shared/types.js';\nimport { getBigNumber, processValue } from '../processing/processing.js';\nimport { sortBigNumbers } from '../utils/utils.js';\nimport { validatePositiveValue, validateValuesArray } from '../validations/validations.js';\n\n/*\n * Essential calculations\n */\n\n/**\n * Adds up a list of values. An empty list sums to 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The sum.\n * @example\n * calculateSum([0.1, '0.2', 0.3]); // 0.6\n * calculateSum([0.1, 0.2], { type: 'string' }); // '0.3'\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateSum = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateSum');\n return processValue(values.length > 0 ? BigNumber.sum(...values) : 0, config);\n};\n\n/**\n * Finds the smallest value in a list. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The smallest value.\n * @example\n * calculateMin([3, '1.5', 2]); // 1.5\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMin = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMin');\n return processValue(values.length > 0 ? BigNumber.min(...values) : 0, config);\n};\n\n/**\n * Finds the largest value in a list. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The largest value.\n * @example\n * calculateMax([3, '1.5', 2]); // 3\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMax = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMax');\n return processValue(values.length > 0 ? BigNumber.max(...values) : 0, config);\n};\n\n/**\n * Calculates the mean of a list of values. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The mean.\n * @example\n * calculateMean([1, 2, 4]); // 2.33\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMean = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMean');\n if (values.length > 0) {\n return processValue(BigNumber.sum(...values).dividedBy(values.length), config);\n }\n return processValue(0, config);\n};\n\n/**\n * Calculates the median of a list of values: the middle value, or the mean of the two middle\n * values when the list has an even length. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The median.\n * @example\n * calculateMedian([5, 1, 3]); // 3\n * calculateMedian([4, 1, 3, 2]); // 2.5\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMedian = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMedian');\n if (values.length === 0) {\n return processValue(0, config);\n }\n const half = Math.floor(values.length / 2);\n const sorted = values.map(getBigNumber).sort(sortBigNumbers('asc'));\n const middle = sorted[half] as IBigNumber;\n const median =\n values.length % 2 === 1 ? middle : (sorted[half - 1] as IBigNumber).plus(middle).dividedBy(2);\n return processValue(median, config);\n};\n\n/*\n * Percentage calculations\n */\n\n/**\n * Calculates the percentage a value changed by: positive when it increased, negative when it\n * decreased, and 0 when it didn't change. The largest decrease is -100%, returned whenever the new\n * value is 0 or less.\n * @param oldValue The value before the change.\n * @param newValue The value after the change.\n * @param config How the result is processed.\n * @returns The percentage change.\n * @example\n * calculatePercentageChange(100, 125); // 25\n * calculatePercentageChange(100, 80); // -20\n * calculatePercentageChange(100, 0); // -100\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the oldValue is not positive\n */\nexport const calculatePercentageChange = <T extends Partial<IConfig>>(\n oldValue: IBigNumberValue,\n newValue: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const oldValueBN = getBigNumber(oldValue);\n const newValueBN = getBigNumber(newValue);\n validatePositiveValue(oldValueBN);\n\n let change: IBigNumber;\n if (newValueBN.isGreaterThan(oldValueBN)) {\n change = newValueBN.minus(oldValueBN).dividedBy(oldValueBN).times(100);\n } else if (oldValueBN.isGreaterThan(newValueBN)) {\n change = newValueBN.isGreaterThan(0)\n ? oldValueBN.minus(newValueBN).dividedBy(oldValueBN).times(100).negated()\n : getBigNumber(-100);\n } else {\n change = getBigNumber(0);\n }\n return processValue(change, config);\n};\n\n/**\n * Changes a value by a percentage: a positive percentage increases it, and a negative one\n * decreases it, to 0 at most.\n * @param value The value to change.\n * @param percentage The percentage to change it by.\n * @param config How the result is processed.\n * @returns The changed value.\n * @example\n * adjustByPercentage(100, 25); // 125\n * adjustByPercentage(100, -10); // 90\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value is not positive\n */\nexport const adjustByPercentage = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n percentage: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const percentageBN = getBigNumber(percentage);\n validatePositiveValue(valueBN);\n\n let adjusted: IBigNumber;\n if (percentageBN.isGreaterThan(0)) {\n adjusted = percentageBN.dividedBy(100).plus(1).times(valueBN);\n } else if (percentageBN.isLessThan(0)) {\n adjusted = percentageBN.isGreaterThan(-100)\n ? percentageBN.times(-1).dividedBy(100).minus(1).times(valueBN).times(-1)\n : getBigNumber(0);\n } else {\n adjusted = valueBN;\n }\n return processValue(adjusted, config);\n};\n\n/**\n * Calculates what percentage of a total a value represents.\n * @param value The part.\n * @param total The total.\n * @param config How the result is processed.\n * @returns The percentage.\n * @example\n * calculatePercentageRepresentation(25, 200); // 12.5\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value or total are not positive\n */\nexport const calculatePercentageRepresentation = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n total: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const totalBN = getBigNumber(total);\n validatePositiveValue(valueBN, true);\n validatePositiveValue(totalBN);\n return processValue(valueBN.times(100).dividedBy(totalBN), config);\n};\n\n/*\n * Financial calculations\n */\n\n/**\n * Calculates the amount of an asset an exchange gives for a value at a rate, such as how much\n * BTC 100 USDT buys at 65,000 USDT per BTC.\n * @param value The amount being exchanged.\n * @param rate The price of one unit of the asset received.\n * @param config How the result is processed.\n * @returns The amount received.\n * @example\n * calculateExchange(100, 65000, { decimalPlaces: 8 }); // 0.00153846\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value or rate are not positive\n */\nexport const calculateExchange = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n rate: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const rateBN = getBigNumber(rate);\n validatePositiveValue(valueBN);\n validatePositiveValue(rateBN);\n return processValue(valueBN.dividedBy(rateBN), config);\n};\n\n/**\n * Calculates the fee charged for an exchange, as a percentage of the value exchanged.\n * @param value The amount being exchanged.\n * @param feePercentage The fee, as a percentage.\n * @param config How the result is processed.\n * @returns The fee.\n * @example\n * calculateExchangeFee(1000, 0.1); // 1\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value or feePercentage are not positive\n */\nexport const calculateExchangeFee = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n feePercentage: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const feePercentageBN = getBigNumber(feePercentage);\n validatePositiveValue(valueBN);\n validatePositiveValue(feePercentageBN, true);\n return processValue(feePercentageBN.times(valueBN).dividedBy(100), config);\n};\n\n/**\n * Calculates the average entry price of a position bought in several trades, weighting each price\n * by the amount bought. An empty list, or one whose amounts add up to 0, returns 0.\n * @param trades The trades, each as a `[price, amount]` tuple.\n * @param config How the result is processed.\n * @returns The weighted average price.\n * @example\n * calculateWeightedEntry([[100, 2], [130, 1]]); // 110\n * calculateWeightedEntry([]); // 0\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateWeightedEntry = <T extends Partial<IConfig>>(\n trades: [IBigNumberValue, IBigNumberValue][],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(trades, 'calculateWeightedEntry');\n if (trades.length === 0) {\n return processValue(0, config);\n }\n let priceTimesShares = getBigNumber(0);\n let totalShares = getBigNumber(0);\n trades.forEach(([price, amount]) => {\n const amountBN = getBigNumber(amount);\n priceTimesShares = priceTimesShares.plus(getBigNumber(price).times(amountBN));\n totalShares = totalShares.plus(amountBN);\n });\n if (totalShares.isZero()) {\n return processValue(0, config);\n }\n return processValue(priceTimesShares.dividedBy(totalShares), config);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"calculations.js","sourceRoot":"","sources":["../../src/calculations/calculations.ts"],"names":[],"mappings":"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","sourcesContent":["import { BigNumber } from '../shared/constants.js';\nimport type { IBigNumber, IBigNumberValue, IConfig, IOutput } from '../shared/types.js';\nimport { getBigNumber, processValue } from '../processing/processing.js';\nimport { sortBigNumbers } from '../utils/utils.js';\nimport { validatePositiveValue, validateValuesArray } from '../validations/validations.js';\n\n/*\n * Essential calculations\n */\n\n/**\n * Adds up a list of values. An empty list sums to 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The sum.\n * @example\n * import { calculateSum } from 'jg-bignumber';\n *\n * calculateSum([0.1, '0.2', 0.3]); // => 0.6\n * calculateSum([0.1, 0.2], { type: 'string' }); // => '0.3'\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateSum = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateSum');\n return processValue(values.length > 0 ? BigNumber.sum(...values) : 0, config);\n};\n\n/**\n * Finds the smallest value in a list. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The smallest value.\n * @example\n * import { calculateMin } from 'jg-bignumber';\n *\n * calculateMin([3, '1.5', 2]); // => 1.5\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMin = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMin');\n return processValue(values.length > 0 ? BigNumber.min(...values) : 0, config);\n};\n\n/**\n * Finds the largest value in a list. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The largest value.\n * @example\n * import { calculateMax } from 'jg-bignumber';\n *\n * calculateMax([3, '1.5', 2]); // => 3\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMax = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMax');\n return processValue(values.length > 0 ? BigNumber.max(...values) : 0, config);\n};\n\n/**\n * Calculates the mean of a list of values. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The mean.\n * @example\n * import { calculateMean } from 'jg-bignumber';\n *\n * calculateMean([1, 2, 4]); // => 2.33\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMean = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMean');\n if (values.length > 0) {\n return processValue(BigNumber.sum(...values).dividedBy(values.length), config);\n }\n return processValue(0, config);\n};\n\n/**\n * Calculates the median of a list of values: the middle value, or the mean of the two middle\n * values when the list has an even length. An empty list returns 0.\n * @param values The values.\n * @param config How the result is processed.\n * @returns The median.\n * @example\n * import { calculateMedian } from 'jg-bignumber';\n *\n * calculateMedian([5, 1, 3]); // => 3\n * calculateMedian([4, 1, 3, 2]); // => 2.5\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateMedian = <T extends Partial<IConfig>>(\n values: IBigNumberValue[],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(values, 'calculateMedian');\n if (values.length === 0) {\n return processValue(0, config);\n }\n const half = Math.floor(values.length / 2);\n const sorted = values.map(getBigNumber).sort(sortBigNumbers('asc'));\n const middle = sorted[half] as IBigNumber;\n const median =\n values.length % 2 === 1 ? middle : (sorted[half - 1] as IBigNumber).plus(middle).dividedBy(2);\n return processValue(median, config);\n};\n\n/*\n * Percentage calculations\n */\n\n/**\n * Calculates the percentage a value changed by: positive when it increased, negative when it\n * decreased, and 0 when it didn't change. The largest decrease is -100%, returned whenever the new\n * value is 0 or less.\n * @param oldValue The value before the change.\n * @param newValue The value after the change.\n * @param config How the result is processed.\n * @returns The percentage change.\n * @example\n * import { calculatePercentageChange } from 'jg-bignumber';\n *\n * calculatePercentageChange(100, 125); // => 25\n * calculatePercentageChange(100, 80); // => -20\n * calculatePercentageChange(100, 0); // => -100\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the oldValue is not positive\n */\nexport const calculatePercentageChange = <T extends Partial<IConfig>>(\n oldValue: IBigNumberValue,\n newValue: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const oldValueBN = getBigNumber(oldValue);\n const newValueBN = getBigNumber(newValue);\n validatePositiveValue(oldValueBN);\n\n let change: IBigNumber;\n if (newValueBN.isGreaterThan(oldValueBN)) {\n change = newValueBN.minus(oldValueBN).dividedBy(oldValueBN).times(100);\n } else if (oldValueBN.isGreaterThan(newValueBN)) {\n change = newValueBN.isGreaterThan(0)\n ? oldValueBN.minus(newValueBN).dividedBy(oldValueBN).times(100).negated()\n : getBigNumber(-100);\n } else {\n change = getBigNumber(0);\n }\n return processValue(change, config);\n};\n\n/**\n * Changes a value by a percentage: a positive percentage increases it, and a negative one\n * decreases it, to 0 at most.\n * @param value The value to change.\n * @param percentage The percentage to change it by.\n * @param config How the result is processed.\n * @returns The changed value.\n * @example\n * import { adjustByPercentage } from 'jg-bignumber';\n *\n * adjustByPercentage(100, 25); // => 125\n * adjustByPercentage(100, -10); // => 90\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value is not positive\n */\nexport const adjustByPercentage = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n percentage: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const percentageBN = getBigNumber(percentage);\n validatePositiveValue(valueBN);\n\n let adjusted: IBigNumber;\n if (percentageBN.isGreaterThan(0)) {\n adjusted = percentageBN.dividedBy(100).plus(1).times(valueBN);\n } else if (percentageBN.isLessThan(0)) {\n adjusted = percentageBN.isGreaterThan(-100)\n ? percentageBN.times(-1).dividedBy(100).minus(1).times(valueBN).times(-1)\n : getBigNumber(0);\n } else {\n adjusted = valueBN;\n }\n return processValue(adjusted, config);\n};\n\n/**\n * Calculates what percentage of a total a value represents.\n * @param value The part.\n * @param total The total.\n * @param config How the result is processed.\n * @returns The percentage.\n * @example\n * import { calculatePercentageRepresentation } from 'jg-bignumber';\n *\n * calculatePercentageRepresentation(25, 200); // => 12.5\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value or total are not positive\n */\nexport const calculatePercentageRepresentation = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n total: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const totalBN = getBigNumber(total);\n validatePositiveValue(valueBN, true);\n validatePositiveValue(totalBN);\n return processValue(valueBN.times(100).dividedBy(totalBN), config);\n};\n\n/*\n * Financial calculations\n */\n\n/**\n * Calculates the amount of an asset an exchange gives for a value at a rate, such as how much\n * BTC 100 USDT buys at 65,000 USDT per BTC.\n * @param value The amount being exchanged.\n * @param rate The price of one unit of the asset received.\n * @param config How the result is processed.\n * @returns The amount received.\n * @example\n * import { calculateExchange } from 'jg-bignumber';\n *\n * calculateExchange(100, 65000, { decimalPlaces: 8 }); // => 0.00153846\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value or rate are not positive\n */\nexport const calculateExchange = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n rate: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const rateBN = getBigNumber(rate);\n validatePositiveValue(valueBN);\n validatePositiveValue(rateBN);\n return processValue(valueBN.dividedBy(rateBN), config);\n};\n\n/**\n * Calculates the fee charged for an exchange, as a percentage of the value exchanged.\n * @param value The amount being exchanged.\n * @param feePercentage The fee, as a percentage.\n * @param config How the result is processed.\n * @returns The fee.\n * @example\n * import { calculateExchangeFee } from 'jg-bignumber';\n *\n * calculateExchangeFee(1000, 0.1); // => 1\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - NEGATIVE_VALUE_NOT_ALLOWED: if the value or feePercentage are not positive\n */\nexport const calculateExchangeFee = <T extends Partial<IConfig>>(\n value: IBigNumberValue,\n feePercentage: IBigNumberValue,\n config?: T,\n): IOutput<T> => {\n const valueBN = getBigNumber(value);\n const feePercentageBN = getBigNumber(feePercentage);\n validatePositiveValue(valueBN);\n validatePositiveValue(feePercentageBN, true);\n return processValue(feePercentageBN.times(valueBN).dividedBy(100), config);\n};\n\n/**\n * Calculates the average entry price of a position bought in several trades, weighting each price\n * by the amount bought. An empty list, or one whose amounts add up to 0, returns 0.\n * @param trades The trades, each as a `[price, amount]` tuple.\n * @param config How the result is processed.\n * @returns The weighted average price.\n * @example\n * import { calculateWeightedEntry } from 'jg-bignumber';\n *\n * calculateWeightedEntry([[100, 2], [130, 1]]); // => 110\n * calculateWeightedEntry([]); // => 0\n * @throws\n * - INVALID_VALUE: if any of the given values isn't a finite number or BigNumber throws an error\n * - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason\n * - INVALID_ROUNDING_MODE: if the rounding mode name is not supported\n * - INVALID_TYPE: if the processing type is not supported\n * - INVALID_VALUES_ARRAY: if the provided values arg is not a valid array\n */\nexport const calculateWeightedEntry = <T extends Partial<IConfig>>(\n trades: [IBigNumberValue, IBigNumberValue][],\n config?: T,\n): IOutput<T> => {\n validateValuesArray(trades, 'calculateWeightedEntry');\n if (trades.length === 0) {\n return processValue(0, config);\n }\n let priceTimesShares = getBigNumber(0);\n let totalShares = getBigNumber(0);\n trades.forEach(([price, amount]) => {\n const amountBN = getBigNumber(amount);\n priceTimesShares = priceTimesShares.plus(getBigNumber(price).times(amountBN));\n totalShares = totalShares.plus(amountBN);\n });\n if (totalShares.isZero()) {\n return processValue(0, config);\n }\n return processValue(priceTimesShares.dividedBy(totalShares), config);\n};\n"]}
|
|
@@ -5,8 +5,9 @@ import type { IBigNumber, IBigNumberFormat, IBigNumberValue, IConfig, IOutput }
|
|
|
5
5
|
* @param value The value.
|
|
6
6
|
* @returns The BigNumber.
|
|
7
7
|
* @example
|
|
8
|
-
* getBigNumber
|
|
9
|
-
*
|
|
8
|
+
* import { getBigNumber } from 'jg-bignumber';
|
|
9
|
+
*
|
|
10
|
+
* getBigNumber('0.1').plus('0.2').toString(); // => '0.3'
|
|
10
11
|
* @throws
|
|
11
12
|
* - INVALID_VALUE: if the value isn't a finite number or BigNumber throws an error
|
|
12
13
|
*/
|
|
@@ -18,9 +19,11 @@ export declare const getBigNumber: (value: IBigNumberValue) => IBigNumber;
|
|
|
18
19
|
* @param configuration The decimal places, rounding mode, and output type.
|
|
19
20
|
* @returns The processed value.
|
|
20
21
|
* @example
|
|
21
|
-
* processValue
|
|
22
|
-
*
|
|
23
|
-
* processValue(
|
|
22
|
+
* import { processValue } from 'jg-bignumber';
|
|
23
|
+
*
|
|
24
|
+
* processValue(512.155); // => 512.16
|
|
25
|
+
* processValue(512.155, { decimalPlaces: 1, roundingMode: 'ROUND_FLOOR' }); // => 512.1
|
|
26
|
+
* processValue('0.000001', { decimalPlaces: 6, type: 'string' }); // => '0.000001'
|
|
24
27
|
* @throws
|
|
25
28
|
* - INVALID_VALUE: if the value isn't a finite number or BigNumber throws an error
|
|
26
29
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -34,8 +37,10 @@ export declare const processValue: <T extends Partial<IConfig>>(value: IBigNumbe
|
|
|
34
37
|
* @param config How the value is processed and formatted.
|
|
35
38
|
* @returns The formatted value.
|
|
36
39
|
* @example
|
|
37
|
-
* prettifyValue
|
|
38
|
-
*
|
|
40
|
+
* import { prettifyValue } from 'jg-bignumber';
|
|
41
|
+
*
|
|
42
|
+
* prettifyValue(1234567.891); // => '1,234,567.89'
|
|
43
|
+
* prettifyValue(1234.5, { processing: { decimalPlaces: 2 }, format: { prefix: '$' } }); // => '$1,234.5'
|
|
39
44
|
* @throws
|
|
40
45
|
* - INVALID_VALUE: if the value isn't a finite number or BigNumber throws an error
|
|
41
46
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -53,8 +58,10 @@ export declare const prettifyValue: (value: IBigNumberValue, config?: {
|
|
|
53
58
|
* @param value The value.
|
|
54
59
|
* @returns Whether it's a BigNumber.
|
|
55
60
|
* @example
|
|
56
|
-
*
|
|
57
|
-
*
|
|
61
|
+
* import { getBigNumber, isBigNumber } from 'jg-bignumber';
|
|
62
|
+
*
|
|
63
|
+
* isBigNumber(getBigNumber(1)); // => true
|
|
64
|
+
* isBigNumber(1); // => false
|
|
58
65
|
*/
|
|
59
66
|
export declare const isBigNumber: (value: unknown) => value is IBigNumber;
|
|
60
67
|
/**
|
|
@@ -62,9 +69,11 @@ export declare const isBigNumber: (value: unknown) => value is IBigNumber;
|
|
|
62
69
|
* @param value The value.
|
|
63
70
|
* @returns Whether it's a finite number.
|
|
64
71
|
* @example
|
|
65
|
-
* isNumber
|
|
66
|
-
*
|
|
67
|
-
* isNumber('
|
|
72
|
+
* import { isNumber } from 'jg-bignumber';
|
|
73
|
+
*
|
|
74
|
+
* isNumber('12.5'); // => true
|
|
75
|
+
* isNumber(Infinity); // => false
|
|
76
|
+
* isNumber('abc'); // => false
|
|
68
77
|
*/
|
|
69
78
|
export declare const isNumber: (value: unknown) => boolean;
|
|
70
79
|
/**
|
|
@@ -72,8 +81,10 @@ export declare const isNumber: (value: unknown) => boolean;
|
|
|
72
81
|
* @param value The value.
|
|
73
82
|
* @returns Whether it's an integer.
|
|
74
83
|
* @example
|
|
75
|
-
* isInteger
|
|
76
|
-
*
|
|
84
|
+
* import { isInteger } from 'jg-bignumber';
|
|
85
|
+
*
|
|
86
|
+
* isInteger('12'); // => true
|
|
87
|
+
* isInteger(12.5); // => false
|
|
77
88
|
*/
|
|
78
89
|
export declare const isInteger: (value: unknown) => boolean;
|
|
79
90
|
/**
|
|
@@ -81,7 +92,9 @@ export declare const isInteger: (value: unknown) => boolean;
|
|
|
81
92
|
* @param value The value.
|
|
82
93
|
* @returns Whether it's a float.
|
|
83
94
|
* @example
|
|
84
|
-
* isFloat
|
|
85
|
-
*
|
|
95
|
+
* import { isFloat } from 'jg-bignumber';
|
|
96
|
+
*
|
|
97
|
+
* isFloat(12.5); // => true
|
|
98
|
+
* isFloat('12'); // => false
|
|
86
99
|
*/
|
|
87
100
|
export declare const isFloat: (value: unknown) => boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Exception,
|
|
1
|
+
import { Exception, isException } from 'jg-exception';
|
|
2
2
|
import { BigNumber } from '../shared/constants.js';
|
|
3
3
|
import { ERRORS } from '../shared/errors.js';
|
|
4
4
|
import { buildConfig, buildFormatConfig, buildInvalidValueException, convertBigNumberToType, roundBigNumber, } from '../utils/utils.js';
|
|
@@ -8,8 +8,9 @@ import { buildConfig, buildFormatConfig, buildInvalidValueException, convertBigN
|
|
|
8
8
|
* @param value The value.
|
|
9
9
|
* @returns The BigNumber.
|
|
10
10
|
* @example
|
|
11
|
-
* getBigNumber
|
|
12
|
-
*
|
|
11
|
+
* import { getBigNumber } from 'jg-bignumber';
|
|
12
|
+
*
|
|
13
|
+
* getBigNumber('0.1').plus('0.2').toString(); // => '0.3'
|
|
13
14
|
* @throws
|
|
14
15
|
* - INVALID_VALUE: if the value isn't a finite number or BigNumber throws an error
|
|
15
16
|
*/
|
|
@@ -33,9 +34,11 @@ export const getBigNumber = (value) => {
|
|
|
33
34
|
* @param configuration The decimal places, rounding mode, and output type.
|
|
34
35
|
* @returns The processed value.
|
|
35
36
|
* @example
|
|
36
|
-
* processValue
|
|
37
|
-
*
|
|
38
|
-
* processValue(
|
|
37
|
+
* import { processValue } from 'jg-bignumber';
|
|
38
|
+
*
|
|
39
|
+
* processValue(512.155); // => 512.16
|
|
40
|
+
* processValue(512.155, { decimalPlaces: 1, roundingMode: 'ROUND_FLOOR' }); // => 512.1
|
|
41
|
+
* processValue('0.000001', { decimalPlaces: 6, type: 'string' }); // => '0.000001'
|
|
39
42
|
* @throws
|
|
40
43
|
* - INVALID_VALUE: if the value isn't a finite number or BigNumber throws an error
|
|
41
44
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -53,8 +56,10 @@ export const processValue = (value, configuration) => {
|
|
|
53
56
|
* @param config How the value is processed and formatted.
|
|
54
57
|
* @returns The formatted value.
|
|
55
58
|
* @example
|
|
56
|
-
* prettifyValue
|
|
57
|
-
*
|
|
59
|
+
* import { prettifyValue } from 'jg-bignumber';
|
|
60
|
+
*
|
|
61
|
+
* prettifyValue(1234567.891); // => '1,234,567.89'
|
|
62
|
+
* prettifyValue(1234.5, { processing: { decimalPlaces: 2 }, format: { prefix: '$' } }); // => '$1,234.5'
|
|
58
63
|
* @throws
|
|
59
64
|
* - INVALID_VALUE: if the value isn't a finite number or BigNumber throws an error
|
|
60
65
|
* - INVALID_DECIMAL_PLACES: if the number of decimal places is invalid for any reason
|
|
@@ -70,10 +75,13 @@ export const prettifyValue = (value, config = {}) => {
|
|
|
70
75
|
}).toFormat(buildFormatConfig(config.format));
|
|
71
76
|
}
|
|
72
77
|
catch (error) {
|
|
73
|
-
if (
|
|
78
|
+
if (isException(error)) {
|
|
74
79
|
throw error;
|
|
75
80
|
}
|
|
76
|
-
throw new Exception(
|
|
81
|
+
throw new Exception('The value could not be formatted.', {
|
|
82
|
+
code: ERRORS.INVALID_BIGNUMBER_FORMAT,
|
|
83
|
+
cause: error,
|
|
84
|
+
});
|
|
77
85
|
}
|
|
78
86
|
};
|
|
79
87
|
/**
|
|
@@ -82,8 +90,10 @@ export const prettifyValue = (value, config = {}) => {
|
|
|
82
90
|
* @param value The value.
|
|
83
91
|
* @returns Whether it's a BigNumber.
|
|
84
92
|
* @example
|
|
85
|
-
*
|
|
86
|
-
*
|
|
93
|
+
* import { getBigNumber, isBigNumber } from 'jg-bignumber';
|
|
94
|
+
*
|
|
95
|
+
* isBigNumber(getBigNumber(1)); // => true
|
|
96
|
+
* isBigNumber(1); // => false
|
|
87
97
|
*/
|
|
88
98
|
export const isBigNumber = (value) => BigNumber.isBigNumber(value);
|
|
89
99
|
/**
|
|
@@ -91,9 +101,11 @@ export const isBigNumber = (value) => BigNumber.isBigNumber(value);
|
|
|
91
101
|
* @param value The value.
|
|
92
102
|
* @returns Whether it's a finite number.
|
|
93
103
|
* @example
|
|
94
|
-
* isNumber
|
|
95
|
-
*
|
|
96
|
-
* isNumber('
|
|
104
|
+
* import { isNumber } from 'jg-bignumber';
|
|
105
|
+
*
|
|
106
|
+
* isNumber('12.5'); // => true
|
|
107
|
+
* isNumber(Infinity); // => false
|
|
108
|
+
* isNumber('abc'); // => false
|
|
97
109
|
*/
|
|
98
110
|
export const isNumber = (value) => {
|
|
99
111
|
try {
|
|
@@ -109,8 +121,10 @@ export const isNumber = (value) => {
|
|
|
109
121
|
* @param value The value.
|
|
110
122
|
* @returns Whether it's an integer.
|
|
111
123
|
* @example
|
|
112
|
-
* isInteger
|
|
113
|
-
*
|
|
124
|
+
* import { isInteger } from 'jg-bignumber';
|
|
125
|
+
*
|
|
126
|
+
* isInteger('12'); // => true
|
|
127
|
+
* isInteger(12.5); // => false
|
|
114
128
|
*/
|
|
115
129
|
export const isInteger = (value) => {
|
|
116
130
|
try {
|
|
@@ -125,8 +139,10 @@ export const isInteger = (value) => {
|
|
|
125
139
|
* @param value The value.
|
|
126
140
|
* @returns Whether it's a float.
|
|
127
141
|
* @example
|
|
128
|
-
* isFloat
|
|
129
|
-
*
|
|
142
|
+
* import { isFloat } from 'jg-bignumber';
|
|
143
|
+
*
|
|
144
|
+
* isFloat(12.5); // => true
|
|
145
|
+
* isFloat('12'); // => false
|
|
130
146
|
*/
|
|
131
147
|
export const isFloat = (value) => {
|
|
132
148
|
try {
|