protected override void OnSave(BitArrayWriter writer, IEnumerable <ExecutionMessage> messages, TickMetaInfo metaInfo)
        {
            if (metaInfo.IsEmpty())
            {
                var first = messages.First();

                metaInfo.FirstId      = metaInfo.PrevId = first.GetTradeId();
                metaInfo.ServerOffset = first.ServerTime.Offset;
            }

            writer.WriteInt(messages.Count());

            var allowNonOrdered  = metaInfo.Version >= MarketDataVersions.Version48;
            var isUtc            = metaInfo.Version >= MarketDataVersions.Version50;
            var allowDiffOffsets = metaInfo.Version >= MarketDataVersions.Version54;

            foreach (var msg in messages)
            {
                if (msg.ExecutionType != ExecutionTypes.Tick)
                {
                    throw new ArgumentOutOfRangeException(nameof(messages), msg.ExecutionType, LocalizedStrings.Str1695Params.Put(msg.TradeId));
                }

                var tradeId = msg.GetTradeId();

                // сделки для индексов имеют нулевой номер
                if (tradeId < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(messages), tradeId, LocalizedStrings.Str1020);
                }

                // execution ticks (like option execution) may be a zero cost
                // ticks for spreads may be a zero cost or less than zero
                //if (msg.TradePrice < 0)
                //	throw new ArgumentOutOfRangeException("messages", msg.TradePrice, LocalizedStrings.Str1021Params.Put(msg.TradeId));

                metaInfo.PrevId = writer.SerializeId(tradeId, metaInfo.PrevId);

                // pyhta4og.
                // http://stocksharp.com/forum/yaf_postsm6450_Oshibka-pri-importie-instrumientov-s-Finama.aspx#post6450

                var volume = msg.Volume;

                if (metaInfo.Version < MarketDataVersions.Version53)
                {
                    if (volume == null)
                    {
                        throw new ArgumentException(LocalizedStrings.Str1022Params.Put((object)msg.TradeId ?? msg.TradeStringId), nameof(messages));
                    }

                    if (volume < 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(messages), volume, LocalizedStrings.Str1022Params.Put(msg.TradeId));
                    }

                    writer.WriteVolume(volume.Value, metaInfo, SecurityId);
                }
                else
                {
                    writer.Write(volume != null);

                    if (volume != null)
                    {
                        if (volume < 0)
                        {
                            throw new ArgumentOutOfRangeException(nameof(messages), volume, LocalizedStrings.Str1022Params.Put(msg.TradeId));
                        }

                        writer.WriteVolume(volume.Value, metaInfo, SecurityId);
                    }
                }

                writer.WritePriceEx(msg.GetTradePrice(), metaInfo, SecurityId);
                writer.WriteSide(msg.OriginSide);

                var lastOffset = metaInfo.LastServerOffset;
                metaInfo.LastTime         = writer.WriteTime(msg.ServerTime, metaInfo.LastTime, LocalizedStrings.Str985, allowNonOrdered, isUtc, metaInfo.ServerOffset, allowDiffOffsets, ref lastOffset);
                metaInfo.LastServerOffset = lastOffset;

                if (metaInfo.Version < MarketDataVersions.Version40)
                {
                    continue;
                }

                if (metaInfo.Version < MarketDataVersions.Version47)
                {
                    writer.WriteLong(SecurityId.GetLatency(msg.ServerTime, msg.LocalTime).Ticks);
                }
                else
                {
                    var hasLocalTime = true;

                    if (metaInfo.Version >= MarketDataVersions.Version49)
                    {
                        hasLocalTime = !msg.LocalTime.IsDefault() && msg.LocalTime != msg.ServerTime;
                        writer.Write(hasLocalTime);
                    }

                    if (hasLocalTime)
                    {
                        lastOffset               = metaInfo.LastLocalOffset;
                        metaInfo.LastLocalTime   = writer.WriteTime(msg.LocalTime, metaInfo.LastLocalTime, LocalizedStrings.Str1024, allowNonOrdered, isUtc, metaInfo.LocalOffset, allowDiffOffsets, ref lastOffset);
                        metaInfo.LastLocalOffset = lastOffset;
                    }
                }

                if (metaInfo.Version < MarketDataVersions.Version42)
                {
                    continue;
                }

                if (metaInfo.Version >= MarketDataVersions.Version51)
                {
                    writer.Write(msg.IsSystem != null);

                    if (msg.IsSystem != null)
                    {
                        writer.Write(msg.IsSystem.Value);
                    }
                }
                else
                {
                    writer.Write(msg.IsSystem ?? true);
                }

                if (msg.IsSystem == false)
                {
                    if (metaInfo.Version >= MarketDataVersions.Version51)
                    {
                        writer.WriteNullableInt(msg.TradeStatus);
                    }
                    else
                    {
                        writer.WriteInt(msg.TradeStatus ?? 0);
                    }
                }

                var oi = msg.OpenInterest;

                if (metaInfo.Version < MarketDataVersions.Version46)
                {
                    writer.WriteVolume(oi ?? 0m, metaInfo, SecurityId);
                }
                else
                {
                    writer.Write(oi != null);

                    if (oi != null)
                    {
                        writer.WriteVolume(oi.Value, metaInfo, SecurityId);
                    }
                }

                if (metaInfo.Version < MarketDataVersions.Version45)
                {
                    continue;
                }

                writer.Write(msg.IsUpTick != null);

                if (msg.IsUpTick != null)
                {
                    writer.Write(msg.IsUpTick.Value);
                }

                if (metaInfo.Version < MarketDataVersions.Version52)
                {
                    continue;
                }

                writer.Write(msg.Currency != null);

                if (msg.Currency != null)
                {
                    writer.WriteInt((int)msg.Currency.Value);
                }
            }
        }
