Files
vyndr/src/services/mlbGrader.js
T

77 lines
2.2 KiB
JavaScript

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 };