Пример #1
0
        public AnalyticData ProcessData()
        {
            AnalyticData          data               = new AnalyticData();
            Streak                currentStreak      = Streak.Up;
            Streak                previousRound      = Streak.NoData;
            int                   currentStreakCount = 0;
            decimal               priceAccumulator   = 0;
            long                  volumeAccumulator  = 0;
            Dictionary <int, int> sequenceDist       = new Dictionary <int, int>();

            data.Symbol      = Symbol;
            data.RoundsCount = this.PriceSeries.Count;
            InitAnalytics(data);

            foreach (PriceData round in PriceSeries)
            {
                priceAccumulator  += RoundPriceAvg(round);
                volumeAccumulator += round.Volume;

                MinsMaxs(data, round);

                StreakCalculator(data, ref currentStreak, ref previousRound, ref currentStreakCount, round, sequenceDist);
            }

            CalculateAverages(sequenceDist, data, volumeAccumulator, priceAccumulator, data.RoundsCount);

            return(data);
        }
Пример #2
0
 public PlayarStatisistics(Guid id, PlayarName name)
 {
     Id = id;
     Name = name;
     Score = InitialScore;
     ScoreHistory = new LimitedQueue<Tuple<double, Activity>>(KeepLatestResults);
     Offensive = new GamePercentage();
     Defensive = new GamePercentage();
     Total = new GamePercentage();
     _winning = new Streak(5);
     _loosing = new Streak(5);
 }
Пример #3
0
        private void StreakCalculator(AnalyticData data, ref Streak currentStreak, ref Streak previousRound, ref int currentStreakCount, PriceData round, Dictionary <int, int> sequenceDist)
        {
            if (round.ClosingPrice > round.OpenPrice)
            {
                data.UpsideRoundsCount++;

                if (currentStreak == Streak.Down && previousRound == Streak.Up)
                {
                    data.Sequence.Add($"{currentStreakCount}U");
                    UpdateSequenceDictionary(sequenceDist, -currentStreakCount);
                    if (currentStreakCount > data.MaxDownsideStreakCount)
                    {
                        data.MaxDownsideStreakCount = currentStreakCount;
                    }
                    currentStreakCount = 2;
                    currentStreak      = Streak.Up;
                }
                else
                {
                    currentStreakCount++;
                }

                previousRound = Streak.Up;
            }
            else if (round.ClosingPrice <= round.OpenPrice)
            {
                data.DownsideRoundsCount++;

                if (currentStreak == Streak.Up && previousRound == Streak.Down)
                {
                    data.Sequence.Add($"{currentStreakCount}D");
                    UpdateSequenceDictionary(sequenceDist, currentStreakCount);
                    if (currentStreakCount > data.MaxUpsideStreakCount)
                    {
                        data.MaxUpsideStreakCount = currentStreakCount;
                    }
                    currentStreakCount = 2;
                    currentStreak      = Streak.Down;
                }
                else
                {
                    currentStreakCount++;
                }

                previousRound = Streak.Down;
            }
        }
