Esempio n. 1
0
        private IEnumerable <MessageBuffer <T> > GetFormedBuffers(T msg, DateTimeOffset openTime, SecurityId secId)
        {
            var buffers = new List <MessageBuffer <T> >();

            lock (_buffers.SyncRoot)
            {
                var buffer = _buffers.SafeAdd(openTime, key => new MessageBuffer <T>(openTime, _bufferSize));
                buffer.AddMessage(_securityIndecies[secId], msg);

                if (!buffer.IsFilled)
                {
                    return(Enumerable.Empty <MessageBuffer <T> >());
                }

                // mika
                // далее идет обработка 4-рех ситуаций
                //
                // 1. первая свеча оказалась заполненой полностью, и мы просто удаляем начальные буфера
                // так как они уже никогда не заполняться.
                //
                // 2. первая свеча оказалось размазанной, тогда так же удаляем хвосты, но при этом формируем
                // из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.
                //
                // 3. появилась заполненная полностью свеча, и тогда дозаполняем промежутки с _lastProcessBuffer
                //
                // 4. появилась размазанная свеча, и тогда дозаполняем промежутки с _lastProcessBuffer + формируем
                // из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.

                var firstTimeBuffer = _lastProcessBuffer == null;

                // последней буфер, до которого (включительно) можно сформировать спред по текущим данным
                var lastBuffer = buffer;

                var deleteKeys = new List <DateTimeOffset>();

                foreach (var time in _buffers.CachedKeys)
                {
                    if (time >= lastBuffer.Time)
                    {
                        break;
                    }

                    var curr = _buffers[time];

                    if (firstTimeBuffer)
                    {
                        if (!buffer.IsFilled)
                        {
                            if (_lastProcessBuffer == null)
                            {
                                _lastProcessBuffer = curr;
                            }
                            else
                            {
                                _lastProcessBuffer.Fill(curr);
                                _lastProcessBuffer = curr;
                            }
                        }
                    }
                    else
                    {
                        curr.Fill(_lastProcessBuffer);

                        _lastProcessBuffer = curr;

                        if (curr.IsFilled)
                        {
                            buffers.Add(curr);
                        }
                    }

                    deleteKeys.Add(time);
                }

                if (!buffer.IsFilled)
                {
                    lastBuffer.Fill(_lastProcessBuffer);
                }

                if (lastBuffer.IsFilled)
                {
                    deleteKeys.Add(lastBuffer.Time);

                    _lastProcessBuffer = lastBuffer;
                    buffers.Add(lastBuffer);
                }

                deleteKeys.ForEach(k => _buffers.Remove(k));
            }

            return(buffers);
        }
Esempio n. 2
0
        private IEnumerable <CandleBuffer> GetFormedBuffers(Candle candle)
        {
            var buffers = new List <CandleBuffer>();

            lock (_buffers.SyncRoot)
            {
                var buffer = _buffers.SafeAdd(candle.OpenTime, key => new CandleBuffer(candle.OpenTime, candle.CloseTime, _bufferSize, false));
                buffer.AddCandle(_securityIndecies[candle.Security], candle);

                if (!buffer.IsFilled)
                {
                    return(Enumerable.Empty <CandleBuffer>());

                    // mika
                    // заполняем "размазанные" буфера, чтобы определить, что первее наступит,
                    // заполнится ли полностью одна из свечек,
                    // или мы сможем достроить спред из "размазанных" буферов

                    // TODO пока убрал, нужно больше тестов
                    if (_sparseBuffer1 == null)
                    {
                        _sparseBuffer1 = new CandleBuffer(candle.OpenTime, candle.CloseTime, _bufferSize, true);
                    }

                    if (!_sparseBuffer1.IsFilled)
                    {
                        _sparseBuffer1.AddCandle(_securityIndecies[candle.Security], candle);
                    }
                    else
                    {
                        if (_sparseBuffer2 == null)
                        {
                            _sparseBuffer2 = new CandleBuffer(candle.OpenTime, candle.CloseTime, _bufferSize, true);
                        }

                        _sparseBuffer2.AddCandle(_securityIndecies[candle.Security], candle);

                        // если первая свеча будет построена по размазанному буферу, то разница между временем эти буферов
                        // должна гарантировать, что между ними
                        //if (_lastProcessBuffer == null && _sparseBuffer2.IsFilled && (_sparseBuffer1.CloseTime > _sparseBuffer2.OpenTime))
                        //	return Enumerable.Empty<CandleBuffer>();
                    }

                    if (_sparseBuffer2 == null || !_sparseBuffer2.IsFilled)
                    {
                        return(Enumerable.Empty <CandleBuffer>());
                    }
                }

                // mika
                // далее идет обработка 4-рех ситуаций
                //
                // 1. первая свеча оказалась заполненой полностью, и мы просто удаляем начальные буфера
                // так как они уже никогда не заполняться.
                //
                // 2. первая свеча оказалось размазанной, тогда так же удаляем хвосты, но при этом формируем
                // из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.
                //
                // 3. появилась заполненная полностью свеча, и тогда дозаполняем промежутки с _lastProcessBuffer
                //
                // 4. появилась размазанная свеча, и тогда дозаполняем промежутки с _lastProcessBuffer + формируем
                // из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.

                var firstTimeBuffer = _lastProcessBuffer == null;

                // последней буфер, до которого (включительно) можно сформировать спред по текущим данным
                var lastBuffer = buffer.IsFilled ? buffer : _buffers[_sparseBuffer2.OpenTime];

                var deleteKeys = new List <DateTimeOffset>();

                foreach (var time in _buffers.CachedKeys)
                {
                    if (time >= lastBuffer.OpenTime)
                    {
                        break;
                    }

                    var curr = _buffers[time];

                    if (firstTimeBuffer)
                    {
                        if (!buffer.IsFilled)
                        {
                            if (_lastProcessBuffer == null)
                            {
                                _lastProcessBuffer = curr;
                            }
                            else
                            {
                                _lastProcessBuffer.Fill(curr);
                                _lastProcessBuffer = curr;
                            }
                        }
                    }
                    else
                    {
                        curr.Fill(_lastProcessBuffer);

                        if (!curr.IsFilled)
                        {
                            throw new InvalidOperationException(LocalizedStrings.Str655);
                        }

                        _lastProcessBuffer = curr;
                        buffers.Add(curr);
                    }

                    deleteKeys.Add(time);
                }

                if (!buffer.IsFilled)
                {
                    lastBuffer.Fill(_lastProcessBuffer);
                }

                if (!lastBuffer.IsFilled)
                {
                    throw new InvalidOperationException(LocalizedStrings.Str656);
                }

                deleteKeys.Add(lastBuffer.OpenTime);

                _lastProcessBuffer = lastBuffer;
                buffers.Add(lastBuffer);

                _sparseBuffer1 = _sparseBuffer2;
                _sparseBuffer2 = null;

                deleteKeys.ForEach(k => _buffers.Remove(k));
            }

            return(buffers);
        }