public void Import(string connectionString, StatbookModel statbook, bool assumeATeams) { _connection = new SqlConnection(connectionString); try { _connection.Open(); _transaction = _connection.BeginTransaction(); // insert leagues LeagueGateway leagueGateway = new LeagueGateway(_connection, _transaction); var leagues = leagueGateway.GetAllLeagues(); League homeLeague = leagues.FirstOrDefault(l => l.Name.ToLower() == statbook.HomeTeam.LeagueName.ToLower()); League awayLeague = leagues.FirstOrDefault(l => l.Name.ToLower() == statbook.AwayTeam.LeagueName.ToLower()); int maxID = leagues.Select(l => l.ID).Max(); if(homeLeague == null) { homeLeague = leagueGateway.GetLeague(maxID + 1, statbook.HomeTeam.LeagueName, statbook.Date, false); maxID++; } if(awayLeague == null) { awayLeague = leagueGateway.GetLeague(maxID + 1, statbook.AwayTeam.LeagueName, statbook.Date, false); maxID++; } // insert teams TeamGateway teamGateway = new TeamGateway(_connection, _transaction); Team homeTeam, awayTeam; if (assumeATeams) { homeTeam = teamGateway.GetATeam(homeLeague.ID); awayTeam = teamGateway.GetATeam(awayLeague.ID); } else { homeTeam = teamGateway.GetTeam(statbook.HomeTeam.Name, homeLeague.ID, "A", false); awayTeam = teamGateway.GetTeam(statbook.AwayTeam.Name, awayLeague.ID, "A", false); } // insert bout BoutGateway boutGateway = new BoutGateway(_connection, _transaction); if(!boutGateway.DoesBoutExist(homeTeam.ID, awayTeam.ID, statbook.Date)) { Bout bout = boutGateway.GetBout(homeTeam.ID, awayTeam.ID, statbook.Date); BoutDataImport(statbook, bout, homeTeam, awayTeam); } else { // bout already exists Console.WriteLine(string.Format("Bout between {0} and {1} on {2} already exists.", homeTeam.Name, awayTeam.Name, statbook.Date)); } _transaction.Commit(); } finally { _connection.Close(); } }
public TeamPlayerPerformanceCalculator(string connString) { _connectionString = connString; SqlConnection connection = new SqlConnection(_connectionString); connection.Open(); SqlTransaction transaction = connection.BeginTransaction(); // get bouts var bouts = new BoutGateway(connection, transaction).GetBouts().OrderBy(b => b.BoutDate); IList<Jam> jams = new JamGateway(connection, transaction).GetAllJams(); IList<JamPlayer> jamPlayers = new JamPlayerGateway(connection, transaction).GetJamPlayers(); var jamPlayerMap = jamPlayers.GroupBy(jp => jp.JamID).ToDictionary(g => g.Key, g => g.ToList()); foreach(Bout bout in bouts) { var boutJams = jams.Where(j => j.BoutID == bout.ID); // get teamplayerperformance values // scrape FTS? // get FTS data for this bout (input ratings, differential, ratings change) // Calculate an estimated Team Str based on play rate of players double homeTeamStrength, awayTeamStrength; CalculateEstimatedTeamStrength(boutJams, bout, jamPlayerMap, out homeTeamStrength, out awayTeamStrength); // Calculate Expected Ratio from Team Str comparison CalculateExpectedHomeTeamShare(bout, homeTeamStrength, awayTeamStrength); // Calculate Expected Delta (Modify both sides scores equally?) // Convert expected delta to PerfAgainstAverage // ??? Compare Sum of PerfAgainstAverage to Actual Delta // ??? Adjust player Ratings to align Team Str with results } }
public IList<Dictionary<int, PlayerPerformance>> GetAllPlayerPointPerformances(int numberOfIterations) { // pull data SqlConnection connection = new SqlConnection(_connectionString); connection.Open(); SqlTransaction transaction = connection.BeginTransaction(); var players = new PlayerGateway(connection, transaction).GetAllPlayers().GroupBy(p => p.ID).ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.TeamID)); var jams = new JamGateway(connection, transaction).GetAllJams().OrderBy(j => j.ID); var jamBoutMap = jams.ToDictionary(j => j.ID, j => j.BoutID); var jpe = new JamPlayerEffectivenessGateway(connection, transaction).GetAllJamPlayerEffectiveness(); var jamData = new JamDataGateway(connection, transaction).GetAllJamData() .GroupBy(jd => jd.JamID) .ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.TeamID)); var teams = new TeamGateway(connection, transaction).GetAllTeams().ToDictionary(t => t.ID); var bouts = new BoutGateway(connection, transaction).GetBouts().ToDictionary(t => t.ID); var penalties = new PenaltyGateway(connection, transaction).GetAllPenalties() .GroupBy(p => p.JamID) .ToDictionary( g => g.Key, g => g.GroupBy(g2 => g2.PlayerID).ToDictionary(g3 => g3.Key, g3 => g3.ToList())); var pgs = new PenaltyGroupGateway(connection, transaction).GetAllPenaltyGroups(); Dictionary<int, int> boxTimeEstimates = new BoxTimeEstimateGateway(connection, transaction).GetAllBoxTimeEstimates(); Dictionary<FoulComparison, Dictionary<int, float>> sss = new SituationalScoreGateway(connection, transaction).GetAllSituationalScores(); AveragePenaltyCostPerJam avgPenCost = new AveragePenaltyCostGateway(connection, transaction).GetAveragePenaltyCost(); Dictionary<int, Dictionary<int, JamPlayer>> jamPlayerMap = new JamPlayerGateway(connection, transaction).GetJamPlayers() .GroupBy(jp => jp.JamID) .ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.PlayerID)); transaction.Commit(); connection.Close(); Dictionary<FoulComparison, float> medians = CalculateMedianScores(sss); PenaltyCostCalculator ppcCalc = new PenaltyCostCalculator(_connectionString); Dictionary<int, double> groupPenaltyCostMap = PenaltyCostCalculator.CalculatePointCosts(jamData, jamPlayerMap, pgs, boxTimeEstimates, sss); Dictionary<int, double> jamTotalPortionMap = new Dictionary<int, double>(300); var previousResult = GenerateInitialPlayerPerformance(players, jams, jpe, jamData, teams, bouts, penalties, pgs, avgPenCost, medians, groupPenaltyCostMap, jamTotalPortionMap); List<Dictionary<int, PlayerPerformance>> result = new List<Dictionary<int, PlayerPerformance>>(numberOfIterations); result.Add(previousResult); int i = 0; while(i < numberOfIterations) { previousResult = GeneratePlayerPerformanceIteration(previousResult, jams, jamData, jamTotalPortionMap, jpe, avgPenCost); result.Add(previousResult); i++; } return result; }
public void Import(string connectionString, StatbookModel statbook) { _connection = new SqlConnection(connectionString); try { _connection.Open(); _transaction = _connection.BeginTransaction(); // insert leagues LeagueGateway leagueGateway = new LeagueGateway(_connection, _transaction); var leagues = leagueGateway.GetAllLeagues(); League homeLeague = leagues.FirstOrDefault(l => l.Name.ToLower() == statbook.HomeTeam.LeagueName.ToLower()); League awayLeague = leagues.FirstOrDefault(l => l.Name.ToLower() == statbook.AwayTeam.LeagueName.ToLower()); int maxID = leagues.Select(l => l.ID).Max(); if(homeLeague == null || awayLeague == null) { throw new InvalidOperationException("Bad league name"); } // for the basic importer, we'll just take whatever A team this league has, rather than worrying about validating the team name TeamGateway teamGateway = new TeamGateway(_connection, _transaction); Team homeTeam = teamGateway.GetATeam(homeLeague.ID); Team awayTeam = teamGateway.GetATeam(awayLeague.ID); // insert bout BoutGateway boutGateway = new BoutGateway(_connection, _transaction); if(!boutGateway.DoesBoutExist(homeTeam.ID, awayTeam.ID, statbook.Date)) { Bout bout = boutGateway.GetBout(homeTeam.ID, awayTeam.ID, statbook.Date); BoutDataImport(statbook, bout, homeTeam, awayTeam); } else { // bout already exists Console.WriteLine(string.Format("Bout between {0} and {1} on {2} already exists.", homeTeam.Name, awayTeam.Name, statbook.Date)); } _transaction.Commit(); } finally { _connection.Close(); } }
public IList<PlayerPerformance> GetPlayerPointPerformancesForTeam(int teamID) { // pull data SqlConnection connection = new SqlConnection(_connectionString); connection.Open(); SqlTransaction transaction = connection.BeginTransaction(); var players = new PlayerGateway(connection, transaction).GetPlayersForTeam(teamID).ToDictionary(p => p.ID); var jams = new JamGateway(connection, transaction).GetJamsForTeamAfterDate(teamID, new DateTime(2016,1,1)).OrderBy(j => j.ID); var jamBoutMap = jams.ToDictionary(j => j.ID, j => j.BoutID); var jpe = new JamPlayerEffectivenessGateway(connection, transaction).GetJamPlayerEffectivenessForTeam(teamID); var jamData = new JamDataGateway(connection, transaction).GetJamDataForTeam(teamID).ToDictionary(jd => jd.JamID); var teams = new TeamGateway(connection, transaction).GetAllTeams().ToDictionary(t => t.ID); var bouts = new BoutGateway(connection, transaction).GetBouts().ToDictionary(t => t.ID); var penalties = new PenaltyGateway(connection, transaction).GetPenaltiesForTeam(teamID) .GroupBy(p => p.JamID) .ToDictionary( g => g.Key, g => g.GroupBy(g2 => g2.PlayerID).ToDictionary(g3 => g3.Key, g3 => g3.ToList())); var pgs = new PenaltyGroupGateway(connection, transaction).GetPenaltyGroupsForTeam(teamID); Dictionary<int, int> boxTimeEstimates = new BoxTimeEstimateGateway(connection, transaction).GetAllBoxTimeEstimates(); Dictionary<FoulComparison, Dictionary<int, float>> sss = new SituationalScoreGateway(connection, transaction).GetAllSituationalScores(); AveragePenaltyCostPerJam avgPenCost = new AveragePenaltyCostGateway(connection, transaction).GetAveragePenaltyCost(); transaction.Commit(); connection.Close(); Dictionary<FoulComparison, float> medians = CalculateMedianScores(sss); PenaltyCostCalculator ppcCalc = new PenaltyCostCalculator(_connectionString); Dictionary<int, double> groupPenaltyCostMap = ppcCalc.CalculatePointCostsForTeam(jamData, pgs, boxTimeEstimates, sss); Dictionary<int, PlayerPerformance> pps = new Dictionary<int, PlayerPerformance>(25); Dictionary<int, double> jamTotalPortionMap = new Dictionary<int, double>(300); foreach(Jam jam in jams) { var pe = jpe[jam.ID]; foreach(JamPlayerEffectiveness eff in pe.Values) { // get/set PlayerPerformance object if(!pps.ContainsKey(eff.PlayerID)) { pps[eff.PlayerID] = new PlayerPerformance { Player = players[eff.PlayerID], Bouts = new List<BoutPerformance>() }; } PlayerPerformance curPP = pps[eff.PlayerID]; // get/set BoutPerformance object Bout bout = bouts[jam.BoutID]; BoutPerformance bp = null; if (!curPP.Bouts.Any() || curPP.Bouts.Last().BoutID != bout.ID) { bp = new BoutPerformance { BoutID = bout.ID, AwayTeamName = teams[bout.AwayTeamID].Name, HomeTeamName = teams[bout.HomeTeamID].Name, BoutDate = bout.BoutDate, Jams = new List<JamPerformance>() }; curPP.Bouts.Add(bp); } else { bp = curPP.Bouts.Last(); } JamTeamData jd = jamData[jam.ID]; int penaltyCount = penalties.ContainsKey(jam.ID) && penalties[jam.ID].ContainsKey(eff.PlayerID) ? penalties[jam.ID][eff.PlayerID].Count() : 0; JamPerformance jp = new JamPerformance { BlockerJamPercentage = eff.IsJammer ? 0 : eff.JamPortion, DeltaPercentile = eff.BaseQuality, IsFirstHalf = jam.IsFirstHalf, JamID = jam.ID, JammerJamPercentage = eff.IsJammer ? eff.JamPortion : 0, JamNumber = jam.JamNumber, JamPenalties = penaltyCount, MedianDelta = medians[jd.FoulComparison], PenaltyCost = 0, PointDelta = jd.PointDelta }; if (jamTotalPortionMap.ContainsKey(jam.ID)) { jamTotalPortionMap[jam.ID] += eff.IsJammer ? eff.JamPortion * 4 : eff.JamPortion; } else { jamTotalPortionMap[jam.ID] = eff.IsJammer ? eff.JamPortion * 4 : eff.JamPortion; } bp.Jams.Add(jp); } } foreach(PenaltyGroup pg in pgs) { foreach(Penalty p in pg.Penalties) { if (jams.Any(j => j.ID == p.JamID)) { JamPerformance jp = pps[p.PlayerID].Bouts.SelectMany(b => b.Jams).Where(j => j.JamID == p.JamID).First(); jp.PenaltyCost += groupPenaltyCostMap[pg.GroupID]; } } } foreach(PlayerPerformance pp in pps.Values) { RollUpPlayerPerformance(avgPenCost, jamTotalPortionMap, pp); } CalculateTeamAverages(pps, bouts); foreach(PlayerPerformance pp in pps.Values) { pp.BlockerPerformance.PlayerValueVersusTeamAverage = pp.Bouts.Sum(b => b.BlockerPerformance.PlayerValueVersusTeamAverage); pp.JammerPerformance.PlayerValueVersusTeamAverage = pp.Bouts.Sum(b => b.JammerPerformance.PlayerValueVersusTeamAverage); } return pps.Values.ToList(); }