Example #2
0
        protected override void OnSave(BitArrayWriter writer, IEnumerable <QuoteChangeMessage> messages, QuoteMetaInfo metaInfo)
        {
            if (metaInfo.IsEmpty())
            {
                var firstDepth = messages.FirstOrDefault(d => !d.Bids.IsEmpty() || !d.Asks.IsEmpty());

                if (firstDepth == null)
                {
                    throw new ArgumentException(LocalizedStrings.Str931, "messages");
                }

                metaInfo.LastPrice = metaInfo.FirstPrice = GetDepthPrice(firstDepth);

                //pyh: будет баг если первый стакан пустой и с другим временем.
                //metaInfo.FirstTime = firstDepth.LastChangeTime;

                metaInfo.ServerOffset = firstDepth.ServerTime.Offset;
            }

            writer.WriteInt(messages.Count());

            QuoteChangeMessage prevQuoteMsg = null;

            var allowNonOrdered = metaInfo.Version >= MarketDataVersions.Version47;
            var isUtc           = metaInfo.Version >= MarketDataVersions.Version50;

            foreach (var quoteMsg in messages)
            {
                //if (depth.IsFullEmpty())
                //	throw new ArgumentException("Переданный стакан является пустым.", "depths");

                var bid = quoteMsg.GetBestBid();
                var ask = quoteMsg.GetBestAsk();

                // у LMAX бид и оффер могут быть равны
                if (bid != null && ask != null && bid.Price > ask.Price)
                {
                    throw new ArgumentException(LocalizedStrings.Str932Params.Put(bid.Price, ask.Price, quoteMsg.ServerTime), "messages");
                }

                metaInfo.LastTime = writer.WriteTime(quoteMsg.ServerTime, metaInfo.LastTime, LocalizedStrings.MarketDepth, allowNonOrdered, isUtc, metaInfo.ServerOffset);

                var isFull = prevQuoteMsg == null;

                writer.Write(isFull);                 // пишем, полный ли стакан или это дельта

                var delta = isFull ? quoteMsg : prevQuoteMsg.GetDelta(quoteMsg);

                prevQuoteMsg = quoteMsg;

                SerializeQuotes(writer, delta.Bids, metaInfo /*, isFull*/);
                SerializeQuotes(writer, delta.Asks, metaInfo /*, isFull*/);

                metaInfo.LastPrice = GetDepthPrice(quoteMsg);

                if (metaInfo.Version < MarketDataVersions.Version40)
                {
                    continue;
                }

                if (metaInfo.Version < MarketDataVersions.Version46)
                {
                    writer.WriteLong(SecurityId.GetLatency(quoteMsg.ServerTime, quoteMsg.LocalTime).Ticks);
                }
                else
                {
                    var hasLocalTime = true;

                    if (metaInfo.Version >= MarketDataVersions.Version49)
                    {
                        hasLocalTime = !quoteMsg.LocalTime.IsDefault() && quoteMsg.LocalTime != quoteMsg.ServerTime;
                        writer.Write(hasLocalTime);
                    }

                    if (hasLocalTime)
                    {
                        metaInfo.LastLocalTime = writer.WriteTime(quoteMsg.LocalTime, metaInfo.LastLocalTime, LocalizedStrings.Str934, allowNonOrdered, isUtc, metaInfo.LocalOffset);
                    }
                }
            }
        }
