示例#1
0
 public Tick(DateTime dt, int number, float price, int volue)
 {
     this.number = number;
     this.price  = price;
     this.volume = volue;
     this.dt     = DateTime2Int.Int(dt);
 }
示例#2
0
        public static TicksFile LoadFromAllTicksFileList(string dataDir, StreamReader sr)
        {
            string fileName = Path.Combine(dataDir, sr.ReadLine());

            if (!File.Exists(fileName))
            {
                l.Error("Файл не существует " + fileName);
                return(null);
            }
            if ((sr.ReadLine() != CaptionLine1) || (sr.ReadLine() != CaptionLine2))
            {
                l.Error("Не верный формат файла " + fileName);
                return(null);
            }

            string symbol = sr.ReadLine();

            System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.InvariantCulture;
            DateTime startDate = DateTime.ParseExact(sr.ReadLine(), "yyyy.MM.dd", provider);
            DateTime endDate   = DateTime.ParseExact(sr.ReadLine(), "yyyy.MM.dd", provider).AddDays(1).AddSeconds(-1);

            int count = int.Parse(sr.ReadLine());

            return(new TicksFile(fileName, symbol, DateTime2Int.Int(startDate), DateTime2Int.Int(endDate), count));
        }
示例#3
0
        TicksFile GetFile(int dt)
        {
            _lock.AcquireReaderLock(1000);
            try
            {
                if ((file_GetFileCache != null) && (file_GetFileCache.Include(dt)))
                {
                    return(file_GetFileCache);
                }

                foreach (TicksFile f in ticksFileList)
                {
                    if (f.Include(dt))
                    {
                        file_GetFileCache = f;
                        return(f);
                    }
                }

                LockCookie lc = _lock.UpgradeToWriterLock(1000);
                try
                {
                    DateTime startDate = new DateTime(DateTime2Int.DateTime(dt).Year, DateTime2Int.DateTime(dt).Month, 1);
                    DateTime endDate   = startDate.AddMonths(1).AddSeconds(-1);

                    string fileName = Path.Combine(dataDir, symbol + " " + startDate.ToString("yyyyMM") + TicksFile.FileExt);
                    //Создаю уникальное имя для файла, чтобы не затереть данные
                    int i = 1;
                    while (File.Exists(fileName))
                    {
                        l.Error("Не уникальное имя файла с тиками " + fileName);
                        fileName = Path.Combine(dataDir, symbol + " " + startDate.ToString("yyyyMM") + "[" + i + "]" + TicksFile.FileExt);
                        ++i;
                    }

                    TicksFile newTickFile = new TicksFile(
                        fileName,
                        symbol,
                        DateTime2Int.Int(startDate),
                        DateTime2Int.Int(endDate));

                    ticksFileList.Add(newTickFile);

                    staticLock.AcquireWriterLock(10000);
                    try { allTicksFileList.Add(newTickFile); }
                    finally { staticLock.ReleaseLock(); }

                    file_GetFileCache = newTickFile;
                    return(newTickFile);
                }
                finally
                {
                    _lock.DowngradeFromWriterLock(ref lc);
                }
            }
            finally
            {
                _lock.ReleaseReaderLock();
            }
        }
示例#4
0
        public TicksFile(string fileName)
        {
            this.fileName = fileName;
            if (!File.Exists(fileName))
            {
                l.Error("Файл не существует" + fileName);
                return;
            }
            using (StreamReader sr = new StreamReader(fileName, new System.Text.UTF8Encoding()))
            {
                if ((sr.ReadLine() != CaptionLine1) || (sr.ReadLine() != CaptionLine2))
                {
                    l.Error("Не верный формат файла " + fileName);
                    return;
                }

                symbol = Core.Data.GetSymbol(sr.ReadLine());

                System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.InvariantCulture;
                startDateTime = DateTime2Int.Int(DateTime.ParseExact(sr.ReadLine(), "yyyy.MM.dd", provider));
                endDateTime   = DateTime2Int.Int(DateTime.ParseExact(sr.ReadLine(), "yyyy.MM.dd", provider).AddDays(1).AddSeconds(-1));

                Count = int.Parse(sr.ReadLine());
            }
        }
