const HITTING_STATS = [ 'hits', 'total_bases', 'home_runs', 'rbis', 'runs_scored', 'strikeouts_batter', 'walks', 'stolen_bases', ]; const PITCHING_STATS = [ 'strikeouts', 'earned_runs', 'outs_recorded', 'walks_allowed', 'hits_allowed', 'pitches_thrown', ]; const ALL_MLB_STATS = [...HITTING_STATS, ...PITCHING_STATS]; function isMlbStatType(statType) { return ALL_MLB_STATS.includes(statType); } function calculateMlbEdge(playerAvg, line, direction) { if (playerAvg == null || line == null) return 0; if (direction === 'over') { return ((playerAvg - line) / line) * 100; } // under return ((line - playerAvg) / line) * 100; } function gradeMlbProp({ player, stat_type, line, direction, seasonAvg, recentAvg, killConditions = [] }) { if (!isMlbStatType(stat_type)) { return { grade: 'D', confidence: 30, edge_pct: 0, composite: 0 }; } const seasonEdge = calculateMlbEdge(seasonAvg, line, direction); const recentEdge = calculateMlbEdge(recentAvg, line, direction); // Weighted composite: 60% season, 40% recent const edge_pct = Math.round((seasonEdge * 0.6 + recentEdge * 0.4) * 100) / 100; // Grade thresholds based on edge let grade; if (edge_pct >= 5) { grade = 'A'; } else if (edge_pct >= 3) { grade = 'B'; } else if (edge_pct >= 1) { grade = 'C'; } else { grade = 'D'; } // Confidence based on edge magnitude let confidence; if (grade === 'A') { confidence = Math.min(95, 80 + Math.floor(edge_pct)); } else if (grade === 'B') { confidence = Math.min(79, 65 + Math.floor(edge_pct)); } else if (grade === 'C') { confidence = Math.min(64, 50 + Math.floor(edge_pct * 2)); } else { confidence = Math.max(30, 45 + Math.floor(edge_pct)); } // Kill condition penalty: cap at C and reduce confidence by 15 per condition if (killConditions.length > 0) { if (grade === 'A' || grade === 'B') { grade = 'C'; } confidence -= killConditions.length * 15; } confidence = Math.max(30, Math.min(95, confidence)); const composite = Math.round(edge_pct * 100) / 100; return { grade, confidence, edge_pct, composite }; } module.exports = { gradeMlbProp, calculateMlbEdge, isMlbStatType, HITTING_STATS, PITCHING_STATS, ALL_MLB_STATS };