Files

78 lines
2.3 KiB
JavaScript

const { oddsToImplied, impliedToAmerican, devig, clv } = require('../../src/utils/odds');
describe('odds utility', () => {
describe('oddsToImplied', () => {
test('+150 → ~0.40', () => {
expect(oddsToImplied(150)).toBeCloseTo(0.4, 3);
});
test('-110 → ~0.524', () => {
expect(oddsToImplied(-110)).toBeCloseTo(0.5238, 3);
});
test('invalid input returns null', () => {
expect(oddsToImplied(null)).toBeNull();
expect(oddsToImplied('abc')).toBeNull();
expect(oddsToImplied(0)).toBeNull();
});
});
describe('impliedToAmerican', () => {
test('0.5 → -100', () => {
expect(impliedToAmerican(0.5)).toBe(-100);
});
test('0.4 → +150', () => {
expect(impliedToAmerican(0.4)).toBe(150);
});
test('round-trips with oddsToImplied within 1 cent', () => {
// +100 and -100 both encode p=0.5 (even money) so we skip the boundary.
for (const odds of [-200, -150, -110, +150, +250]) {
const back = impliedToAmerican(oddsToImplied(odds));
expect(Math.abs(back - odds)).toBeLessThanOrEqual(1);
}
});
test('out-of-range prob returns null', () => {
expect(impliedToAmerican(0)).toBeNull();
expect(impliedToAmerican(1)).toBeNull();
expect(impliedToAmerican(NaN)).toBeNull();
});
});
describe('devig', () => {
test('symmetric -110/-110 normalizes to 0.5/0.5', () => {
const { fairOver, fairUnder } = devig(-110, -110);
expect(fairOver).toBeCloseTo(0.5, 5);
expect(fairUnder).toBeCloseTo(0.5, 5);
});
test('asymmetric -130/+110 — over more likely, both sum to 1.0', () => {
const { fairOver, fairUnder } = devig(-130, +110);
expect(fairOver + fairUnder).toBeCloseTo(1.0, 5);
expect(fairOver).toBeGreaterThan(0.5);
});
test('invalid odds returns null', () => {
expect(devig(0, -110)).toBeNull();
expect(devig(-110, null)).toBeNull();
});
});
describe('clv', () => {
test('positive when closing > graded', () => {
expect(clv(0.50, 0.55)).toBeCloseTo(0.05, 5);
});
test('negative when closing < graded', () => {
expect(clv(0.55, 0.50)).toBeCloseTo(-0.05, 5);
});
test('invalid input returns null', () => {
expect(clv('x', 0.5)).toBeNull();
expect(clv(0.5, undefined)).toBeNull();
});
});
});