示例#5
0
        TicksFile forConcatCreateFile(DateTime from, DateTime till, string maskForDateTime, int count)
        {
            int intTill = DateTime2Int.Int(till);
            int intFrom = DateTime2Int.Int(from);

            // Проверяю, возможно данный файл уже существует
            foreach (TicksFile tf in ticksFileList)
            {
                if ((tf.startDateTime == intFrom) && (tf.endDateTime == intTill))
                {
                    return(tf);
                }
            }

            // ну а если нет, то создаю
            IBar bar = Get(DateTime2Int.Int(from));

            if (bar == null)
            {
                bar = First;
            }

            IList <IBar> ticks = new List <IBar>(count);

            while ((bar != null) && (bar.DT <= intTill))
            {
                if (bar.DT >= intFrom)
                {
                    ticks.Add(bar);
                }
                bar = GetNext(bar);
            }

            string fileName = string.Empty;

            if (maskForDateTime == string.Empty)
            {
                fileName = Path.Combine(dataDir, symbol + TicksFile.FileExt);
            }
            else
            {
                fileName = Path.Combine(dataDir, symbol + from.ToString(maskForDateTime) + TicksFile.FileExt);
            }

            //  Создаю уникальное имя для файла, чтобы не затереть данные
            int i = 1;

            while (File.Exists(fileName))
            {
                l.Info("Не уникальное имя файла с тиками " + fileName);
                fileName = Path.Combine(dataDir, symbol + from.ToString(maskForDateTime) + "[" + i + "]" + TicksFile.FileExt);
                ++i;
            }

            TicksFile result = new TicksFile(fileName, symbol, intFrom, intTill);

            result.ticks = ticks;
            return(result);
        }
示例#6
0
 private void exportButton_Click(object sender, EventArgs e)
 {
     EnableAll(false);
     backgroundWorker1.RunWorkerAsync(new DoWorkParam(
                                          selectSymbol1.GetSelectedSymbols(),
                                          (int)numericUpDown1.Value,
                                          DateTime2Int.Int(dateTimePicker1.Value),
                                          DateTime2Int.Int(dateTimePicker2.Value),
                                          folderTextBox.Text,
                                          comboBox1.Text
                                          ));
 }
示例#7
0
        string SetName()
        {
            string from;

            if (this.beginning == -1)
            {
                from = string.Empty;
            }
            else
            {
                from = "From" + DateTime2Int.DateTime(beginning).ToString("yyMMdd hhmmss");
            }


            if ((interval == 1) && (scaleType != ScaleEnum.month))
            {
                return(scaleType.ToString() + from);
            }
            if (scaleType == ScaleEnum.sec)
            {
                if ((interval >= 604800) && (interval % 604800 == 0))
                {
                    return(interval / 604800 + "w" + from);
                }

                if ((interval >= 86400) && (interval % 86400 == 0))
                {
                    return(interval / 86400 + "d" + from);
                }

                if ((interval >= 3600) && (interval % 3600 == 0))
                {
                    return(interval / 3600 + "h" + from);
                }

                if ((interval >= 60) && (interval % 60 == 0))
                {
                    return(interval / 60 + "min" + from);
                }
                return(interval + "sec" + beginning);
            }
            else
            if (scaleType == ScaleEnum.month)
            {
                return(interval.ToString() + "m" + beginning);
            }
            else
            {
                return(interval.ToString() + scaleType.ToString() + beginning);
            }
        }
示例#8
0
        List <IBar> Load()
        {
            _lock.AcquireWriterLock(1000);
            try
            {
                if (!File.Exists(fileName))
                {
                    return(new List <IBar>(10000));
                }
                List <IBar> data = null;
                using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    long length   = fs.Length;
                    long position = CaptionLength;
                    if (length <= CaptionLength)
                    {
                        return(new List <IBar>(10000));
                    }
                    if (DateTime2Int.Int(DateTime.Now) < endDateTime)
                    {
                        data = new List <IBar>((int)(2 * (length - position) / Tick.Size));
                    }
                    else
                    {
                        data = new List <IBar>((int)(1.1 * (length - position) / Tick.Size));
                    }

                    fs.Position = CaptionLength;
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        while (position < length)
                        {
                            data.Add(new Tick(br));
                            position += Tick.Size;
                        }
                    }
                }
                Count      = data.Count;
                changeFrom = int.MaxValue;
                return(data);
            }
            finally
            {
                _lock.ReleaseWriterLock();
            }
        }
