All files / src/pricing round.ts

0% Statements 0/12
0% Branches 0/5
0% Functions 0/1
0% Lines 0/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28                                                       
/**
 * Round `value` to `dp` decimal places using decimal half-even (round half to
 * even / banker's rounding) so it mirrors the server's `Decimal(round(x, n))`.
 *
 * This intentionally matches Python's *decimal* half-even behaviour, NOT Python
 * float `round()` (e.g. `roundHalfEven(2.675, 2) === 2.68`, whereas float
 * `round(2.675, 2)` yields 2.67).
 *
 * Targeted at the money domain: small magnitudes and `dp <= 3`. The `EPS`
 * half-detection tolerance is tuned for that domain and is not intended for
 * arbitrary large magnitudes or high precision.
 */
export function roundHalfEven(value: number, dp: number): number {
  Iif (!isFinite(value)) return value;
  const factor = Math.pow(10, dp);
  const scaled = value * factor;
  const floor = Math.floor(scaled);
  const diff = scaled - floor;
  const EPS = 1e-9;
  let rounded: number;
  if (Math.abs(diff - 0.5) < EPS) {
    rounded = floor % 2 === 0 ? floor : floor + 1;
  } else {
    rounded = Math.round(scaled);
  }
  return rounded / factor;
}