public void TestSaveHistoricalDataEmptyFolder()
        {
            var fn = string.Empty;

            _hist = new QuoteBasicFileStore(_exchange, _folder, _numBarsInFile);
            _hist.OnQuoteSaved += (object sender, string exch, string filename) =>
            {
                fn = filename;
            };

            var starttime = _timenow - 10000 * _interval;
            var q         = CreateQuote(starttime, 700);
            var r         = _hist.Save(q);

            Assert.IsTrue(r);

            Assert.IsTrue(fn == this.GetQuoteFileName(_symbol, _interval, 0));

            starttime = q.LastTime + _interval;
            q         = CreateQuote(starttime, 700);
            r         = _hist.Save(q);
            Assert.IsTrue(r);
            Assert.IsTrue(fn == this.GetQuoteFileName(_symbol, _interval, 0));

            starttime = q.LastTime - 100 * _interval;
            q         = CreateQuote(starttime, 700);
            r         = _hist.Save(q);
            Assert.IsTrue(r);
            Assert.IsTrue(fn == this.GetQuoteFileName(_symbol, _interval, 1));
            q = QuoteBasicExension.LoadFile(fn);
            Assert.IsTrue(q.Count == 599);
        }
        //file naming convention: exchange_symbol_interval_index.txt
        public bool Save(IQuoteBasicBase quote, int numBarsToRemoveGap = -1)
        {
            lock (this)
            {
                if (quote == null || quote.Count == 0)
                {
                    return(false);
                }
                var files = this.FindQuoteFiles(quote.Symbol, quote.Interval);

                if (files != null && files.Count > 0)
                {
                    files.Sort();
                    var q1 = QuoteBasicExension.LoadFile(files.Last());

                    if (numBarsToRemoveGap > 0)
                    {
                        for (int i = Math.Max(0, q1.Count - numBarsToRemoveGap); i < q1.Count - 1; i++)
                        {
                            if (q1.Time[i + 1] - q1.Time[i] > q1.Interval)
                            {
                                q1.Clear(i + 1, q1.Count - 1);
                                break;
                            }
                        }
                    }

                    //var readtream = new FileStream(files.Last(), FileMode.Open);
                    //var q1 = QuoteBasicBase.InitByStream(readtream);
                    //readtream.Close();

                    if (quote.LastTime <= q1.LastTime)
                    {
                        return(false);
                    }

                    if (q1.Count < _maxNumBarsInFile)
                    {
                        var fn = files.Last();
                        q1.Append(quote);
                        q1.SaveToFile(fn);
                        //var writestream = new FileStream(files.Last(), FileMode.Truncate);
                        //q1.AppendStream(writestream);
                        //writestream.Close();
                        OnQuoteSaved?.Invoke(this, this.Exchange, fn);
                    }
                    else
                    {
                        var last  = files.Last().Split('_').Last();
                        var index = int.Parse(last.Split('.')[0]);
                        var fn    = this.GetQuoteFileName(quote.Symbol, quote.Interval, index + 1);

                        //var writestream = new FileStream(fn, FileMode.OpenOrCreate);
                        if (q1.LastTime >= quote.FirstTime)  //remove redundant sticks from new files
                        {
                            var sind = quote.FindIndexForGivenTime(q1.LastTime);
                            var q2   = new QuoteBasicBase(quote);
                            q2.Clear(0, sind);
                            q2.SaveToFile(fn);
                            //q2.AppendStream(writestream);
                        }
                        else
                        {
                            quote.SaveToFile(fn);
                            //quote.AppendStream(writestream);
                        }
                        //writestream.Close();
                        OnQuoteSaved?.Invoke(this, this.Exchange, fn);
                    }
                }
                else
                {
                    var fn = this.GetQuoteFileName(quote.Symbol, quote.Interval, 0);
                    quote.SaveToFile(fn);
                    //var writestream = new FileStream(fn, FileMode.OpenOrCreate);
                    //quote.AppendStream(writestream);
                    //writestream.Close();
                    OnQuoteSaved?.Invoke(this, this.Exchange, fn);
                }

                return(true);
            }
        }