private static double CalculateNewRating(GlickoPlayer competitor, List<GlickoOpponent> opponents, double newRatingDeviation) { var sum = 0.0; foreach(var opponent in opponents) { sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent)); } return competitor.GlickoRating + ((Math.Pow(newRatingDeviation, 2)) * sum); }
private static double RatingImprovement(GlickoPlayer competitor, List <GlickoOpponent> opponents, double variance) { double sum = 0; foreach (var opponent in opponents) { sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent)); } return(variance * sum); }
private static double CalculateNewRating(GlickoPlayer competitor, List <GlickoOpponent> opponents, double newRatingDeviation) { var sum = 0.0; foreach (var opponent in opponents) { sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent)); } return(competitor.GlickoRating + ((Math.Pow(newRatingDeviation, 2)) * sum)); }
public void GlickoUpdateNoOpponents() { var expectedValue = 0.06; var player1Opponents = new List<GlickoOpponent>(); player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents); var actualValue = player1.Volatility; Assert.AreEqual(expectedValue, actualValue); }
private static double CalculateNewVolatility(GlickoPlayer competitor, List<GlickoOpponent> opponents, double variance) { var rankingChange = RatingImprovement(competitor, opponents, variance); var rankDeviation = competitor.GlickoRatingDeviation; var A = VolatilityTransform(competitor.Volatility); var a = VolatilityTransform(competitor.Volatility); var k = 1; double B = 0.0; if (Math.Pow(rankingChange, 2) > (Math.Pow(competitor.GlickoRatingDeviation, 2) + variance)) { B = Math.Log(Math.Pow(rankingChange, 2) - Math.Pow(competitor.GlickoRatingDeviation, 2) - variance); } if (Math.Pow(rankingChange, 2) <= (Math.Pow(competitor.GlickoRatingDeviation, 2) + variance)) { var x = VolatilityTransform(competitor.Volatility) - (k * VolatilityChange); while(VolatilityFunction(x, rankingChange, rankDeviation, variance, competitor.Volatility) < 0) { k++; } } B = VolatilityTransform(competitor.Volatility) - (k * VolatilityChange); var fA = VolatilityFunction(A, rankingChange, rankDeviation, variance, competitor.Volatility); var fB = VolatilityFunction(B, rankingChange, rankDeviation, variance, competitor.Volatility); while (Math.Abs(B - A) > ConvergenceTolerance) { var C = A + ((A - B) * fA / (fB - fA)); var fC = VolatilityFunction(C, rankingChange, rankDeviation, variance, competitor.Volatility); if ((fC * fB) < 0) { A = B; fA = fB; } else { fA = fA / 2; } B = C; fB = fC; } return Math.Exp(A / 2); }
private static double ComputeVariance(GlickoPlayer competitor, List <GlickoOpponent> opponents) { double sum = 0; foreach (var opponent in opponents) { var eDeltaPhi = Edeltaphi(competitor.GlickoRating, opponent); sum += Math.Pow(opponent.GPhi, 2) * eDeltaPhi * (1 - eDeltaPhi); } return(Math.Pow(sum, -1)); }
private static double CalculateNewVolatility(GlickoPlayer competitor, List <GlickoOpponent> opponents, double variance) { var rankingChange = RatingImprovement(competitor, opponents, variance); var rankDeviation = competitor.GlickoRatingDeviation; var A = VolatilityTransform(competitor.Volatility); var a = VolatilityTransform(competitor.Volatility); double B; if (Math.Pow(rankingChange, 2) > (Math.Pow(competitor.GlickoRatingDeviation, 2) + variance)) { B = Math.Log(Math.Pow(rankingChange, 2) - Math.Pow(competitor.GlickoRatingDeviation, 2) - variance); } else { var k = 1; double x; do { x = a - (k * VolatilityChange); k++; } while (VolatilityFunction(x, rankingChange, rankDeviation, variance, competitor.Volatility) < 0); B = x; } var fA = VolatilityFunction(A, rankingChange, rankDeviation, variance, competitor.Volatility); var fB = VolatilityFunction(B, rankingChange, rankDeviation, variance, competitor.Volatility); while (Math.Abs(B - A) > ConvergenceTolerance) { var C = A + ((A - B) * fA / (fB - fA)); var fC = VolatilityFunction(C, rankingChange, rankDeviation, variance, competitor.Volatility); if ((fC * fB) < 0) { A = B; fA = fB; } else { fA = fA / 2; } B = C; fB = fC; } return(Math.Exp(A / 2)); }
public void GlickoUpdateRatingDeviationCorrect() { var expectedValue = 151.52; var player1Opponents = new List<GlickoOpponent> { new GlickoOpponent(player2, 1), new GlickoOpponent(player3, 0), new GlickoOpponent(player4, 0) }; player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents); var actualValue = Math.Round(player1.RatingDeviation, 2); Assert.AreEqual(expectedValue, actualValue); }
public void GlickoUpdateCorrect() { var expectedValue = 0.059995984286488495; var player1Opponents = new List<GlickoOpponent> { new GlickoOpponent(player2, 1), new GlickoOpponent(player3, 0), new GlickoOpponent(player4, 0) }; player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents); var actualValue = player1.Volatility; Assert.AreEqual(expectedValue, actualValue); }
public void RankTournament(int tournamentId) { var tournament = _tournamentDbHelper.GetTournamentPlayersAndMatches(tournamentId); var newRankings = new List<PlayerGlickoHistory>(); foreach (var attendee in tournament.TournamentAttendees) { var playerOpponents = new List<GlickoOpponent>(); var playerRanking = attendee.Player.PlayerGlickoHistories.OrderByDescending(x => x.Tournament.Date).First(); var glickoPlayer = new GlickoPlayer((double)playerRanking.Ranking, (double)playerRanking.Deviation, (double)playerRanking.Volatility); var matches = tournament.Matches.Where(x => x.Player1Id == attendee.PlayerId || x.Player2Id == attendee.PlayerId); foreach (var match in matches) { var opponentPlayer = match.Player1Id != attendee.PlayerId ? match.Player1 : match.Player2; var opponentRank = opponentPlayer.PlayerGlickoHistories.OrderByDescending(x => x.TournamentId == tournamentId).First(); var opponentGlicko = new GlickoPlayer((double)opponentRank.Ranking, (double)opponentRank.Deviation, (double)opponentRank.Volatility); var result = match.WinnerId == attendee.PlayerId ? 1 : 0; var glickoOpponent = new GlickoOpponent(opponentGlicko, result); playerOpponents.Add(glickoOpponent); } glickoPlayer = GlickoCalculator.CalculateRanking(glickoPlayer, playerOpponents); var newRank = new PlayerGlickoHistory() { Deviation = Convert.ToDecimal(glickoPlayer.RatingDeviation), Ranking = Convert.ToDecimal(glickoPlayer.Rating), Volatility = Convert.ToDecimal(glickoPlayer.Volatility), PlayerId = attendee.PlayerId, TournamentId = tournamentId }; newRankings.Add(newRank); } UpdateRankingsDb(newRankings); }
public static GlickoPlayer CalculateRanking(GlickoPlayer competitor, List<GlickoOpponent> opponents) { var variance = ComputeVariance(competitor, opponents); var updatedVolatility = CalculateNewVolatility(competitor, opponents, variance); var preratingDeviation = CalculatePreRatingDeviation(competitor.GlickoRatingDeviation, updatedVolatility); var newRatingDeviation = CalculateNewRatingDeviation(preratingDeviation, variance); var newRating = CalculateNewRating(competitor, opponents, newRatingDeviation); competitor.RatingDeviation = ConvertRatingDeviationToOriginal(newRatingDeviation); if (opponents.Count == 0) return competitor; competitor.Rating = ConvertRatingToOriginal(newRating); competitor.Volatility = updatedVolatility; return competitor; }
public static GlickoPlayer CalculateRanking(GlickoPlayer competitor, List <GlickoOpponent> opponents) { var variance = ComputeVariance(competitor, opponents); var updatedVolatility = CalculateNewVolatility(competitor, opponents, variance); var preratingDeviation = CalculatePreRatingDeviation(competitor.GlickoRatingDeviation, updatedVolatility); var newRatingDeviation = CalculateNewRatingDeviation(preratingDeviation, variance); var newRating = CalculateNewRating(competitor, opponents, newRatingDeviation); competitor.RatingDeviation = ConvertRatingDeviationToOriginal(newRatingDeviation); if (opponents.Count == 0) { return(competitor); } competitor.Rating = ConvertRatingToOriginal(newRating); competitor.Volatility = updatedVolatility; return(competitor); }
static void Main(string[] args) { var player1 = new GlickoPlayer(ratingDeviation: 200); var player2 = new GlickoPlayer(1400, 30); var player3 = new GlickoPlayer(1550, 100); var player4 = new GlickoPlayer(1700, 300); var player1Opponents = new List<GlickoOpponent> { new GlickoOpponent(player2, 1), new GlickoOpponent(player3, 0), new GlickoOpponent(player4, 0) }; Console.WriteLine(String.Format("Player ranking: {0}", player1.Rating)); Console.WriteLine(String.Format("Player ranking deviation: {0}", player1.RatingDeviation)); player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents); Console.WriteLine(String.Format("Player ranking: {0}", player1.Rating)); Console.WriteLine(String.Format("Player ranking deviation: {0}", player1.RatingDeviation)); Console.ReadKey(); }
private static double RatingImprovement(GlickoPlayer competitor, List<GlickoOpponent> opponents, double variance) { double sum = 0; foreach (var opponent in opponents) { sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent)); } return variance * sum; }
private static double Edeltaphi(double playerRating, GlickoPlayer opponent) { return(1 / (1 + (Math.Exp(-opponent.GPhi * (playerRating - opponent.GlickoRating))))); }
private static double ComputeVariance(GlickoPlayer competitor, List<GlickoOpponent> opponents) { double sum = 0; foreach (var opponent in opponents) { var eDeltaPhi = Edeltaphi(competitor.GlickoRating, opponent); sum += Math.Pow(opponent.GPhi, 2) * eDeltaPhi * (1 - eDeltaPhi); } return Math.Pow(sum, -1); }
private static double Edeltaphi(double playerRating, GlickoPlayer opponent) { return 1 / (1 + (Math.Exp(-opponent.GPhi * (playerRating - opponent.GlickoRating)))); }
public void GlickoUpdateRatingDeviationNoOpponents() { var expectedValue = 200.27; var player1Opponents = new List<GlickoOpponent>(); player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents); var actualValue = Math.Round(player1.RatingDeviation, 2); Assert.AreEqual(expectedValue, actualValue); }