/// <summary>
        /// 到来一个新的Tick,更新Bar
        /// </summary>
        /// <param name="tick"></param>
        public void AddTick(Tick tick)
        {
            #region

            if (tick == null)
            {
                ChangeState = 4;
                return;
            }

            double turnover = 0;
            double volume   = 0;

            lock (_lockobj)
            {
                // 第一个tick
                if (_lasttick != null)
                {
                    turnover = _lasttick.Turnover;
                    volume   = _lasttick.Volume;
                }
                else
                {
                    if (_blive)
                    {
                        _diff = tick.DateTime - DateTime.Now;
                    }

                    foreach (var bar in _bars)
                    {
                        if (bar.TradingDate == TradingDay)
                        {
                            turnover = turnover + bar.Turnover;
                            volume   = volume + bar.Volume;
                        }
                    }

                    //for (int i = _bars.Count - 1; i >= _bars.Count - _posBar - 1; --i)
                    //{
                    //    if (_bars[i].Open > 0)
                    //        break;

                    //    _bars[i].Open = _bars[i].High = _bars[i].Low = _bars[i].Close = _bars[i].PreClose = tick.OpenPrice;
                    //    _bars[i].OpenInterest = tick.PreOpenInterest;
                    //    if (i == _bars.Count - _posBar - 1)
                    //    {
                    //        if (tick.PreSettlementPrice > 0)
                    //            _bars[i].PreClose = tick.PreSettlementPrice;
                    //        else
                    //            _bars[i].PreClose = tick.PreClosePrice;
                    //    }
                    //}
                }

                if (IsEnd)
                {
                    ChangeState = 4;
                    return;
                }

                int idx;
                int ir = MoveTo(tick.DateTime, out idx);
                if (ir == -1)
                {
                    ChangeState = 4;
                    return;
                }

                _lasttick = tick;

                var baropencount  = 0;
                var barclosecount = 0;
                for (; _posTime < idx; ++_posTime)
                {
                    DateTimeSlice currentT = _lstslice[_posTime];

                    if (_posBar == _posTime)
                    {
                        ++barclosecount;

                        _bars.Last.CloseBar(currentT.EndTime);
                        OnBarClosed(_bars.Last);
                    }
                    else
                    {
                        #region 20150628 去掉空Bar

                        if (AllBlankBar)
                        {
                            ++baropencount;
                            var bar = new Bar {
                                BeginTime = currentT.BeginTime
                            };
                            if (_posBar >= 0)
                            {
                                bar.Close        = bar.PreClose = bar.Open = bar.High = bar.Low = _bars.Last.Close;
                                bar.OpenInterest = _bars.Last.OpenInterest;
                            }
                            else if (_lasttick != null)
                            {
                                if (_lasttick.PreSettlementPrice > 0)
                                {
                                    bar.Close        =
                                        bar.PreClose = bar.Open = bar.High = bar.Low = _lasttick.PreSettlementPrice;
                                }
                                else
                                {
                                    bar.Close = bar.PreClose = bar.Open = bar.High = bar.Low = _lasttick.PreClosePrice;
                                }

                                bar.OpenInterest = _lasttick.PreOpenInterest;
                            }
                            bar.TradingDate = tick.TradingDay;
                            _bars.Add(bar);

                            ++barclosecount;
                            _bars.Last.CloseBar(currentT.EndTime);
                            OnBarClosed(_bars.Last);
                        }


                        #endregion

                        ++_posBar;
                    }
                }

                if (ir == 0)
                {
                    if (_posBar == _posTime)
                    {
                        Bar bar = _bars.Last;
                        bar.AddTick(tick);
                        bar.Turnover = bar.Turnover + tick.Turnover - turnover;
                        bar.Volume   = bar.Volume + tick.Volume - volume;
                    }
                    else
                    {
                        Bar lastbar = _bars.Last;

                        Bar bar = new Bar {
                            TradingDate = TradingDay
                        };
                        bar.OpenBar(_lstslice[_posTime].BeginTime, tick, lastbar, _posTime == 0);
                        if (lastbar != null)
                        {
                            bar.Turnover = tick.Turnover - turnover;
                            bar.Volume   = tick.Volume - volume;
                        }
                        else
                        {
                            bar.Turnover = tick.Turnover;
                            bar.Volume   = tick.Volume;
                        }
                        _bars.Add(bar);

                        ++baropencount;
                        OnBarOpened(bar);

                        ++_posBar;
                    }
                }

                if (baropencount == 0 && barclosecount == 0)
                {
                    ChangeState = 0;
                    return;
                }

                if (baropencount > barclosecount)
                {
                    ChangeState = 2;
                    return;
                }

                if (barclosecount > baropencount)
                {
                    ChangeState = 1;
                    return;
                }

                ChangeState = 3;
            }

            #endregion
        }