示例#9
0
        public int TimeAlignment(int dt)
        {
            if (scale.scaleType != ScaleEnum.sec)
            {
                throw new InvalidOperationException("Для scaleType отличного от ScaleEnum.sec вызов данного метода ошибочен");
            }

            int periods = (dt - scale.beginning) / scale.interval;

            int result = scale.beginning + periods * scale.interval;

            if (l.IsDebugEnabled)
            {
                l.Debug(debKey + "Округлил время " + DateTime2Int.DateTime(dt) + " до " + DateTime2Int.DateTime(result));
            }
            return(result);
        }
示例#10
0
 public DateTime GetDateTime()
 {
     return(DateTime2Int.DateTime(dt));
 }
示例#11
0
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            l.Debug("стартовал backgroundWorker_DoWork");

            Random             random        = new Random(DateTime.Now.Millisecond);
            List <EmitentInfo> listDownloads = new List <EmitentInfo>();

            #region Формирование списка эмитентов
            backgroundWorker.ReportProgress(0, "Формирую список эмитентов для обработки");
            l.Debug("Формирую список эмитентов для обработки");

            lock (FinamHelper.Lock)
            {
                foreach (EmitentInfo emitent in FinamHelper.Emitents)
                {
                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true; return;
                    }                                                                      // пользователь отменил операцию
                    if ((emitent.Id != -1) && (emitent.Checked))
                    {
                        listDownloads.Add(emitent);
                    }
                }
            }
            #endregion Формирование списка эмитентов

            IScale tickScale = Core.Data.GetScale(ScaleEnum.tick, 1);

            for (int i = 0; i < listDownloads.Count; ++i)
            {
                ISymbol symbol = Core.Data.GetSymbol(listDownloads[i].MarketName, listDownloads[i].Name);

                backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "==== Работаю с " + symbol);
                l.Debug("==== Работаю с " + symbol);

                if (backgroundWorker.CancellationPending)
                {
                    e.Cancel = true; return;
                }                                                                      // пользователь отменил операцию

                #region Определение начальной date
                DateTime date = settings.from;

                switch (settings.fromType)
                {
                case 0:
                    date = settings.from;
                    break;

                case 1:
                    date = DateTime.Now.Date.AddDays(-1);
                    break;

                case 2:
                    date = DateTime2Int.DateTime(Core.Data.GetBars(symbol, tickScale).Last.DT);
                    break;

                case 3:
                    date = DateTime2Int.DateTime(Core.Data.GetBars(symbol, tickScale).Last.DT).AddDays(-1);
                    break;

                default:
                    l.Error("settings.fromType=" + settings.fromType);
                    break;
                }
                #endregion Определение начальной date

                for (; date <= settings.to; date = date.AddDays(1))
                {
                    string filename = Path.Combine(settings.saveCSVFolder, listDownloads[i].MarketName + "-" + listDownloads[i].Code + "-" + date.ToString("yyyyMMdd") + ".csv");
                    string csv      = string.Empty;

                    if (!File.Exists(filename))
                    {
                        #region Загрузка c финама
                        if (settings.downloadChecked)
                        {
                            backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Загружаю " + symbol + " за " + date.ToShortDateString());
                            l.Debug("Загружаю " + symbol + " за " + date.ToShortDateString());
                            do
                            {
                                if (backgroundWorker.CancellationPending)
                                {
                                    e.Cancel = true; return;
                                }                                                                      // пользователь отменил операцию
                                try
                                {
                                    csv = FinamHelper.Download(settings, listDownloads[i], date);
                                }
                                catch
                                {
                                    l.Error("Необробатываемый Exception в FinamHelper.Download");
                                    csv = "Exception";
                                }
                                if (csv == "Система уже обрабатывает Ваш запрос. Дождитесь окончания обработки.")
                                {
                                    backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Финам просит подождать");
                                    System.Threading.Thread.Sleep(random.Next(30000));
                                    if (backgroundWorker.CancellationPending)
                                    {
                                        e.Cancel = true; return;
                                    }                                                                      // пользователь отменил операцию
                                    backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Пробую снова");
                                }
                                if (csv == "Exception")
                                {
                                    backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Ошибка при скачивании");
                                    System.Threading.Thread.Sleep(random.Next(30000));
                                    if (backgroundWorker.CancellationPending)
                                    {
                                        e.Cancel = true; return;
                                    }                                                                      // пользователь отменил операцию
                                    backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Пробую снова");
                                }
                            } while
                            (
                                (csv == "Система уже обрабатывает Ваш запрос. Дождитесь окончания обработки.")
                                ||
                                (csv == "Exception")
                            );

                            if ((csv == String.Empty) || (csv.Length < 30))
                            {
                                backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "нет данных \r\n" + csv);
                                l.Debug("нет данных \r\n" + csv);
                                if (backgroundWorker.CancellationPending)
                                {
                                    e.Cancel = true; return;
                                }                                                                      // пользователь отменил операцию
                            }
                        }
                        #endregion Загрузка с финама

                        #region Сохранение
                        if ((settings.saveCSVChecked) && (csv.Length >= 30))
                        {
                            backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Сохраняю csv");
                            l.Debug("Сохраняю csv");

                            try
                            {
                                if (!Directory.Exists(settings.saveCSVFolder))
                                {
                                    Directory.CreateDirectory(settings.saveCSVFolder);
                                }

                                File.WriteAllText(filename, csv, Encoding.UTF8);
                            }
                            catch (Exception exc)
                            {
                                l.Error("Не смог сохранить csv в файл ", exc);
                            }
                        }
                        #endregion Сохранение
                    }

                    #region Анализ
                    if (settings.analyzeChecked)
                    {
                        if ((csv.Length < 30) && (File.Exists(filename)))
                        {
                            csv = File.ReadAllText(filename, Encoding.UTF8);
                        }

                        if ((settings.analyzeChecked) && (csv.Length >= 30))
                        {
                            backgroundWorker.ReportProgress((100 * i / listDownloads.Count), "Анализирую " + symbol + " за " + date.ToShortDateString());
                            l.Debug("Анализирую " + symbol + " за " + date.ToShortDateString());
                            using (StringReader csvStringReader = new StringReader(csv))
                            {
                                FinamHelper.LoadCSV(csvStringReader, symbol);
                            }
                        }
                    }
                    #endregion Анализ

                    System.Threading.Thread.Sleep(random.Next(100)); // дадим интерфейсу отрисоваться, а финуму отдохнуть
                }
            }

            if (backgroundWorker.CancellationPending)
            {
                e.Cancel = true; return;
            }                                                 // пользователь отменил операцию

            System.Threading.Thread.Sleep(random.Next(1000)); // дадим интерфейсу отрисоваться, а финуму отдохнуть

            backgroundWorker.ReportProgress(100, "Всё!!!");
            l.Info("backgroundWorker_DoWork закончил");
        }