Example #3
0
        protected override void OnSave(BitArrayWriter writer, IEnumerable <QuoteChangeMessage> messages, QuoteMetaInfo metaInfo)
        {
            if (metaInfo.IsEmpty())
            {
                var firstDepth = messages.FirstOrDefault(d => !d.Bids.IsEmpty() || !d.Asks.IsEmpty());

                if (firstDepth == null)
                {
                    throw new ArgumentException(LocalizedStrings.Str931, "messages");
                }

                metaInfo.LastPrice = metaInfo.FirstPrice = GetDepthPrice(firstDepth);

                //pyh: будет баг если первый стакан пустой и с другим временем.
                //metaInfo.FirstTime = firstDepth.LastChangeTime;

                metaInfo.ServerOffset = firstDepth.ServerTime.Offset;
            }

            writer.WriteInt(messages.Count());

            QuoteChangeMessage prevQuoteMsg = null;

            var allowNonOrdered  = metaInfo.Version >= MarketDataVersions.Version47;
            var isUtc            = metaInfo.Version >= MarketDataVersions.Version50;
            var allowDiffOffsets = metaInfo.Version >= MarketDataVersions.Version52;

            foreach (var m in messages)
            {
                var quoteMsg = m;

                //if (depth.IsFullEmpty())
                //	throw new ArgumentException("Переданный стакан является пустым.", "depths");

                if (!quoteMsg.IsSorted)
                {
                    quoteMsg = (QuoteChangeMessage)quoteMsg.Clone();

                    quoteMsg.Bids = quoteMsg.Bids.OrderByDescending(q => q.Price).ToArray();
                    quoteMsg.Asks = quoteMsg.Asks.OrderBy(q => q.Price).ToArray();
                }

                var bid = quoteMsg.GetBestBid();
                var ask = quoteMsg.GetBestAsk();

                // LMAX has equals best bid and ask
                if (bid != null && ask != null && bid.Price > ask.Price)
                {
                    throw new ArgumentException(LocalizedStrings.Str932Params.Put(bid.Price, ask.Price, quoteMsg.ServerTime), "messages");
                }

                var lastOffset = metaInfo.LastServerOffset;
                metaInfo.LastTime         = writer.WriteTime(quoteMsg.ServerTime, metaInfo.LastTime, LocalizedStrings.MarketDepth, allowNonOrdered, isUtc, metaInfo.ServerOffset, allowDiffOffsets, ref lastOffset);
                metaInfo.LastServerOffset = lastOffset;

                var isFull = prevQuoteMsg == null;

                writer.Write(isFull);

                var delta = isFull ? quoteMsg : prevQuoteMsg.GetDelta(quoteMsg);

                prevQuoteMsg = quoteMsg;

                SerializeQuotes(writer, delta.Bids, metaInfo /*, isFull*/);
                SerializeQuotes(writer, delta.Asks, metaInfo /*, isFull*/);

                metaInfo.LastPrice = GetDepthPrice(quoteMsg);

                if (metaInfo.Version < MarketDataVersions.Version40)
                {
                    continue;
                }

                if (metaInfo.Version < MarketDataVersions.Version46)
                {
                    writer.WriteLong(SecurityId.GetLatency(quoteMsg.ServerTime, quoteMsg.LocalTime).Ticks);
                }
                else
                {
                    var hasLocalTime = true;

                    if (metaInfo.Version >= MarketDataVersions.Version49)
                    {
                        hasLocalTime = !quoteMsg.LocalTime.IsDefault() && quoteMsg.LocalTime != quoteMsg.ServerTime;
                        writer.Write(hasLocalTime);
                    }

                    if (hasLocalTime)
                    {
                        lastOffset               = metaInfo.LastLocalOffset;
                        metaInfo.LastLocalTime   = writer.WriteTime(quoteMsg.LocalTime, metaInfo.LastLocalTime, LocalizedStrings.Str934, allowNonOrdered, isUtc, metaInfo.LocalOffset, allowDiffOffsets, ref lastOffset);
                        metaInfo.LastLocalOffset = lastOffset;
                    }
                }

                if (metaInfo.Version < MarketDataVersions.Version51)
                {
                    continue;
                }

                writer.Write(quoteMsg.Currency != null);

                if (quoteMsg.Currency != null)
                {
                    writer.WriteInt((int)quoteMsg.Currency.Value);
                }
            }
        }