Files
cup26/src/lib/odds.test.ts
T
NilsBriggen d887664fce v3 Phase A (urgent): bookmaker odds capture — the Model-vs-Market benchmark
- docs/V3-GIGA-PLAN.md: the v3 plan (data lake to 7+GB, GIGA ensemble, scoreboard,
  UI clarity) with the honest reframe: perfect accuracy = perfect calibration;
  'beat the betting sites' = a live public head-to-head, scored with proper rules.
- src/lib/odds.ts: American-ml → decimal, de-vig (normalize away the margin),
  overround; 3 vitest cases incl. tonight's real opening lines.
- ESPN core odds adapter (server/src/ingest/espnOdds.ts): captures DraftKings
  1X2 moneylines + O/U + spread per fixture; follows $ref pointer items.
- odds_history table (insert-if-changed → clean line-movement history);
  scheduler odds sweep every 3h over a 14-day horizon, first sweep at boot;
  /api/odds + /api/odds/:num. Odds are a benchmark ONLY — never a model input.
- Boot speed-up: fixture↔event mapping skips dates already fully mapped.
- Verified: 54 fixtures captured with real moneylines locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 17:03:15 +02:00

29 lines
1.0 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { americanToDecimal, deVig, overround } from './odds';
describe('americanToDecimal', () => {
it('converts favourites and underdogs', () => {
expect(americanToDecimal(-235)).toBeCloseTo(1.4255, 3);
expect(americanToDecimal(340)).toBeCloseTo(4.4, 3);
expect(americanToDecimal(100)).toBeCloseTo(2.0, 6);
expect(americanToDecimal(-100)).toBeCloseTo(2.0, 6);
});
});
describe('deVig', () => {
it('produces probabilities that sum to 1 with the margin removed', () => {
// tonight's real opening-match lines: Mexico -235 / draw +340 / SA +750
const p = deVig(-235, 340, 750)!;
expect(p.home + p.draw + p.away).toBeCloseTo(1, 9);
expect(p.home).toBeGreaterThan(0.6); // heavy favourite
expect(p.away).toBeLessThan(0.15);
// raw implied sum exceeds 1 (the vig)
expect(overround(-235, 340, 750)).toBeGreaterThan(1);
});
it('returns null on missing lines', () => {
expect(deVig(null, 340, 750)).toBeNull();
expect(deVig(-235, 0, 750)).toBeNull();
});
});