示例#12
0
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            DoWorkParam doWorkParam = e.Argument as DoWorkParam;

            if (doWorkParam != null)
            {
                if (!Directory.Exists(doWorkParam.Dir))
                {
                    Directory.CreateDirectory(doWorkParam.Dir);
                }

                IScale scale;
                if (doWorkParam.TimeFrame > 0)
                {
                    scale = Core.Data.GetScale(ScaleEnum.sec, doWorkParam.TimeFrame);
                }
                else
                {
                    scale = Core.Data.GetScale(ScaleEnum.tick, 1);
                }

                for (int i4Symbol = 0; i4Symbol < doWorkParam.SymbolList.Count; ++i4Symbol)
                {
                    if (backgroundWorker1.CancellationPending)
                    {
                        e.Cancel = true; return;
                    }
                    IBars bars = Core.Data.GetBars(doWorkParam.SymbolList[i4Symbol], scale);
                    if (backgroundWorker1.CancellationPending)
                    {
                        e.Cancel = true; return;
                    }
                    IBar bar = bars.Get(doWorkParam.From);
                    if (bar == null)
                    {
                        bar = bars.First;
                    }
                    if ((bar != null) && (bar.DT <= doWorkParam.To))
                    {
                        double progressDelta = 1 / doWorkParam.SymbolList.Count;
                        int    count         = 0;
//                        using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\WriteLines2.txt"))
                        using (BinaryWriter file = new BinaryWriter(File.Open(Path.Combine(doWorkParam.Dir, string.Concat(doWorkParam.SymbolList[i4Symbol], ".", doWorkParam.FileType)), FileMode.Create, FileAccess.Write)))
                        {
                            //заголовок файла
                            if (doWorkParam.FileType == "wl")
                            {
                                file.Write((int)0);
                            }
                            else
                            if (doWorkParam.TimeFrame == 0)
                            {
                                file.Write(Encoding.ASCII.GetBytes("<DATE>;<TIME>;<LAST>;<VOL>;<ID>" + Environment.NewLine));
                            }
                            else
                            {
                                file.Write(Encoding.ASCII.GetBytes("<DATE>;<TIME>;<OPEN>;<HIGH>;<LOW>;<CLOSE>;<VOL>" + Environment.NewLine));
                            }

                            // данные файла
                            while ((bar != null) && (bar.DT <= doWorkParam.To))
                            {
                                if (backgroundWorker1.CancellationPending)
                                {
                                    e.Cancel = true; return;
                                }

                                if (doWorkParam.FileType == "wl")
                                {
                                    file.Write((double)DateTime2Int.DateTime(bar.DT).ToOADate());
                                    file.Write((float)bar.Open);
                                    file.Write((float)bar.High);
                                    file.Write((float)bar.Low);
                                    file.Write((float)bar.Close);
                                    file.Write((float)bar.Volume);
                                }
                                else
                                {
                                    string s = string.Empty;
                                    if (doWorkParam.TimeFrame == 0)
                                    {
                                        s = string.Concat(
                                            DateTime2Int.DateTime(bar.DT).ToString("yyyyMMdd;"),
                                            DateTime2Int.DateTime(bar.DT).ToString("hhmmss;"),
                                            bar.Close.ToString(),
                                            ";",
                                            bar.Volume.ToString(),
                                            ";",
                                            bar.Number.ToString(),
                                            Environment.NewLine
                                            );
                                    }
                                    else
                                    {
                                        s = string.Concat(
                                            DateTime2Int.DateTime(bar.DT).ToString("yyyyMMdd;"),
                                            DateTime2Int.DateTime(bar.DT).ToString("hhmmss;"),
                                            bar.Open.ToString(),
                                            ";",
                                            bar.High.ToString(),
                                            ";",
                                            bar.Low.ToString(),
                                            ";",
                                            bar.Close.ToString(),
                                            ";",
                                            bar.Volume.ToString(),
                                            Environment.NewLine
                                            );
                                    }
                                    byte[] bytes = Encoding.ASCII.GetBytes(s);
                                    file.Write(bytes);
                                }

                                ++count;
                                backgroundWorker1.ReportProgress((int)(100 * i4Symbol / doWorkParam.SymbolList.Count + progressDelta));
                                bar = bars.GetNext(bar);
                            }
                            if (doWorkParam.FileType == "wl")
                            {
                                file.Seek(0, SeekOrigin.Begin);
                                file.Write(count);
                            }
                            file.Close();
                        }
                    }
                }
            }
            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true; return;
            }
        }
