/// <summary>
        /// Returns a bar open time by giving its index, it supports both past and future bars but the future bars provided
        /// open time is an approximation based on previous bars time differences not exact open time
        /// </summary>
        /// <param name="bars">The market series</param>
        /// <param name="barIndex">The bar index</param>
        /// <returns>DateTime</returns>
        public static DateTime GetOpenTime(this Bars bars, double barIndex)
        {
            var currentIndex = bars.GetIndex();

            TimeSpan timeDiff = bars.GetTimeDiff();

            var indexDiff = barIndex - currentIndex;

            var indexDiffAbs = Math.Abs(indexDiff);

            var result = indexDiff <= 0 ? bars.OpenTimes[(int)barIndex] : bars.OpenTimes[currentIndex];

            if (indexDiff > 0)
            {
                for (var i = 1; i <= indexDiffAbs; i++)
                {
                    do
                    {
                        result = result.Add(timeDiff);
                    }while (result.DayOfWeek == DayOfWeek.Saturday || result.DayOfWeek == DayOfWeek.Sunday);
                }
            }

            var barIndexFraction = barIndex % 1;

            var barIndexFractionInMinutes = timeDiff.TotalMinutes * barIndexFraction;

            result = result.AddMinutes(barIndexFractionInMinutes);

            return(result);
        }
        /// <summary>
        /// Returns the bar elapsed time or open time - close time
        /// </summary>
        /// <param name="bars">Bars</param>
        /// <param name="index">Bar index</param>
        /// <returns>TimeSpane</returns>
        public static TimeSpan GetBarElapsedTime(this Bars bars, int index)
        {
            if (bars.GetIndex() <= index)
            {
                throw new ArgumentException("There must be another bar available after the current bar to calculate its" +
                                            " elapsed time");
            }

            return(bars.OpenTimes[index + 1] - bars.OpenTimes[index]);
        }
        /// <summary>
        /// Returns the most common time difference between two bar of a market series
        /// </summary>
        /// <param name="bars"></param>
        /// <returns>TimeSpan</returns>
        public static TimeSpan GetTimeDiff(this Bars bars)
        {
            var index = bars.GetIndex();

            if (index < 4)
            {
                throw new InvalidOperationException("Not enough data in market series to calculate the time difference");
            }

            var timeDiffs = new List <TimeSpan>();

            for (var i = index; i >= index - 4; i--)
            {
                timeDiffs.Add(bars.OpenTimes[i] - bars.OpenTimes[i - 1]);
            }

            return(timeDiffs.GroupBy(diff => diff).OrderBy(diffGroup => diffGroup.Count()).Last().First());
        }