Пример #4
0
        /// <summary>
        /// Compare Streaks with current kill streak.
        /// </summary>
        private void CheackForStreak()
        {
            var highestStreak = new Streak();

            foreach (var streak in Streaks)
            {
                var nextStreak = streak;
                if (nextStreak.RequiredKills > highestStreak.RequiredKills)
                {
                    highestStreak = nextStreak;
                }

                if (m_currentKillStreak >= nextStreak.RequiredKills)
                {
                    ScriptableTextDisplay.DisableAll(8);
                    ScriptableTextDisplay.InitializeScriptableText(8, transform.position, streak.Name);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Create new attempt records and return them in a list. All new attempts should be after the most recent successful attempt.
        /// </summary>
        /// <param name="achievementTypeCache">The achievement type cache.</param>
        /// <param name="streak">The streak.</param>
        /// <param name="mostRecentClosedAttempt">The most recent closed attempt.</param>
        /// <returns></returns>
        protected override List <AchievementAttempt> CreateNewAttempts(AchievementTypeCache achievementTypeCache, Streak streak, AchievementAttempt mostRecentClosedAttempt)
        {
            var rockContext       = new RockContext();
            var streakTypeService = new StreakTypeService(rockContext);
            var streakTypeCache   = StreakTypeCache.Get(streak.StreakTypeId);

            // Validate the attribute values
            var numberToAchieve = GetAttributeValue(achievementTypeCache, AttributeKey.NumberToAchieve).AsInteger();

            if (numberToAchieve <= 0)
            {
                ExceptionLogService.LogException($"StreakAchievement.CreateNewAttempts cannot process because the NumberToAchieve attribute is less than 1");
                return(null);
            }

            var attributeTimespanDays = GetAttributeValue(achievementTypeCache, AttributeKey.TimespanInDays).AsIntegerOrNull();

            if (attributeTimespanDays.HasValue && attributeTimespanDays.Value <= 0)
            {
                ExceptionLogService.LogException($"StreakAchievement.CreateNewAttempts cannot process because the TimespanInDays attribute is less than 1");
                return(null);
            }

            // Calculate the date range where new achievements can be validly found
            var attributeMinDate = GetAttributeValue(achievementTypeCache, AttributeKey.StartDateTime).AsDateTime();
            var attributeMaxDate = GetAttributeValue(achievementTypeCache, AttributeKey.EndDateTime).AsDateTime();
            var minDate          = CalculateMinDateForAchievementAttempt(streak.EnrollmentDate, mostRecentClosedAttempt, attributeMinDate, numberToAchieve);
            var maxDate          = CalculateMaxDateForAchievementAttempt(minDate, attributeMaxDate);

            // Get the max date that streaks can be broken. This is to avoid breaking streaks while people still have time to
            // engage in that day or week (because it is the current day or week)
            var maxDateForStreakBreaking = StreakTypeService.GetMaxDateForStreakBreaking(streakTypeCache);

            // Track the attempts in a list that will be returned. The int is the streak count for that attempt
            var attempts = new List <AchievementAttempt>();
            var streaks  = new List <ComputedStreak>();

            // Define what happens for each bit in the date range
            bool iterationAction(int currentUnit, DateTime currentDate, bool hasOccurrence, bool hasEngagement, bool hasExclusion)
            {
                // If there is an engagement and a timespan, then this is a possible attempt. If there is no timespan then only one
                // attempt needs to be tracked at a time
                if (hasOccurrence && hasEngagement && (attributeTimespanDays.HasValue || !streaks.Any()))
                {
                    streaks.Add(new ComputedStreak(currentDate));
                }
                else if (hasOccurrence && !hasEngagement && !hasExclusion && streaks.Any())
                {
                    // Break the streaks and close an attempt if there is an unexcused absence
                    var longestStreak = streaks.First();
                    attempts.Add(GetAttemptFromStreak(longestStreak, numberToAchieve, currentDate <= maxDateForStreakBreaking));
                    streaks.Clear();
                    return(false);
                }

                for (var i = streaks.Count - 1; i >= 0; i--)
                {
                    var computedStreak = streaks[i];

                    if (hasOccurrence && hasEngagement)
                    {
                        // Increment the streak
                        computedStreak.Count++;
                        computedStreak.EndDate = currentDate;

                        // Check for a fulfilled attempt
                        if (computedStreak.Count >= numberToAchieve)
                        {
                            streaks.Clear();

                            if (achievementTypeCache.AllowOverAchievement)
                            {
                                streaks.Add(computedStreak);
                                i = 0;
                            }
                            else
                            {
                                attempts.Add(GetAttemptFromStreak(computedStreak, numberToAchieve, !achievementTypeCache.AllowOverAchievement));
                                break;
                            }
                        }
                    }

                    // If there is a timespan and this streak is too old, then the attempt is closed
                    if (attributeTimespanDays.HasValue)
                    {
                        var inclusiveAge = (currentDate - computedStreak.StartDate).Days + 1;

                        if (inclusiveAge >= attributeTimespanDays.Value)
                        {
                            var timedOutAttempt = GetAttemptFromStreak(computedStreak, numberToAchieve, true);
                            attempts.Add(timedOutAttempt);
                            streaks.RemoveAt(i);

                            // Remove more recently started streaks that started before the next valid start date (based
                            // on the deficiency of this timed out attempt)
                            var nextValidStartDate = CalculateMinDateForAchievementAttempt(streak.EnrollmentDate, timedOutAttempt, attributeMinDate, numberToAchieve);

                            for (var j = streaks.Count - 1; j >= i; j--)
                            {
                                var moreRecentStreak = streaks[j];

                                if (moreRecentStreak.StartDate < nextValidStartDate)
                                {
                                    streaks.RemoveAt(j);
                                }
                            }
                        }
                    }
                }

                return(false);
            }

            // Iterate through the streak date for the date range specified
            streakTypeService.IterateStreakMap(streakTypeCache, streak.PersonAliasId, minDate, maxDate, iterationAction, out var errorMessage);

            if (!errorMessage.IsNullOrWhiteSpace())
            {
                ExceptionLogService.LogException($"StreakAchievement.CreateNewAttempts got an error calling StreakTypeService.IterateStreakMap: {errorMessage}");
                return(null);
            }

            // The longest leftover streak is an open attempt
            if (streaks.Any())
            {
                var longestStreak = streaks.First();
                attempts.Add(GetAttemptFromStreak(longestStreak, numberToAchieve, false));
            }

            return(attempts);
        }
Пример #6
0
        /// <summary>
        /// Update the open attempt record if there are changes.
        /// </summary>
        /// <param name="openAttempt"></param>
        /// <param name="achievementTypeCache">The achievement type cache.</param>
        /// <param name="streak">The streak.</param>
        protected override void UpdateOpenAttempt(AchievementAttempt openAttempt, AchievementTypeCache achievementTypeCache, Streak streak)
        {
            var rockContext       = new RockContext();
            var streakTypeService = new StreakTypeService(rockContext);
            var streakTypeCache   = GetStreakTypeCache(achievementTypeCache);

            // Validate the attribute values
            var numberToAchieve = GetAttributeValue(achievementTypeCache, AttributeKey.NumberToAchieve).AsInteger();

            if (numberToAchieve <= 0)
            {
                ExceptionLogService.LogException($"StreakAchievement.UpdateOpenAttempt cannot process because the numberToAchieve attribute is less than 1");
                return;
            }

            var attributeTimespanDays = GetAttributeValue(achievementTypeCache, AttributeKey.TimespanInDays).AsIntegerOrNull();

            if (attributeTimespanDays.HasValue && attributeTimespanDays.Value <= 0)
            {
                ExceptionLogService.LogException($"StreakAchievement.UpdateOpenAttempt cannot process because the TimespanInDays attribute is less than 1");
                return;
            }

            // Calculate the date range where the open attempt can be validly fulfilled
            var attributeMaxDate = GetAttributeValue(achievementTypeCache, AttributeKey.EndDateTime).AsDateTime();
            var minDate          = openAttempt.AchievementAttemptStartDateTime;
            var maxDate          = CalculateMaxDateForAchievementAttempt(minDate, attributeMaxDate);

            // Get the max date that streaks can be broken. This is to avoid breaking streaks while people still have time to
            // engage in that day or week (because it is the current day or week)
            var maxDateForStreakBreaking = StreakTypeService.GetMaxDateForStreakBreaking(streakTypeCache);

            // Track the streak
            var computedStreak = new ComputedStreak(minDate)
            {
                EndDate = minDate
            };

            // Define what happens for each bit in the date range
            bool iterationAction(int currentUnit, DateTime currentDate, bool hasOccurrence, bool hasEngagement, bool hasExclusion)
            {
                var iterationCanStop = false;

                // If there is an engagement, then increment the streak
                if (hasOccurrence && hasEngagement)
                {
                    computedStreak.Count++;
                    computedStreak.EndDate = currentDate;

                    // Check for a fulfilled attempt
                    if (computedStreak.Count >= numberToAchieve)
                    {
                        ApplyStreakToAttempt(computedStreak, openAttempt, numberToAchieve, !achievementTypeCache.AllowOverAchievement);
                        iterationCanStop = !achievementTypeCache.AllowOverAchievement;
                    }
                }
                else if (hasOccurrence && !hasEngagement && !hasExclusion)
                {
                    // Break the streak and close the attempt if there is an unexcused absence
                    ApplyStreakToAttempt(computedStreak, openAttempt, numberToAchieve, currentDate <= maxDateForStreakBreaking);
                    iterationCanStop = true;
                }

                // If there is a timespan and this streak is too old, then the attempt is closed
                if (attributeTimespanDays.HasValue)
                {
                    var inclusiveAge = (currentDate - computedStreak.StartDate).Days + 1;

                    if (inclusiveAge >= attributeTimespanDays.Value)
                    {
                        ApplyStreakToAttempt(computedStreak, openAttempt, numberToAchieve, currentDate <= maxDateForStreakBreaking);
                        iterationCanStop = true;
                    }
                }

                return(iterationCanStop);
            }

            // Iterate through the streak date for the date range specified
            streakTypeService.IterateStreakMap(streakTypeCache, streak.PersonAliasId, minDate, maxDate, iterationAction, out var errorMessage);

            if (!errorMessage.IsNullOrWhiteSpace())
            {
                ExceptionLogService.LogException($"StreakAchievement.UpdateOpenAttempt got an error calling StreakTypeService.IterateStreakMap: {errorMessage}");
                return;
            }

            // If the attempt wasn't closed in the iteration, then it will remain open
            if (!openAttempt.IsClosed)
            {
                var progress = CalculateProgress(computedStreak.Count, numberToAchieve);

                openAttempt.Progress     = progress;
                openAttempt.IsSuccessful = progress >= 1m;
            }
        }
Пример #7
0
        public int GetMaxStreak(IEnumerable<int> values)
        {
            int zerosCount = 0;
            var streaksList = new List<Streak>();
            var sortedSet = new SortedSet<int>();

            foreach (var value in values)
            {
                if (value == 0)
                {
                    zerosCount++;
                }
                else
                {
                    sortedSet.Add(value);
                }
            }

            var valuesIterator = sortedSet.GetEnumerator();
            valuesIterator.MoveNext();
            var previousValue = valuesIterator.Current;
            var firstStreak = new Streak { ZerosLeft = zerosCount, StartValue = valuesIterator.Current };
            streaksList.Add(firstStreak);

            if (sortedSet.Count == 0)
            {
                return zerosCount;
            }

            if (sortedSet.Count == 1)
            {
                firstStreak.EndValue = valuesIterator.Current;
            }

            while (valuesIterator.MoveNext())
            {
                int missingValuesGap = valuesIterator.Current - previousValue - 1;
                int streaksCount = streaksList.Count;

                if (missingValuesGap > 0)
                {
                    streaksList.Add(new Streak { ZerosLeft = zerosCount, StartValue = valuesIterator.Current });
                }

                for (int index = 0; index < streaksCount; index++)
                {
                    var streak = streaksList[index];

                    if (!streak.IsSealed)
                    {
                        if (streak.ZerosLeft >= missingValuesGap)
                        {
                            streak.ZerosLeft -= missingValuesGap;
                        }
                        else
                        {
                            streak.EndValue = previousValue;
                            streak.IsSealed = true;
                        }

                        streak.EndValue = missingValuesGap == 0 ? valuesIterator.Current : previousValue;
                    }
                }

                previousValue = valuesIterator.Current;
            }

            return streaksList.Max(x => x.GetValue());
        }
Пример #8
0
        public int GetMaxStreak(IEnumerable <int> values)
        {
            int zerosCount  = 0;
            var streaksList = new List <Streak>();
            var sortedSet   = new SortedSet <int>();

            foreach (var value in values)
            {
                if (value == 0)
                {
                    zerosCount++;
                }
                else
                {
                    sortedSet.Add(value);
                }
            }

            var valuesIterator = sortedSet.GetEnumerator();

            valuesIterator.MoveNext();
            var previousValue = valuesIterator.Current;
            var firstStreak   = new Streak {
                ZerosLeft = zerosCount, StartValue = valuesIterator.Current
            };

            streaksList.Add(firstStreak);

            if (sortedSet.Count == 0)
            {
                return(zerosCount);
            }

            if (sortedSet.Count == 1)
            {
                firstStreak.EndValue = valuesIterator.Current;
            }

            while (valuesIterator.MoveNext())
            {
                int missingValuesGap = valuesIterator.Current - previousValue - 1;
                int streaksCount     = streaksList.Count;

                if (missingValuesGap > 0)
                {
                    streaksList.Add(new Streak {
                        ZerosLeft = zerosCount, StartValue = valuesIterator.Current
                    });
                }

                for (int index = 0; index < streaksCount; index++)
                {
                    var streak = streaksList[index];

                    if (!streak.IsSealed)
                    {
                        if (streak.ZerosLeft >= missingValuesGap)
                        {
                            streak.ZerosLeft -= missingValuesGap;
                        }
                        else
                        {
                            streak.EndValue = previousValue;
                            streak.IsSealed = true;
                        }

                        streak.EndValue = missingValuesGap == 0 ? valuesIterator.Current : previousValue;
                    }
                }

                previousValue = valuesIterator.Current;
            }

            return(streaksList.Max(x => x.GetValue()));
        }
Пример #9
0
        /// <summary>
        /// Update the open attempt record if there are changes.
        /// </summary>
        /// <param name="openAttempt"></param>
        /// <param name="streakTypeAchievementTypeCache">The streak type achievement type cache.</param>
        /// <param name="streak">The streak.</param>
        protected override void UpdateOpenAttempt(StreakAchievementAttempt openAttempt, StreakTypeAchievementTypeCache streakTypeAchievementTypeCache, Streak streak)
        {
            var rockContext       = new RockContext();
            var streakTypeService = new StreakTypeService(rockContext);
            var streakTypeCache   = streakTypeAchievementTypeCache.StreakTypeCache;

            // Validate the attribute values
            var numberToAccumulate = GetAttributeValue(streakTypeAchievementTypeCache, AttributeKey.NumberToAccumulate).AsInteger();

            if (numberToAccumulate <= 0)
            {
                ExceptionLogService.LogException($"AccumulativeAchievement.UpdateOpenAttempt cannot process because the NumberToAccumulate attribute is less than 1");
                return;
            }

            var attributeTimespanDays = GetAttributeValue(streakTypeAchievementTypeCache, AttributeKey.TimespanInDays).AsIntegerOrNull();

            if (attributeTimespanDays.HasValue && attributeTimespanDays.Value <= 0)
            {
                ExceptionLogService.LogException($"AccumulativeAchievement.UpdateOpenAttempt cannot process because the TimespanInDays attribute is less than 1");
                return;
            }

            // Calculate the date range where the open attempt can be validly fulfilled
            var attributeMaxDate = GetAttributeValue(streakTypeAchievementTypeCache, AttributeKey.EndDateTime).AsDateTime();
            var minDate          = openAttempt.AchievementAttemptStartDateTime;
            var maxDate          = CalculateMaxDateForAchievementAttempt(minDate, attributeMaxDate);

            // Track the accumulation
            var accumulation = new ComputedStreak(minDate)
            {
                EndDate = minDate
            };

            // Define what happens for each bit in the date range
            bool iterationAction(int currentUnit, DateTime currentDate, bool hasOccurrence, bool hasEngagement, bool hasExclusion)
            {
                // If there is an engagement, then increment the accumulation
                if (hasOccurrence && hasEngagement)
                {
                    accumulation.Count++;
                    accumulation.EndDate = currentDate;

                    // Check for a fulfilled attempt
                    if (accumulation.Count >= numberToAccumulate)
                    {
                        var progress = CalculateProgress(accumulation.Count, numberToAccumulate);

                        openAttempt.AchievementAttemptEndDateTime = accumulation.EndDate;
                        openAttempt.Progress     = progress;
                        openAttempt.IsClosed     = !streakTypeAchievementTypeCache.AllowOverAchievement;
                        openAttempt.IsSuccessful = progress >= 1m;
                    }
                }

                // If there is a timespan and this accumulation is too old, then the attempt is closed
                if (attributeTimespanDays.HasValue)
                {
                    var inclusiveAge = (currentDate - accumulation.StartDate).Days + 1;

                    if (inclusiveAge >= attributeTimespanDays.Value)
                    {
                        var progress = CalculateProgress(accumulation.Count, numberToAccumulate);

                        openAttempt.AchievementAttemptEndDateTime = accumulation.EndDate;
                        openAttempt.Progress     = progress;
                        openAttempt.IsClosed     = true;
                        openAttempt.IsSuccessful = progress >= 1m;
                    }
                }

                return(openAttempt.IsClosed);
            }

            // Iterate through the streak date for the date range specified
            streakTypeService.IterateStreakMap(streakTypeCache, streak.PersonAliasId, minDate, maxDate, iterationAction, out var errorMessage);

            if (!errorMessage.IsNullOrWhiteSpace())
            {
                ExceptionLogService.LogException($"AccumulativeAchievement.UpdateOpenAttempt got an error calling StreakTypeService.IterateStreakMap: {errorMessage}");
                return;
            }

            // If the attempt wasn't closed in the iteration, then it will remain open
            if (!openAttempt.IsClosed)
            {
                var progress = CalculateProgress(accumulation.Count, numberToAccumulate);

                openAttempt.Progress     = progress;
                openAttempt.IsSuccessful = progress >= 1m;
            }
        }
Пример #10
0
 /// <summary>
 /// Create new attempt records and return them in a list. All new attempts should be after the most recent successful attempt.
 /// </summary>
 /// <param name="achievementTypeCache">The achievement type cache.</param>
 /// <param name="streak">The streak.</param>
 /// <param name="mostRecentSuccess">The most recent successful attempt.</param>
 /// <returns></returns>
 protected abstract List <AchievementAttempt> CreateNewAttempts(AchievementTypeCache achievementTypeCache, Streak streak, AchievementAttempt mostRecentSuccess);
Пример #11
0
 /// <summary>
 /// Update the open attempt record if there are changes. Be sure to close the attempt if it is no longer possible to make
 /// progress on this open attempt.
 /// </summary>
 /// <param name="openAttempt">The open attempt.</param>
 /// <param name="achievementTypeCache">The achievement type cache.</param>
 /// <param name="streak">The streak.</param>
 protected abstract void UpdateOpenAttempt(AchievementAttempt openAttempt, AchievementTypeCache achievementTypeCache, Streak streak);