示例#13
0
        void m_TickBars_NewBarEvent(object sender, BarsEventArgs e) // TODO возможная оптимизация (слишком часто вызываю TimeAlignment(e.bar.dt))
        {
            if (l.IsDebugEnabled)
            {
                l.Debug(debKey + "m_TickBars_NewBarEvent новый тик " + e.bar);
            }
            Lock.AcquireWriterLock(1000);
            try
            {
                AggregateBar bar = FindBar(e.bar.DT) as AggregateBar;

                if (bar == null)
                {
                    int timeAlignment = TimeAlignment(e.bar.DT);

                    if (l.IsDebugEnabled)
                    {
                        l.Debug(debKey + "m_TickBars_NewBarEvent Создаю новый бар " + DateTime2Int.DateTime(timeAlignment));
                    }

                    bar = new AggregateBar(timeAlignment, timeAlignment + scale.interval - 1, e.bar.Number, e.bar.Close, e.bar.Close, e.bar.Close, e.bar.Close, e.bar.Volume);

                    bars.Add(bar);

                    EventHandler <BarsEventArgs> ev = NewBarEvent;
                    if (ev != null)
                    {
                        ev(this, new BarsEventArgs(this, bar));
                    }
                }
                else
                {
                    l.Debug(debKey + "m_TickBars_NewBarEvent Добавляю тик в бар");

                    if ((m_LastTick != null) &&
                        ((m_LastTick.DT > e.bar.DT) ||
                         ((m_LastTick.DT == e.bar.DT) && (m_LastTick.Number > e.bar.Number))))
                    {
                        l.Debug(debKey + "Тики пришли не по порядку. Пересчитываю весь бар");
                        RecalcBar(bar);
                    }
                    else
                    {
                        bar.AddTick(e.bar);
                    }

                    m_LastTick = e.bar;

                    EventHandler <BarsEventArgs> changeBarEvent = ChangeBarEvent;
                    if (changeBarEvent != null)
                    {
                        changeBarEvent(this, new BarsEventArgs(this, bar));
                    }
                }
            }
            finally
            {
                Lock.ReleaseWriterLock();
            }
        }
