The Bar structure
        /// <summary>
        /// Refines the market data
        /// </summary>
        void RefineData()
        {
            // Fill In data gaps
            if (Configs.FillInDataGaps)
            {
                for (int bar = 1; bar < Bars; bar++)
                {
                    aBar[bar].Open = aBar[bar - 1].Close;
                    if (aBar[bar].Open > aBar[bar].High || aBar[bar].Close > aBar[bar].High)
                        aBar[bar].High = aBar[bar].Open > aBar[bar].Close ? aBar[bar].Open : aBar[bar].Close;
                    if (aBar[bar].Open < aBar[bar].Low || aBar[bar].Close < aBar[bar].Low)
                        aBar[bar].Low = aBar[bar].Open < aBar[bar].Close ? aBar[bar].Open : aBar[bar].Close;
                }
            }

            // Cuts off the bad data
            if (Configs.CutBadData)
            {
                int maxConsecutiveBars = 0;
                int maxConsecutiveBar  = 0;
                int consecutiveBars    = 0;
                int lastBar            = 0;

                for (int bar = 0; bar < Bars; bar++)
                {
                    if (Math.Abs(aBar[bar].Open - aBar[bar].Close) < Data.InstrProperties.Point / 2)
                    {
                        if (lastBar == bar - 1 || lastBar == 0)
                        {
                            consecutiveBars++;
                            lastBar = bar;

                            if (consecutiveBars > maxConsecutiveBars)
                            {
                                maxConsecutiveBars = consecutiveBars;
                                maxConsecutiveBar  = bar;
                            }
                        }
                    }
                    else
                    {
                        consecutiveBars = 0;
                    }
                }

                if (maxConsecutiveBars < 10)
                    maxConsecutiveBar = 0;

                int firstBar = Math.Max(maxConsecutiveBar, 1);
                for (int bar = firstBar; bar < Bars; bar++)
                    if ((Time(bar) - Time(bar - 1)).Days > 5 && period < 10080)
                        firstBar = bar;

                if (firstBar == 1)
                    firstBar = 0;

                if (firstBar > 0)
                {
                    Bar[] aBarCopy = new Bar[bars];
                    aBar.CopyTo(aBarCopy, 0);

                    aBar = new Bar[bars - firstBar];
                    for (int bar = firstBar; bar < bars; bar++)
                        aBar[bar - firstBar] = aBarCopy[bar];

                    bars = bars - firstBar;
                    isCut  = true;
                }
            }

            return;
        }
        /// <summary>
        /// Data Horizon - Cuts some data
        /// </summary>
        int DataHorizon()
        {
            if (bars < Configs.MIN_BARS) return 0;

            int startBar = 0;
            int endBar   = bars - 1;
            DateTime startDate = new DateTime(startYear, startMonth, startDay);
            DateTime endDate   = new DateTime(endYear,   endMonth,   endDay);

            // Set the starting date
            if (useStartDate && aBar[0].Time < startDate)
            {
                for (int bar = 0; bar < bars; bar++)
                {
                    if (aBar[bar].Time >= startDate)
                    {
                        startBar  = bar;
                        break;
                    }
                }
            }

            // Set the end date
            if (useEndDate && aBar[bars - 1].Time > endDate)
            {   // We need to cut out the newest bars
                for (int bar = 0; bar < bars; bar++)
                {
                    if (aBar[bar].Time >= endDate)
                    {
                        endBar  = bar - 1;
                        break;
                    }
                }
            }

            if (endBar - startBar > maxBars - 1)
            {
                startBar = endBar - maxBars + 1;
            }

            if (endBar - startBar < Configs.MIN_BARS)
            {
                startBar = endBar - Configs.MIN_BARS + 1;
                if (startBar < 0)
                {
                    startBar = 0;
                    endBar = Configs.MIN_BARS - 1;
                }
            }

            // Cut the data
            if (startBar > 0 || endBar < bars - 1)
            {
                Bar[] aBarCopy = new Bar[bars];
                aBar.CopyTo(aBarCopy, 0);

                int newBars = endBar - startBar + 1;

                aBar = new Bar[newBars];
                for (int bar = startBar; bar <= endBar; bar++)
                    aBar[bar - startBar] = aBarCopy[bar];

                bars   = newBars;
                timeUpdate = aBar[newBars - 1].Time;
                isCut  = true;
            }

            return 0;
        }
        /// <summary>
        /// Refines the market data
        /// </summary>
        private void RefineData()
        {
            // Fill In data gaps
            if (Configs.FillInDataGaps)
            {
                for (int bar = 1; bar < Bars; bar++)
                {
                    _aBar[bar].Open = _aBar[bar - 1].Close;
                    if (_aBar[bar].Open > _aBar[bar].High || _aBar[bar].Close > _aBar[bar].High)
                        _aBar[bar].High = _aBar[bar].Open > _aBar[bar].Close ? _aBar[bar].Open : _aBar[bar].Close;
                    if (_aBar[bar].Open < _aBar[bar].Low || _aBar[bar].Close < _aBar[bar].Low)
                        _aBar[bar].Low = _aBar[bar].Open < _aBar[bar].Close ? _aBar[bar].Open : _aBar[bar].Close;
                }
            }

            // Cuts off the bad data
            if (Configs.CutBadData)
            {
                int maxConsecutiveBars = 0;
                int maxConsecutiveBar = 0;
                int consecutiveBars = 0;
                int lastBar = 0;

                for (int bar = 0; bar < Bars; bar++)
                {
                    if (Math.Abs(_aBar[bar].Open - _aBar[bar].Close) < Data.InstrProperties.Point/2)
                    {
                        if (lastBar == bar - 1 || lastBar == 0)
                        {
                            consecutiveBars++;
                            lastBar = bar;

                            if (consecutiveBars > maxConsecutiveBars)
                            {
                                maxConsecutiveBars = consecutiveBars;
                                maxConsecutiveBar = bar;
                            }
                        }
                    }
                    else
                    {
                        consecutiveBars = 0;
                    }
                }

                if (maxConsecutiveBars < 10)
                    maxConsecutiveBar = 0;

                int firstBar = Math.Max(maxConsecutiveBar, 1);
                for (int bar = firstBar; bar < Bars; bar++)
                    if ((Time(bar) - Time(bar - 1)).Days > 5 && Period < 10080)
                        firstBar = bar;

                if (firstBar == 1)
                    firstBar = 0;

                if (firstBar > 0)
                {
                    var aBarCopy = new Bar[Bars];
                    _aBar.CopyTo(aBarCopy, 0);

                    _aBar = new Bar[Bars - firstBar];
                    for (int bar = firstBar; bar < Bars; bar++)
                        _aBar[bar - firstBar] = aBarCopy[bar];

                    Bars = Bars - firstBar;
                    Cut = true;
                }
            }
        }
        /// <summary>
        /// Data Horizon - Cuts some data
        /// </summary>
        private void DataHorizon()
        {
            if (Bars < Configs.MinBars) return;

            int startBar = 0;
            int endBar = Bars - 1;

            // Set the starting date
            if (UseStartTime && _aBar[0].Time < StartTime)
            {
                for (int bar = 0; bar < Bars; bar++)
                {
                    if (_aBar[bar].Time >= StartTime)
                    {
                        startBar = bar;
                        break;
                    }
                }
            }

            // Set the end date
            if (UseEndTime && _aBar[Bars - 1].Time > EndTime)
            {
                // We need to cut out the newest bars
                for (int bar = 0; bar < Bars; bar++)
                {
                    if (_aBar[bar].Time >= EndTime)
                    {
                        endBar = bar - 1;
                        break;
                    }
                }
            }

            if (endBar - startBar > MaxBars - 1)
            {
                startBar = endBar - MaxBars + 1;
            }

            if (endBar - startBar < Configs.MinBars)
            {
                startBar = endBar - Configs.MinBars + 1;
                if (startBar < 0)
                {
                    startBar = 0;
                    endBar = Configs.MinBars - 1;
                }
            }

            // Cut the data
            if (startBar > 0 || endBar < Bars - 1)
            {
                var aBarCopy = new Bar[Bars];
                _aBar.CopyTo(aBarCopy, 0);

                int newBars = endBar - startBar + 1;

                _aBar = new Bar[newBars];
                for (int bar = startBar; bar <= endBar; bar++)
                    _aBar[bar - startBar] = aBarCopy[bar];

                Bars = newBars;
                Update = _aBar[newBars - 1].Time;
                Cut = true;
            }
        }
        /// <summary>
        /// Parses the input data file.
        /// </summary>
        /// <param name="dataFile">The data file as string.</param>
        /// <param name="regexDataFile">The compiled regex.</param>
        /// <param name="barsCount">The count of bars of the data file.</param>
        /// <returns>Returns a parsed bar array.</returns>
        private Bar[] ParseInput(string dataFile, Regex regexDataFile, int barsCount)
        {
            var barList = new Bar[barsCount];

            string line;
            var bar = 0;
            var stringReader = new StringReader(dataFile);

            while ((line = stringReader.ReadLine()) != null)
            {
                var match = regexDataFile.Match(line);
                if (!match.Success) continue;

                var year = int.Parse(match.Groups["year"].Value);
                year = CorrectProblemYear2000(year);
                var month = int.Parse(match.Groups["month"].Value);
                var day = int.Parse(match.Groups["day"].Value);
                var hour = int.Parse(match.Groups["hour"].Value);
                var min = int.Parse(match.Groups["min"].Value);
                var seconds = match.Groups["sec"].Value;
                var sec = (seconds == "" ? 0 : int.Parse(seconds));

                barList[bar].Time   = new DateTime(year, month, day, hour, min, sec);
                barList[bar].Open   = ParseDouble(match.Groups["open"].Value);
                barList[bar].High   = ParseDouble(match.Groups["high"].Value);
                barList[bar].Low    = ParseDouble(match.Groups["low"].Value);
                barList[bar].Close  = ParseDouble(match.Groups["close"].Value);
                barList[bar].Volume = int.Parse(match.Groups["volume"].Value);

                bar++;
            }

            stringReader.Close();

            return barList;
        }
        /// <summary>
        /// Parses the input data file.
        /// </summary>
        /// <param name="dataFile">The data file as string.</param>
        /// <param name="regexDataFile">The compiled regex.</param>
        /// <param name="period">The period of data file.</param>
        /// <returns>Returns a parsed bar array.</returns>
        private List<Bar> ParseInput(string dataFile, Regex regexDataFile, int period)
        {
            var barList = new List<Bar>();

            string line;
            var stringReader = new StringReader(dataFile);

            while ((line = stringReader.ReadLine()) != null)
            {
                Match match = regexDataFile.Match(line);
                if (!match.Success) continue;

                int year = int.Parse(match.Groups["year"].Value);
                year = CorrectProblemYear2000(year);
                int month = int.Parse(match.Groups["month"].Value);
                int day   = int.Parse(match.Groups["day"].Value);
                int hour  = 0;
                int min   = 0;
                int sec   = 0;
                if (!_isOptionalDataFile)
                {
                    hour = int.Parse(match.Groups["hour"].Value);
                    min  = int.Parse(match.Groups["min"].Value);
                    string seconds = match.Groups["sec"].Value;
                    sec  = (seconds == "" ? 0 : int.Parse(seconds));
                }
                var time = new DateTime(year, month, day, hour, min, sec);

                if (Configs.CutSatSunData && IsSatSun(time))
                    continue;
                if(!CheckTimePeriod(time, period))
                    continue;

                var bar = new Bar
                              {
                                  Time = time,
                                  Open = ParseDouble(match.Groups["open"].Value),
                                  High = ParseDouble(match.Groups["high"].Value),
                                  Low = ParseDouble(match.Groups["low"].Value),
                                  Close = ParseDouble(match.Groups["close"].Value),
                                  Volume = int.Parse(match.Groups["volume"].Value)
                              };
                barList.Add(bar);
            }

            stringReader.Close();

            if (barList.Count == 0)
                throw new Exception(Language.T("Could not count the data bars!"));

            return barList;
        }