private Task saveStockElementToDB(StockDataElement element)
        {
            return(Task.Run(() =>
            {
                lock (contextVol)
                {
                    //Int64 stockID = (from s in dbStocks
                    //                 where s.ticker == element.ticker
                    //                 select s.id).FirstOrDefault();
                    //if (stockID == 0)
                    //{
                    //    stocks ns = new stocks();
                    //    ns.ticker = element.ticker;
                    //    ns.enddate = null;
                    //    ns.pricestep = 100;
                    //    ns.active = true;
                    //    contextVol.stocks.InsertOnSubmit(ns);
                    //    contextVol.SubmitChanges();

                    //    dbStocks = from s in contextVol.stocks
                    //               where s.active == true
                    //               select s;
                    //    stockID = (from s in dbStocks
                    //               where s.ticker == element.ticker
                    //               select s.id).FirstOrDefault();
                    //}

                    volquotes nq = new volquotes();

                    nq.stock = stockID;
                    nq.timeframe = currentTimeFrameId;
                    nq.datetime = element.date;

                    nq.high = element.high;
                    nq.low = element.low;

                    nq.open = element.open;
                    nq.close = element.close;

                    nq.middle = element.middle;

                    nq.volume = element.Volume;
                    nq.volumebuy = element.VolumeBuy;
                    nq.volumesell = element.VolumeSell;

                    contextVol.volquotes.InsertOnSubmit(nq);
                    contextVol.SubmitChanges();
                }
            }));
        }
        // **********************************************************************

        public override void ProcessTick(Tick tick)
        {
            if (tick.DateTime < firstTickDt)
            {
                return;
            }

            lock (VolumeVector)
            {
                DateTime lastDT = DateTime.MinValue;
                if (lastDateTimeVolume.TryGetValue(tick.SecCode, out lastDT) == false)
                {
                    // начальная установка даты и времени отсчета
                    lastDT = tick.DateTime;
                }

                Dictionary <DateTime, StockDataElement> volumes = new Dictionary <DateTime, StockDataElement>();
                if (VolumeVector.TryGetValue(tick.SecCode, out volumes) == false)
                {
                    createNewVolume(tick.SecCode, lastDT);

                    VolumeVector.TryGetValue(tick.SecCode, out volumes);
                }

                StockDataElement vds = new StockDataElement(tick.SecCode, lastDT);
                volumes.TryGetValue(lastDT, out vds);


                // если время больше XXX мин, делаем новую группу
                long csTicks = currentTimeFrame * TimeSpan.TicksPerSecond;
                if (tick.DateTime.Ticks - lastDT.Ticks >= csTicks)
                { // новая группа
                  //--------------------

                    //+ old
                    lastDT = tick.DateTime;
                    createNewVolume(tick.SecCode, lastDT);
                    volumes.TryGetValue(lastDT, out vds);
                    //- old

                    vds.high = tick.IntPrice;
                    vds.low  = tick.IntPrice;

                    vds.open  = tick.IntPrice;
                    vds.close = tick.IntPrice;

                    firstLoopInCandle = true;
                }

                if (firstRound)
                {
                    vds.high = tick.IntPrice;
                    vds.low  = tick.IntPrice;

                    vds.open  = tick.IntPrice;
                    vds.close = tick.IntPrice;
                }
                //+ 02082015 Bug fix
                if (vds.open == 0)
                {
                    vds.open = tick.IntPrice;
                }
                //+ 02082015 Bug fix

                if (tick.IntPrice > vds.high)
                {
                    vds.high = tick.IntPrice;
                }

                if (tick.IntPrice < vds.low)
                {
                    vds.low = tick.IntPrice;
                }

                vds.close = tick.IntPrice;

                vds.Volume         += tick.Volume;
                vds.PriceVolumeSum += (tick.IntPrice * tick.Volume);

                if (tick.Op == TradeOp.Sell)
                {
                    vds.VolumeSell += tick.Volume;
                }
                else
                {
                    vds.VolumeBuy += tick.Volume;
                }

                firstRound        = false;
                firstLoopInCandle = false;

                volumes[lastDT]            = vds;
                VolumeVector[tick.SecCode] = volumes;

                // Save last tick
                if (vds.date >= lastTickDt && !lastCandleSend)
                {
                    vds.middle = vds.PriceVolumeSum / vds.Volume;
                    saveStockElementToDB(vds);

                    lastCandleSend = true;
                }
            }
        }
        // **********************************************************************

        private async void createNewVolume(string SecCode, DateTime lastDT)
        {
            if (stockID == 0)
            {
                stockID = (from s in dbStocks
                           where s.ticker == SecCode
                           select s.id).FirstOrDefault();
            }

            bool found = false;

            DateTime lastCandleTime = DateTime.MinValue;

            if (lastDateTimeVolume.TryGetValue(SecCode, out lastCandleTime) == false)
            {
                // начальная установка даты и времени отсчета
                lastCandleTime = lastDT;
                lastDT         = firstTickDt;         // ставим на начало сессии

                lastDateTimeVolume[SecCode] = lastDT; // сохраняем
            }

            StockDataElement lastEl1 = new StockDataElement(SecCode, lastDT);

            lock (VolumeVector)
            {
                Dictionary <DateTime, StockDataElement> volumes = new Dictionary <DateTime, StockDataElement>();
                lock (volumes)
                {
                    if (VolumeVector.TryGetValue(SecCode, out volumes) == false)
                    {
                        volumes = new Dictionary <DateTime, StockDataElement>();
                        StockDataElement vds = new StockDataElement(SecCode, lastDT);

                        volumes[lastDT]       = vds;
                        VolumeVector[SecCode] = volumes;
                    }
                    else
                    {
                        if (volumes.TryGetValue(lastCandleTime, out lastEl1) == true)
                        {
                            found = true;
                        }

                        StockDataElement vds = new StockDataElement(SecCode, lastDT);

                        volumes[lastDT] = vds;

                        VolumeVector[SecCode] = volumes;
                    }
                }
            }

            lastDateTimeVolume[SecCode] = lastDT;


            // запуск в отдельном процессе сохранения последнего элемента в базу
            if (found)
            {
                lastEl1.middle = lastEl1.PriceVolumeSum / lastEl1.Volume;
                lastEl1.date   = lastCandleTime; // будет одной временной точкой
                await saveStockElementToDB(lastEl1);
                await createNew_VAT(SecCode);
            }
        }