示例#14
0
        // Объеденяет файлы
        public void Concat(int count = 100 *1024 *1024 / Simple.Tick.Size)
        {
            _lock.AcquireWriterLock(10000);
            try
            {
                List <TicksFile> newTicksFileList = new List <TicksFile>();

                if (Count <= count)
                {
                    //Объединяю всё в один файл
                    newTicksFileList.Add(
                        forConcatCreateFile(DateTime.MinValue, DateTime.MaxValue, string.Empty, Count)
                        );
                }
                else
                {
                    // Как минимум разбиваю по годам
                    IBar bar      = First;
                    int  year     = bar.GetDateTime().Year;
                    int  lastYear = Last.GetDateTime().Year;
                    while (year <= lastYear)
                    {
                        // расчитываю кво баров в данном году
                        int barCountOfYear = 0;
                        int nextYear       = DateTime2Int.Int(new DateTime(year + 1, 1, 1));
                        while ((bar != null) && (bar.DT < nextYear))
                        {
                            ++barCountOfYear;
                            bar = GetNext(bar);
                        }
                        if (barCountOfYear <= count)
                        {
                            //Объединяю год в один файл
                            if (barCountOfYear > 0)
                            {
                                newTicksFileList.Add(
                                    forConcatCreateFile(new DateTime(year, 1, 1), new DateTime(year + 1, 1, 1).AddSeconds(-1), " yyyy", barCountOfYear)
                                    );
                            }
                        }
                        else
                        {
                            //Разбивыаю по месяцам
                            for (int i = 1; i <= 12; ++i)
                            {
                                TicksFile tf = forConcatCreateFile(new DateTime(year, i, 1), new DateTime(year, i, 1).AddMonths(1).AddSeconds(-1), " yyyyMM", (barCountOfYear / 12 * 2));
                                if (tf.Count > 0)
                                {
                                    newTicksFileList.Add(tf);
                                }
                            }
                        }
                        ++year;
                    }
                }
                // Удаляю все существующие файлы
                staticLock.AcquireWriterLock(10000);
                try
                {
                    foreach (TicksFile tf in ticksFileList)
                    {
                        if (!newTicksFileList.Contains(tf))
                        {
                            tf.Delete();
                            allTicksFileList.Remove(tf); // TODO возможно здесь баг, т.к. после Concat файл CaptionOfAllFiles.txt был больше 15M, а после пересоздания стал 800K
                        }
                    }

                    ticksFileList = newTicksFileList;
                    foreach (TicksFile tf in ticksFileList)
                    {
                        if (!allTicksFileList.Contains(tf))
                        {
                            allTicksFileList.Add(tf);
                        }
                    }
                }
                finally
                {
                    staticLock.ReleaseWriterLock();
                }
            }
            finally
            {
                _lock.ReleaseWriterLock();
            }
        }