feat: Feature 1.3 — Prop Analysis Engine with 6-step grading pipeline
Core intelligence for BetonBLK prop analysis: - POST /api/analyze/prop — single prop analysis - POST /api/analyze/batch — multi-prop analysis for parlay scanner - 6-step pipeline: season avg → recent form → situational splits → cross-book lines → kill conditions → grade (A/B/C/D) - 6 kill conditions: low_minutes, small_sample, b2b_high_usage, blowout_risk, split_conflict, no_opponent_data - Composite scoring with confidence (30-95), bonuses, penalties - Added spreads market to Odds API fetch (zero extra credits) - Full reasoning output with step-by-step breakdown 36 new tests (unit + integration), 128 total across all features Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
const { deltaToSignal, directedDelta } = require('../../src/utils/signals');
|
||||
|
||||
describe('signals', () => {
|
||||
describe('deltaToSignal', () => {
|
||||
test('0.0-0.49 maps to neutral', () => {
|
||||
expect(deltaToSignal(0)).toBe('neutral');
|
||||
expect(deltaToSignal(0.3)).toBe('neutral');
|
||||
expect(deltaToSignal(0.49)).toBe('neutral');
|
||||
});
|
||||
|
||||
test('0.5-1.99 maps to lean', () => {
|
||||
expect(deltaToSignal(0.5)).toBe('lean');
|
||||
expect(deltaToSignal(1.5)).toBe('lean');
|
||||
expect(deltaToSignal(1.99)).toBe('lean');
|
||||
});
|
||||
|
||||
test('2.0-3.99 maps to bullish', () => {
|
||||
expect(deltaToSignal(2.0)).toBe('bullish');
|
||||
expect(deltaToSignal(3.5)).toBe('bullish');
|
||||
});
|
||||
|
||||
test('>= 4.0 maps to strong_bullish', () => {
|
||||
expect(deltaToSignal(4.0)).toBe('strong_bullish');
|
||||
expect(deltaToSignal(7.0)).toBe('strong_bullish');
|
||||
});
|
||||
|
||||
test('negative deltas map to bearish equivalents', () => {
|
||||
expect(deltaToSignal(-0.3)).toBe('neutral');
|
||||
expect(deltaToSignal(-1.0)).toBe('lean_bearish');
|
||||
expect(deltaToSignal(-2.5)).toBe('bearish');
|
||||
expect(deltaToSignal(-5.0)).toBe('strong_bearish');
|
||||
});
|
||||
});
|
||||
|
||||
describe('directedDelta', () => {
|
||||
test('over: positive when avg > line', () => {
|
||||
expect(directedDelta(28, 26, 'over')).toBe(2);
|
||||
});
|
||||
|
||||
test('over: negative when avg < line', () => {
|
||||
expect(directedDelta(24, 26, 'over')).toBe(-2);
|
||||
});
|
||||
|
||||
test('under: inverts delta', () => {
|
||||
expect(directedDelta(28, 26, 'under')).toBe(-2);
|
||||
expect(directedDelta(24, 26, 'under')).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user