public RatingInfo.WeightingFactors CalculateMatchResultRelibilityFactor(Player player, Result r, Player opponent, float opponentFrequency, bool againstBenchmark, RatingRule rule)
        {
            /*
             * Match Result Reliabiliy Factor is A x B x C x D
             * Where:
             * A = Opponent's Player Rating Reliability
             * B = Match Format Reliability
             * C = Match Frequency Reliability
             * D = Match Competitiveness Coeffecient
             * E = Benchmark Match Coeffecient
             * F = Interpool Match Coeffecient
             */

            float a, b, c, d, rr, f;
            bool  collegeInterpoolApplied = false;

            a  = (rule.EnableOpponentRatingReliability) ? CalculateOpponentRatingReliability(opponent) : 10.0f;
            b  = (rule.EnableMatchFormatReliability) ? CalculateMatchFormatReliability(r, rule) : 1.0f;
            c  = (rule.EnableMatchFrequencyReliability) ? 2 / (opponentFrequency + 1) : 1.0f;
            d  = (rule.EnableMatchCompetitivenessCoeffecient) ? MatchCompetivenessCalculator.CalculateMatchCompetivenessCoeffecient(player, opponent, r, rule) : 1.0f;
            f  = (rule.EnableInterpoolCoeffecient) ? CalculateInterpoolCoefficient(player, opponent, rule, out collegeInterpoolApplied) : 1.0f;
            rr = a * b * c * d * f;
            float coef = 1.0f;

            if (againstBenchmark)
            {
                coef = (rule.EnableBenchmarkMatchCoeffecient) ? rule.BenchmarkMatchCoeffecient : 1.0f;
                rr   = rr * coef;
            }

            RatingInfo.WeightingFactors wf = new RatingInfo.WeightingFactors();
            wf.MatchFormatReliability          = b;
            wf.MatchFrequencyReliability       = c;
            wf.MatchCompetitivenessCoeffecient = d;
            wf.BenchmarkMatchCoeffecient       = coef;
            wf.OpponentRatingReliability       = a;
            wf.InterpoolCoeffecient            = f;
            // TESTING: use college interpool as match weight if it is applied
            //wf.MatchWeight = collegeInterpoolApplied ? (rule.interpoolCoefficientCollege*10) : (float)Math.Truncate(100000 * rr) / 100000;
            wf.MatchWeight = (float)Math.Truncate(100000 * rr) / 100000;
            return(wf);
        }
        public RatingInfo DoResultsCalculation(Player playerInfo, Result r, ArrayList results, Dictionary <int, Player> playerRepo, RatingRule rule, Dictionary <int, int> matchFrequency)
        {
            RatingInfo ratingInfo = new RatingInfo
            {
                SurfaceType          = r.SurfaceType,
                Date                 = r.ResultDate,
                IsMastersOrGrandslam = r.IsMastersOrGrandslam
            };
            var opponent = playerRepo[GetOpponentId(playerInfo.Id, r)]; //info about opponent

            //var opponent = GetOpponent(playerInfo.Id, r, playerRepo);
            if (opponent.BenchmarkRating != null && opponent.BenchmarkRating > 0)
            {
                opponent.Stats.Rating = (double)opponent.BenchmarkRating;
            }
            ratingInfo.Rating = CalculateDynamicRating(playerInfo, opponent, r, playerRepo, rule);
            if (float.IsNaN(ratingInfo.Rating))
            {
                System.Diagnostics.Debug.WriteLine(ratingInfo.Rating);
            }

            ratingInfo.AgainstBenchmark = (opponent.Stats.IsBenchmark) ? true : false;
            float opponentFrequency = 0;

            try
            {
                opponentFrequency = (float)matchFrequency[opponent.Id]; // value from dictionary
            }
            catch (Exception e)
            {
                _logger.LogWarning(e, opponent.Id.ToString());
            }
            RatingInfo.WeightingFactors wf = CalculateMatchResultRelibilityFactor(playerInfo, r, opponent, opponentFrequency, ratingInfo.AgainstBenchmark, rule);
            ratingInfo.Reliability      = wf.MatchWeight; //reliability for match
            ratingInfo.weightingFactors = wf;
            return(ratingInfo);
        }