示例#1
0
        private void ProcessSecurityLookupMessage(SecurityLookupMessage message)
        {
            var instruments = _restClient.GetInstruments(GetAccountId(),
                                                         message.SecurityId.IsDefault()
                                        ? ArrayHelper.Empty <string>()
                                        : new[] { message.SecurityId.ToOanda() });

            foreach (var instrument in instruments)
            {
                var secId = instrument.Code.ToSecurityId();

                SendOutMessage(new SecurityMessage
                {
                    OriginalTransactionId = message.TransactionId,
                    SecurityId            = secId,
                    SecurityType          = SecurityTypes.Currency,
                    Name      = instrument.DisplayName,
                    PriceStep = 0.000001m
                });

                if (instrument.Halted)
                {
                    SendOutMessage(new Level1ChangeMessage
                    {
                        ServerTime = CurrentTime.Convert(TimeZoneInfo.Utc),
                        SecurityId = secId,
                    }.Add(Level1Fields.State, SecurityStates.Stoped));
                }
            }

            SendOutMessage(new SecurityLookupResultMessage {
                OriginalTransactionId = message.TransactionId
            });
        }
        private void OnPositionsResponse(PositionsResponse response)
        {
            foreach (var pos in response.MoneyPositions.GroupBy(p => p.Client))
            {
                SendOutMessage(
                    this.CreatePortfolioChangeMessage(pos.Key)
                    .Add(PositionChangeTypes.BeginValue, pos.Sum(p => p.SaldoIn))
                    .Add(PositionChangeTypes.CurrentValue, pos.Sum(p => p.Saldo))
                    .Add(PositionChangeTypes.Commission, pos.Sum(p => p.Commission)));
            }

            foreach (var pos in response.SecPositions)
            {
                SendOutMessage(
                    new PositionChangeMessage
                {
                    PortfolioName = pos.Client,
                    SecurityId    = new SecurityId {
                        Native = pos.SecId
                    },
                    DepoName   = pos.Register,
                    ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                }
                    .Add(PositionChangeTypes.BeginValue, pos.SaldoIn)
                    .Add(PositionChangeTypes.CurrentValue, pos.Saldo)
                    .Add(PositionChangeTypes.BlockedValue, pos.SaldoMin));
            }

            foreach (var fortsMoney in response.FortsMoneys)
            {
                SendOutMessage(
                    this
                    .CreatePortfolioChangeMessage(fortsMoney.Client)
                    .Add(PositionChangeTypes.BeginValue, fortsMoney.Free)
                    .Add(PositionChangeTypes.CurrentValue, fortsMoney.Current)
                    .Add(PositionChangeTypes.BlockedValue, fortsMoney.Blocked)
                    .Add(PositionChangeTypes.VariationMargin, fortsMoney.VarMargin));
            }

            foreach (var pos in response.FortsPositions)
            {
                SendOutMessage(this
                               .CreatePositionChangeMessage(pos.Client, new SecurityId {
                    Native = pos.SecId
                })
                               .Add(PositionChangeTypes.BeginValue, (decimal)pos.StartNet)
                               .Add(PositionChangeTypes.CurrentValue, (decimal)pos.TotalNet)
                               .Add(PositionChangeTypes.VariationMargin, pos.VarMargin));
            }

            //foreach (var fortsCollaterals in response.FortsCollateralses)
            //{

            //}

            //foreach (var spotLimit in response.SpotLimits)
            //{

            //}
        }
        private void OnSessionOrderBookStatusChanged(OrderBookStatusEvent orderBookStatusEvent)
        {
            SecurityStates state;

            switch (orderBookStatusEvent.Status)
            {
            case OrderBookStatus.New:
            case OrderBookStatus.Opened:
                state = SecurityStates.Trading;
                break;

            case OrderBookStatus.Suspended:
            case OrderBookStatus.Closed:
            case OrderBookStatus.Settled:
            case OrderBookStatus.Withdrawn:
                state = SecurityStates.Stoped;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            SendOutMessage(
                new Level1ChangeMessage
            {
                SecurityId = new SecurityId {
                    Native = orderBookStatusEvent.InstrumentId
                },
                ServerTime = CurrentTime.Convert(TimeZoneInfo.Utc),
            }
                .Add(Level1Fields.State, state));
        }
        private void OnSecuritiesResponse(SecuritiesResponse response)
        {
            foreach (var security in response.Securities)
            {
                var securityId = new SecurityId
                {
                    Native       = security.SecId,
                    SecurityCode = security.SecCode,
                    BoardCode    = security.Board.FixBoardName(),
                };

                SendOutMessage(new SecurityMessage
                {
                    Name         = security.ShortName,
                    SecurityId   = securityId,
                    Multiplier   = security.LotSize,
                    PriceStep    = security.MinStep,
                    Decimals     = security.Decimals,
                    ShortName    = security.ShortName,
                    SecurityType = security.Type.FromTransaq(),
                });

                SendOutMessage(
                    new Level1ChangeMessage
                {
                    SecurityId = securityId,
                    ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                }
                    .Add(Level1Fields.State, security.Active ? SecurityStates.Trading : SecurityStates.Stoped)
                    .TryAdd(Level1Fields.StepPrice, security.PointCost));
            }
        }
        private void OnSessionOrderExecuted(Execution execution)
        {
            var transactionId = TryParseTransactionId(execution.Order.InstructionId);

            if (transactionId == null)
            {
                return;
            }

            SendOutMessage(new ExecutionMessage
            {
                SecurityId = new SecurityId {
                    Native = execution.Order.InstrumentId
                },
                OriginalTransactionId = transactionId.Value,
                TradeId       = execution.ExecutionId,
                TradePrice    = execution.Price,
                TradeVolume   = execution.Quantity.Abs(),
                ExecutionType = ExecutionTypes.Transaction,
                Side          = execution.Order.Quantity > 0 ? Sides.Buy : Sides.Sell,
                Commission    = execution.Order.Commission,
                ServerTime    = CurrentTime.Convert(TimeZoneInfo.Utc),
                HasTradeInfo  = true,
            });
        }
        private void OnQuotationsResponse(QuotationsResponse response)
        {
            foreach (var quote in response.Quotations)
            {
                var message = new Level1ChangeMessage
                {
                    SecurityId = new SecurityId {
                        Native = quote.SecId
                    },
                    ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                };

                message.TryAdd(Level1Fields.AccruedCouponIncome, quote.AccruedIntValue);
                message.TryAdd(Level1Fields.OpenPrice, quote.Open);
                message.TryAdd(Level1Fields.HighPrice, quote.High);
                message.TryAdd(Level1Fields.LowPrice, quote.Low);
                message.TryAdd(Level1Fields.ClosePrice, quote.ClosePrice);
                message.TryAdd(Level1Fields.BidsCount, quote.BidsCount);
                message.TryAdd(Level1Fields.BidsVolume, (decimal?)quote.BidsVolume);
                message.TryAdd(Level1Fields.AsksCount, quote.AsksCount);
                message.TryAdd(Level1Fields.AsksVolume, (decimal?)quote.AsksVolume);
                message.TryAdd(Level1Fields.HighBidPrice, quote.HighBid);
                message.TryAdd(Level1Fields.LowAskPrice, quote.LowAsk);
                message.TryAdd(Level1Fields.Yield, quote.Yield);
                message.TryAdd(Level1Fields.MarginBuy, quote.BuyDeposit);
                message.TryAdd(Level1Fields.MarginSell, quote.SellDeposit);
                message.TryAdd(Level1Fields.HistoricalVolatility, quote.Volatility);
                message.TryAdd(Level1Fields.TheorPrice, quote.TheoreticalPrice);
                message.TryAdd(Level1Fields.Change, quote.Change);
                message.TryAdd(Level1Fields.Volume, (decimal?)quote.VolToday);
                message.TryAdd(Level1Fields.StepPrice, quote.PointCost);
                message.TryAdd(Level1Fields.OpenInterest, (decimal?)quote.OpenInterest);
                message.TryAdd(Level1Fields.TradesCount, quote.TradesCount);

                if (quote.Status != null)
                {
                    message.Add(Level1Fields.State, quote.Status.Value.FromTransaq());
                }


                // Transaq передает только изменения (например, передать только цену сделки, если объем при этом не изменился)

                message.TryAdd(Level1Fields.LastTradePrice, quote.LastTradePrice);
                message.TryAdd(Level1Fields.LastTradeVolume, (decimal?)quote.LastTradeVolume);

                if (quote.LastTradeTime != null)
                {
                    message.Add(Level1Fields.LastTradeTime, quote.LastTradeTime.Value.ToDto());
                }

                message.TryAdd(Level1Fields.BestBidPrice, quote.BestBidPrice);
                message.TryAdd(Level1Fields.BestBidVolume, (decimal?)quote.BestBidVolume);

                message.TryAdd(Level1Fields.BestAskPrice, quote.BestAskPrice);
                message.TryAdd(Level1Fields.BestAskVolume, (decimal?)quote.BestAskVolume);

                SendOutMessage(message);
            }
        }
示例#7
0
 private void SessionOnUserMessage(OEC.API.User user, string message)
 {
     SendOutMessage(new Messages.NewsMessage
     {
         Source     = user.Name,
         Headline   = message,
         ServerTime = CurrentTime.Convert(TimeHelper.Est)
     });
 }
示例#8
0
 private void SessionOnNewsMessage(string channel, string message)
 {
     SendOutMessage(new Messages.NewsMessage
     {
         BoardCode  = channel,
         Headline   = message,
         ServerTime = CurrentTime.Convert(TimeHelper.Est)
     });
 }
 private void OnNewsBodyResponse(NewsBodyResponse response)
 {
     SendOutMessage(new NewsMessage
     {
         Id         = response.Id.To <string>(),
         Story      = response.Text,
         ServerTime = CurrentTime.Convert(TimeHelper.Moscow)
     });
 }
示例#10
0
 private void SessionOnNewOrderBook(OrderBook book)
 {
     SendOutMessage(new QuoteChangeMessage
     {
         SecurityId = _btcUsd,
         Bids       = book.Bids.Select(b => b.ToStockSharp(Sides.Buy)),
         Asks       = book.Asks.Select(b => b.ToStockSharp(Sides.Sell)),
         ServerTime = CurrentTime.Convert(TimeZoneInfo.Utc),
     });
 }
 private void OnNewsHeaderResponse(NewsHeaderResponse response)
 {
     SendOutMessage(new NewsMessage
     {
         Source     = response.Source,
         Headline   = response.Title,
         Id         = response.Id.To <string>(),
         Story      = response.Text,
         ServerTime = response.TimeStamp?.ToDto() ?? CurrentTime.Convert(TimeHelper.Moscow),
     });
 }
示例#12
0
 private void SessionOnNewTrade(Trade trade)
 {
     SendOutMessage(new ExecutionMessage
     {
         ExecutionType = ExecutionTypes.Tick,
         SecurityId    = _btcUsd,
         TradeId       = trade.Id,
         TradePrice    = (decimal)trade.Price,
         TradeVolume   = (decimal)trade.Amount,
         ServerTime    = CurrentTime.Convert(TimeZoneInfo.Utc),
     });
 }
        private void OnProcessQuotes(string where, string[] quotes)
        {
            // paper_no нужно парсить из условия where, так как в поле paper_no передается всегда 0
            var paperNo = where.Split('=')[1].Trim().To <int>();
            var f       = Wrapper.FieldsDepth;

            var bids = new List <QuoteChange>();
            var asks = new List <QuoteChange>();

            foreach (var quoteStr in quotes)
            {
                var cols = quoteStr.ToColumns();

                var sellQty = f.SellQty.GetValue(cols);
                var price   = f.Price.GetValue(cols);
                var buyQty  = f.BuyQty.GetValue(cols);

                if (sellQty == 0 && buyQty == 0)
                {
                    // If the sellQty and buyQty are 0 - that is our limit order
                    // which is not a part of the market depth. Just skip it.
                    continue;
                }

                QuoteChange quote;

                if (sellQty == 0)
                {
                    quote = new QuoteChange(Sides.Buy, price, buyQty);
                    bids.Insert(0, quote);
                }
                else
                {
                    quote = new QuoteChange(Sides.Sell, price, sellQty);
                    asks.Add(quote);
                }
            }

            if (bids.Count > 0 || asks.Count > 0)
            {
                SendOutMessage(new QuoteChangeMessage
                {
                    Bids       = bids,
                    Asks       = asks,
                    SecurityId = new SecurityId {
                        Native = paperNo
                    },
                    IsSorted   = true,
                    ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                });
            }
        }
 private void OnMessagesResponse(MessagesResponse response)
 {
     foreach (var message in response.Messages)
     {
         SendOutMessage(new NewsMessage
         {
             Source     = message.From,
             Headline   = message.Text,
             Story      = message.Text,
             ServerTime = message.Date?.ToDto() ?? CurrentTime.Convert(TimeHelper.Moscow),
         });
     }
 }
        private void OnQuoteChanged(string smartId, int row, int rowCount, decimal?bidPrice, decimal?bidVolume, decimal?askPrice, decimal?askVolume)
        {
            //Debug.Write("Row = " + row + " Bid = " + bidPrice + " BidVolume = " + bidVolume + " Ask = " + askPrice + " AskVolume = " + askVolume);
            var secId = new SecurityId {
                Native = smartId
            };

            var tempDepth = _tempDepths.SafeAdd(secId, key => Tuple.Create(new List <QuoteChange>(), new List <QuoteChange>()));

            var bestQuotes = _bestQuotes.SafeAdd(secId);

            try
            {
                if (bidPrice > 0)
                {
                    tempDepth.Item1.Add(new QuoteChange(Sides.Buy, bidPrice.Value, bidVolume ?? 0));

                    if (row == 0)
                    {
                        bestQuotes.First = Tuple.Create(bidPrice.Value, bidVolume ?? 0);
                    }
                }

                if (askPrice > 0)
                {
                    tempDepth.Item2.Add(new QuoteChange(Sides.Sell, askPrice.Value, askVolume ?? 0));

                    if (row == 0)
                    {
                        bestQuotes.Second = Tuple.Create(askPrice.Value, askVolume ?? 0);
                    }
                }
            }
            finally
            {
                if ((row + 1) == rowCount)
                {
                    SendOutMessage(new QuoteChangeMessage
                    {
                        Bids       = tempDepth.Item1.ToArray(),
                        Asks       = tempDepth.Item2.ToArray(),
                        SecurityId = secId,
                        ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                    });

                    tempDepth.Item1.Clear();
                    tempDepth.Item2.Clear();
                }
            }
        }
        private void OnQuotesResponse(QuotesResponse response)
        {
            foreach (var group in response.Quotes.GroupBy(q => q.SecId))
            {
                var tuple = _quotes.SafeAdd(group.Key, key => Tuple.Create(new Dictionary <decimal, decimal>(), new Dictionary <decimal, decimal>()));

                foreach (var quote in group)
                {
                    if (quote.Price == 0)
                    {
                        continue;
                    }

                    if (quote.Buy != null)
                    {
                        if (quote.Buy == -1)
                        {
                            tuple.Item1.Remove(quote.Price);
                        }
                        else
                        {
                            tuple.Item1[quote.Price] = (decimal)quote.Buy;
                        }
                    }

                    if (quote.Sell != null)
                    {
                        if (quote.Sell == -1)
                        {
                            tuple.Item2.Remove(quote.Price);
                        }
                        else
                        {
                            tuple.Item2[quote.Price] = (decimal)quote.Sell;
                        }
                    }
                }

                SendOutMessage(new QuoteChangeMessage
                {
                    SecurityId = new SecurityId {
                        Native = group.Key
                    },
                    Bids       = tuple.Item1.Select(p => new QuoteChange(Sides.Buy, p.Key, p.Value)).ToArray(),
                    Asks       = tuple.Item2.Select(p => new QuoteChange(Sides.Sell, p.Key, p.Value)).ToArray(),
                    ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                });
            }
        }
示例#17
0
 private void OnMessagesResponse(MessagesResponse response)
 {
     foreach (var message in response.Messages)
     {
         SendOutMessage(new NewsMessage
         {
             Source     = message.From,
             Headline   = message.Text,
             Story      = message.Text,
             ServerTime = message.Date == null
                                         ? CurrentTime.Convert(TimeHelper.Moscow)
                                         : message.Date.Value.ApplyTimeZone(TimeHelper.Moscow),
         });
     }
 }
        private void OnSecInfoResponse(SecInfoResponse response)
        {
            var securityId = new SecurityId
            {
                Native       = response.SecId,
                SecurityCode = response.SecCode,
                BoardCode    = _boards[response.Market],
            };

            SendOutMessage(new SecurityMessage
            {
                SecurityId = securityId,
                ExpiryDate = response.MatDate?.ApplyTimeZone(TimeHelper.Moscow),
                OptionType = response.PutCall?.FromTransaq(),
            });

            var l1Msg = new Level1ChangeMessage
            {
                SecurityId = new SecurityId {
                    Native = response.SecId
                },
                ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
            };

            l1Msg.TryAdd(Level1Fields.MinPrice, response.MinPrice);
            l1Msg.TryAdd(Level1Fields.MaxPrice, response.MaxPrice);

            var marginBuy = response.BuyDeposit;

            if (marginBuy == null || marginBuy == 0m)
            {
                marginBuy = response.BgoBuy;
            }

            var marginSell = response.SellDeposit;

            if (marginSell == null || marginSell == 0m)
            {
                marginSell = response.BgoC;
            }

            l1Msg.TryAdd(Level1Fields.MarginBuy, marginBuy);
            l1Msg.TryAdd(Level1Fields.MarginSell, marginSell);

            SendOutMessage(l1Msg);
        }
        private void ProcessOrderCancel(OrderCancelMessage cancelMsg)
        {
            if (cancelMsg.OrderId == null)
            {
                throw new InvalidOperationException(LocalizedStrings.Str2252Params.Put(cancelMsg.OrderTransactionId));
            }

            var isOk = _httpClient.CancelOrder(cancelMsg.OrderId.Value);

            SendOutMessage(new ExecutionMessage
            {
                ServerTime            = CurrentTime.Convert(TimeZoneInfo.Utc),
                ExecutionType         = ExecutionTypes.Transaction,
                OriginalTransactionId = cancelMsg.TransactionId,
                OrderState            = isOk ? OrderStates.Done : OrderStates.Failed,
                Error = isOk ? null : new InvalidOperationException(LocalizedStrings.Str3300),
            });
        }
        private IEnumerable <Message> ToSecurityFundamentalMessages(string value)
        {
            var parts = value.SplitByComma();

            var pe                   = parts[2].To <decimal?>();
            var beta                 = parts[26].To <decimal?>();
            var precision            = parts[39].To <int>();
            var sic                  = parts[40].To <int?>();
            var historicalVolatility = parts[41].To <decimal?>();
            var securityType         = parts[42].To <int>();
            var listedMarket         = parts[43].To <int>();
            var maturityDate         = parts[49].TryToDateTime("MM/dd/yyyy").ToEst();
            var expirationDate       = parts[51].TryToDateTime("MM/dd/yyyy").ToEst();
            var strikePrice          = parts[52].To <decimal?>();
            var naics                = parts[53].To <int?>();
            var exchangeRoot         = parts[54];

            var secId = CreateSecurityId(parts[0], listedMarket);

            yield return(new SecurityMessage
            {
                SecurityId = secId,
                Decimals = precision,
                Strike = strikePrice ?? 0,
                ExpiryDate = expirationDate ?? maturityDate,
                SecurityType = _securityTypes[securityType],
                UnderlyingSecurityCode = exchangeRoot,
                ExtensionInfo = new Dictionary <object, object>
                {
                    { "SIC", sic },
                    { "NAICS", naics },
                }
            });

            yield return(new Level1ChangeMessage
            {
                SecurityId = secId,
                ServerTime = CurrentTime.Convert(TimeHelper.Est)
            }
                         .TryAdd(Level1Fields.HistoricalVolatility, historicalVolatility)
                         .TryAdd(Level1Fields.Beta, beta)
                         .TryAdd(Level1Fields.PriceEarnings, pe));
        }
示例#21
0
        private void ProcessLevel1()
        {
            var currTime = CurrentTime;

            if ((currTime - _prevLevel1Time) < _level1Interval)
            {
                return;
            }

            _prevLevel1Time = currTime;

            var btcUsd = _httpClient.RequestBtcUsd();

            if (btcUsd != null)
            {
                SendOutMessage(new Level1ChangeMessage
                {
                    SecurityId = _btcUsd,
                    ServerTime = btcUsd.Time.ApplyTimeZone(TimeZoneInfo.Utc)
                }
                               .TryAdd(Level1Fields.HighBidPrice, (decimal)btcUsd.High)
                               .TryAdd(Level1Fields.LowAskPrice, (decimal)btcUsd.Low)
                               .TryAdd(Level1Fields.VWAP, (decimal)btcUsd.VWAP)
                               .TryAdd(Level1Fields.LastTradePrice, (decimal)btcUsd.Last)
                               .TryAdd(Level1Fields.Volume, (decimal)btcUsd.Volume)
                               .TryAdd(Level1Fields.BestBidPrice, (decimal)btcUsd.Bid)
                               .TryAdd(Level1Fields.BestAskPrice, (decimal)btcUsd.Ask));
            }

            var eurUsd = _httpClient.RequestEurUsd();

            if (eurUsd != null)
            {
                SendOutMessage(new Level1ChangeMessage
                {
                    SecurityId = _eurUsd,
                    ServerTime = CurrentTime.Convert(TimeZoneInfo.Utc),
                }
                               .TryAdd(Level1Fields.BestBidPrice, (decimal)eurUsd.Buy)
                               .TryAdd(Level1Fields.BestAskPrice, (decimal)eurUsd.Sell));
            }
        }
示例#22
0
        private void OnSessionInstructionRejected(InstructionRejectedEvent evt)
        {
            var transactionId = TryParseTransactionId(evt.InstructionId);

            if (transactionId == null)
            {
                return;
            }

            SendOutMessage(new ExecutionMessage
            {
                ExecutionType = ExecutionTypes.Order,
                SecurityId    = new SecurityId {
                    Native = evt.InstrumentId
                },
                OriginalTransactionId = transactionId.Value,
                OrderState            = OrderStates.Failed,
                Error         = new InvalidOperationException(evt.Reason),
                PortfolioName = evt.AccountId.To <string>(),
                ServerTime    = CurrentTime.Convert(TimeZoneInfo.Utc)
            });
        }
        private void OnSecurityChanged(string smartId, Tuple <decimal?, decimal?, DateTime> lastTrade, decimal?open, decimal?high, decimal?low, decimal?close, decimal?volume, QuoteChange bid, QuoteChange ask,
                                       decimal?openInt, Tuple <decimal?, decimal?> goBuySell, Tuple <decimal?, decimal?> goBase, Tuple <decimal?, decimal?> limits, int tradingStatus, Tuple <decimal?, decimal?> volatTheorPrice)
        {
            var secId = new SecurityId {
                Native = smartId
            };

            var message = new Level1ChangeMessage
            {
                SecurityId    = secId,
                ExtensionInfo = new Dictionary <object, object>
                {
                    { SmartComExtensionInfoHelper.SecurityOptionsMargin, goBase.Item1 },
                    { SmartComExtensionInfoHelper.SecurityOptionsSyntheticMargin, goBase.Item2 }
                },
                ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
            };

            message.TryAdd(Level1Fields.LastTradePrice, lastTrade.Item1);
            message.TryAdd(Level1Fields.LastTradeVolume, lastTrade.Item2);
            message.Add(Level1Fields.LastTradeTime, lastTrade.Item3.ApplyTimeZone(TimeHelper.Moscow));

            var prevQuotes = _bestQuotes.TryGetValue(secId);

            if (bid.Price != 0)
            {
                message.Add(Level1Fields.BestBidPrice, bid.Price);

                if (prevQuotes != null && prevQuotes.First != null && prevQuotes.First.Item1 == bid.Price)
                {
                    message.Add(Level1Fields.BestBidVolume, prevQuotes.First.Item2);
                }
            }

            if (ask.Price != 0)
            {
                message.Add(Level1Fields.BestAskPrice, ask.Price);

                if (prevQuotes != null && prevQuotes.Second != null && prevQuotes.Second.Item1 == ask.Price)
                {
                    message.Add(Level1Fields.BestAskVolume, prevQuotes.Second.Item2);
                }
            }

            message.TryAdd(Level1Fields.BidsVolume, bid.Volume);
            message.TryAdd(Level1Fields.AsksVolume, ask.Volume);

            message.TryAdd(Level1Fields.OpenPrice, open);
            message.TryAdd(Level1Fields.LowPrice, low);
            message.TryAdd(Level1Fields.HighPrice, high);
            message.TryAdd(Level1Fields.ClosePrice, close);

            message.TryAdd(Level1Fields.MinPrice, limits.Item1);
            message.TryAdd(Level1Fields.MaxPrice, limits.Item2);

            message.TryAdd(Level1Fields.MarginBuy, goBuySell.Item1);
            message.TryAdd(Level1Fields.MarginSell, goBuySell.Item2);
            message.TryAdd(Level1Fields.OpenInterest, openInt);

            message.TryAdd(Level1Fields.ImpliedVolatility, volatTheorPrice.Item1);
            message.TryAdd(Level1Fields.TheorPrice, volatTheorPrice.Item2);

            message.TryAdd(Level1Fields.Volume, volume);

            message.Add(Level1Fields.State, tradingStatus == 0 ? SecurityStates.Trading : SecurityStates.Stoped);

            SendOutMessage(message);
        }
        private void OnNewSecurity(int row, int rowCount, string smartId, string name, string secCode, string secClass, int decimals, int lotSize,
                                   decimal?stepPrice, decimal?priceStep, string isin, string board, DateTime?expiryDate, decimal?daysBeforeExpiry, decimal?strike)
        {
            //AMU: заглушка. 11.01.2013 обнаружил, что через SmartCom стали приходить инструменты (класс EQBR и FISS) с пустым secCode - "longName" в понятии АйтиИнвеста
            if (secCode.IsEmpty())
            {
                secCode = smartId;
            }

            var securityId = new SecurityId
            {
                SecurityCode = secCode,
                BoardCode    = board,
                Native       = smartId,
                Isin         = isin
            };

            if (secClass.IsEmpty())
            {
                secClass = board;
            }

            var secMsg = new SecurityMessage
            {
                PriceStep     = priceStep,
                Decimals      = decimals,
                Multiplier    = lotSize,
                Name          = name,
                ShortName     = name,
                ExpiryDate    = expiryDate?.ApplyTimeZone(TimeHelper.Moscow),
                ExtensionInfo = new Dictionary <object, object>
                {
                    { "Class", secClass }
                },
                OriginalTransactionId = _lookupSecuritiesId
            };

            if (secClass.CompareIgnoreCase("IDX"))
            {
                secMsg.SecurityType = SecurityTypes.Index;

                switch (secMsg.SecurityId.BoardCode)
                {
                case "RUSIDX":
                    securityId.BoardCode = secCode.ContainsIgnoreCase("MICEX") || secCode.ContainsIgnoreCase("MCX") ? ExchangeBoard.Micex.Code : ExchangeBoard.Forts.Code;
                    break;
                    //default:
                    //	security.Board = ExchangeBoard.Test;
                    //	break;
                }
            }
            else
            {
                var info = SecurityClassInfo.GetSecurityClassInfo(secClass);

                secMsg.SecurityType  = info.Item1;
                securityId.BoardCode = info.Item2;

                // http://stocksharp.com/forum/yaf_postsm16847_Vopros-po-vystavlieniiu-zaiavok.aspx#post16847
                if (ExchangeBoard.GetOrCreateBoard(info.Item2).IsMicex
                    &&
                    /* проверяем, что не началась ли трансляция правильных дробных шагов */
                    secMsg.PriceStep != null && secMsg.PriceStep == (int)secMsg.PriceStep)
                {
                    // http://stocksharp.com/forum/yaf_postsm21245_Sokhranieniie-stakanov-po-GAZP-EQNE.aspx#post21245
                    secMsg.PriceStep = 1m / 10m.Pow(secMsg.PriceStep.Value);
                }
            }

            secMsg.SecurityId = securityId;

            if (secMsg.SecurityType == SecurityTypes.Option)
            {
                var optionInfo = secMsg.Name.GetOptionInfo(ExchangeBoard.Forts);

                if (optionInfo != null)
                {
                    // http://stocksharp.com/forum/yaf_postst1355_Exception-Change-Set-11052.aspx
                    if (!secCode.IsEmpty())
                    {
                        var futureInfo = optionInfo.UnderlyingSecurityId.GetFutureInfo(secCode, ExchangeBoard.Forts);
                        if (futureInfo != null)
                        {
                            secMsg.UnderlyingSecurityCode = futureInfo.SecurityId.SecurityCode;
                        }
                    }

                    secMsg.ExpiryDate = optionInfo.ExpiryDate;
                    secMsg.OptionType = optionInfo.OptionType;
                    secMsg.Strike     = optionInfo.Strike;
                }
            }

            SendOutMessage(secMsg);

            if (stepPrice != null)
            {
                SendOutMessage(
                    new Level1ChangeMessage
                {
                    SecurityId = securityId,
                    ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                }
                    .TryAdd(Level1Fields.StepPrice, stepPrice.Value));
            }

            if ((row + 1) < rowCount)
            {
                return;
            }

            SendOutMessage(new SecurityLookupResultMessage {
                OriginalTransactionId = _lookupSecuritiesId
            });
            _lookupSecuritiesId = 0;
        }
        private void OnSessionOrderChanged(LmaxOrder lmaxOrder)
        {
            var transactionId = TryParseTransactionId(lmaxOrder.InstructionId);

            if (transactionId == null)
            {
                return;
            }

            LmaxOrderCondition condition = null;
            decimal            price     = 0;
            OrderTypes         orderType;

            switch (lmaxOrder.OrderType)
            {
            case OrderType.MARKET:
                orderType = OrderTypes.Market;
                break;

            case OrderType.LIMIT:
                orderType = OrderTypes.Limit;

                if (lmaxOrder.LimitPrice == null)
                {
                    throw new ArgumentException(LocalizedStrings.Str3394Params.Put(transactionId), nameof(lmaxOrder));
                }

                price = (decimal)lmaxOrder.LimitPrice;
                break;

            case OrderType.STOP_ORDER:
            case OrderType.STOP_LOSS_MARKET_ORDER:
            case OrderType.STOP_PROFIT_LIMIT_ORDER:
                orderType = OrderTypes.Conditional;

                if (lmaxOrder.StopPrice == null)
                {
                    throw new ArgumentException(LocalizedStrings.Str3395Params.Put(transactionId), nameof(lmaxOrder));
                }

                price = (decimal)lmaxOrder.StopPrice;

                condition = new LmaxOrderCondition
                {
                    StopLossOffset   = lmaxOrder.StopLossOffset,
                    TakeProfitOffset = lmaxOrder.StopProfitOffset,
                };
                break;

            case OrderType.CLOSE_OUT_ORDER_POSITION:
            case OrderType.CLOSE_OUT_POSITION:
            case OrderType.SETTLEMENT_ORDER:
            case OrderType.OFF_ORDERBOOK:
            case OrderType.REVERSAL:
            case OrderType.UNKNOWN:
                orderType = OrderTypes.Execute;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            DateTimeOffset?expiryDate = null;
            var            tif        = StockSharpTimeInForce.PutInQueue;

            switch (lmaxOrder.TimeInForce)
            {
            case LmaxTimeInForce.FillOrKill:
                tif = StockSharpTimeInForce.MatchOrCancel;
                break;

            case LmaxTimeInForce.ImmediateOrCancel:
                tif = StockSharpTimeInForce.CancelBalance;
                break;

            case LmaxTimeInForce.GoodForDay:
                expiryDate = DateTime.Today.ApplyTimeZone(TimeZoneInfo.Utc);
                break;

            case LmaxTimeInForce.GoodTilCancelled:
                break;

            case LmaxTimeInForce.Unknown:
                throw new NotSupportedException(LocalizedStrings.Str3396Params.Put(lmaxOrder.TimeInForce, transactionId.Value, lmaxOrder.OrderId));

            default:
                throw new InvalidOperationException(LocalizedStrings.Str3397Params.Put(lmaxOrder.TimeInForce, transactionId.Value, lmaxOrder.OrderId));
            }

            var msg = new ExecutionMessage
            {
                SecurityId = new SecurityId {
                    Native = lmaxOrder.InstrumentId
                },
                OriginalTransactionId = transactionId.Value,
                OrderType             = orderType,
                OrderPrice            = price,
                Condition             = condition,
                OrderVolume           = lmaxOrder.Quantity.Abs(),
                Side          = lmaxOrder.Quantity > 0 ? Sides.Buy : Sides.Sell,
                Balance       = lmaxOrder.Quantity - lmaxOrder.FilledQuantity,
                PortfolioName = lmaxOrder.AccountId.To <string>(),
                TimeInForce   = tif,
                ExpiryDate    = expiryDate,
                OrderStringId = lmaxOrder.OrderId,
                ExecutionType = ExecutionTypes.Transaction,
                Commission    = lmaxOrder.Commission,
                ServerTime    = CurrentTime.Convert(TimeZoneInfo.Utc),
                HasOrderInfo  = true,
            };

            msg.OrderState = lmaxOrder.CancelledQuantity > 0
                                                                ? OrderStates.Done
                                                                : (msg.Balance == 0 ? OrderStates.Done : OrderStates.Active);

            //msg.Action = lmaxOrder.CancelledQuantity > 0
            //				 ? ExecutionActions.Canceled
            //				 : (lmaxOrder.FilledQuantity == 0 ? ExecutionActions.Registered : ExecutionActions.Matched);

            SendOutMessage(msg);
        }
        private void SearchSecurities(string secCode, long transactionId, ICollection <Instrument> instruments, bool hasMoreResults)
        {
            if (secCode.IsEmpty())
            {
                throw new ArgumentNullException(nameof(secCode), LocalizedStrings.Str3391);
            }

            if (instruments == null)
            {
                throw new ArgumentNullException(nameof(instruments));
            }

            foreach (var instrument in instruments)
            {
                SecurityTypes type;
                var           typeName = instrument.Underlying.AssetClass.ToUpperInvariant();
                switch (typeName)
                {
                case "COMMODITY":
                    type = SecurityTypes.Commodity;
                    break;

                case "CURRENCY":
                    type = SecurityTypes.Currency;
                    break;

                case "INDEX":
                    type = SecurityTypes.Index;
                    break;

                default:
                    SendOutError(LocalizedStrings.Str2140Params.Put(typeName));
                    continue;
                }

                var securityId = new SecurityId
                {
                    SecurityCode = instrument.Underlying.Symbol,
                    BoardCode    = ExchangeBoard.Lmax.Code,
                    Native       = instrument.Id
                };

                SendOutMessage(new SecurityMessage
                {
                    SecurityId            = securityId,
                    Name                  = instrument.Name,
                    PriceStep             = instrument.OrderBook.PriceIncrement,
                    VolumeStep            = instrument.OrderBook.QuantityIncrement,
                    Multiplier            = instrument.Contract.ContractSize,
                    Currency              = instrument.Contract.Currency.To <CurrencyTypes>(),
                    ExpiryDate            = instrument.Calendar.ExpiryTime == null ? (DateTimeOffset?)null : instrument.Calendar.ExpiryTime.Value.ApplyTimeZone(TimeZoneInfo.Utc),
                    SecurityType          = type,
                    OriginalTransactionId = transactionId,
                });

                SendOutMessage(
                    new Level1ChangeMessage
                {
                    SecurityId = securityId,
                    ServerTime = CurrentTime.Convert(TimeZoneInfo.Utc),
                }
                    .TryAdd(Level1Fields.StepPrice, instrument.Contract.UnitPrice));
            }

            if (hasMoreResults)
            {
                _session.SearchInstruments(new SearchRequest(secCode, instruments.Count), (i, h) => SearchSecurities(secCode, transactionId, i, h), CreateErrorHandler("SearchInstruments"));
            }
            else
            {
                SendOutMessage(new SecurityLookupResultMessage {
                    OriginalTransactionId = transactionId
                });
            }
        }
        private IEnumerable <Message> ToSecurityUpdateMessage(string value)
        {
            var parts = value.SplitByComma();

            var index = 0;

            var secCode    = parts[index++];
            var exchangeId = int.Parse(parts[index++], NumberStyles.HexNumber);
            var tradeBoard = parts[index++].To <int?>();
            var bidBoard   = parts[index++].To <int?>();
            var askBoard   = parts[index++].To <int?>();

            var l1Messages = new[] { exchangeId, tradeBoard, bidBoard, askBoard }
            .Where(id => id != null)
            .Select(id => id.Value)
            .Distinct()
            .ToDictionary(boardId => boardId, boardId => new Level1ChangeMessage
            {
                SecurityId = CreateSecurityId(secCode, boardId)
            });

            DateTime?lastTradeDate   = null;
            TimeSpan?lastTradeTime   = null;
            decimal? lastTradePrice  = null;
            decimal? lastTradeVolume = null;
            long?    lastTradeId     = null;

            var types = new HashSet <Level1Fields>(Enumerator.GetValues <Level1Fields>());
            var messageContentsIndex = Level1Columns.IndexOf(Level1ColumnRegistry.MessageContents);

            if (messageContentsIndex != -1)
            {
                types.Exclude(parts[messageContentsIndex + index]);
            }

            if (tradeBoard == null)
            {
                types.Remove(Level1Fields.LastTradeId);
                types.Remove(Level1Fields.LastTradeTime);
                types.Remove(Level1Fields.LastTradePrice);
                types.Remove(Level1Fields.LastTradeVolume);
            }

            if (bidBoard == null)
            {
                types.Remove(Level1Fields.BestBidTime);
                types.Remove(Level1Fields.BestBidPrice);
                types.Remove(Level1Fields.BestBidVolume);
            }

            if (askBoard == null)
            {
                types.Remove(Level1Fields.BestAskTime);
                types.Remove(Level1Fields.BestAskPrice);
                types.Remove(Level1Fields.BestAskVolume);
            }

            foreach (var column in Level1Columns)
            {
                var colValue = parts[index++];

                if (colValue.IsEmpty())
                {
                    continue;
                }

                //colValue = colValue.To(column.Type);

                switch (column.Field)
                {
                case IQFeedLevel1Column.DefaultField:
                {
                    var typedColValue = column.Convert(colValue);

                    if (typedColValue != null)
                    {
                        l1Messages[exchangeId].AddValue(column.Name, typedColValue);
                    }

                    break;
                }

                case Level1Fields.LastTradeId:
                    if (types.Contains(column.Field))
                    {
                        lastTradeId = colValue.To <long?>();

                        if (lastTradeId != null && lastTradeId != 0)
                        {
                            l1Messages[tradeBoard.Value].Add(column.Field, lastTradeId.Value);
                        }
                    }
                    break;

                case Level1Fields.LastTradeTime:
                    if (types.Contains(column.Field))
                    {
                        if (column == Level1ColumnRegistry.LastDate)
                        {
                            lastTradeDate = colValue.TryToDateTime(column.Format);
                        }
                        else if (column == Level1ColumnRegistry.LastTradeTime)
                        {
                            lastTradeTime = column.ConvertToTimeSpan(colValue);
                        }

                        if (lastTradeDate.HasValue && lastTradeTime.HasValue)
                        {
                            var l1Msg = l1Messages[tradeBoard.Value];
                            l1Msg.ServerTime = (lastTradeDate.Value + lastTradeTime.Value).ApplyTimeZone(TimeHelper.Est);
                            l1Msg.Add(Level1Fields.LastTradeTime, l1Msg.ServerTime);
                        }
                    }
                    break;

                case Level1Fields.LastTradePrice:
                case Level1Fields.LastTradeVolume:
                    if (types.Contains(column.Field))
                    {
                        var decValue = colValue.To <decimal?>();

                        l1Messages[tradeBoard.Value].TryAdd(column.Field, decValue);

                        if (column == Level1ColumnRegistry.LastTradePrice)
                        {
                            lastTradePrice = decValue;
                        }
                        else                                // if (column == SessionHolder.Level1ColumnRegistry.LastTradeVolume)
                        {
                            lastTradeVolume = decValue;
                        }
                    }
                    break;

                case Level1Fields.BestBidTime:
                    if (types.Contains(column.Field))
                    {
                        var typedColValue = column.ConvertToTimeSpan(colValue);

                        if (typedColValue != null)
                        {
                            var l1Msg = l1Messages[bidBoard.Value];
                            l1Msg.ServerTime = (DateTime.Today + typedColValue.Value).ApplyTimeZone(TimeHelper.Est);
                            l1Msg.Add(Level1Fields.BestBidTime, l1Msg.ServerTime);
                        }
                    }
                    break;

                case Level1Fields.BestBidPrice:
                case Level1Fields.BestBidVolume:
                    if (types.Contains(column.Field))
                    {
                        l1Messages[bidBoard.Value].TryAdd(column.Field, colValue.To <decimal?>());
                    }
                    break;

                case Level1Fields.BestAskTime:
                    if (types.Contains(column.Field))
                    {
                        var typedColValue = column.ConvertToTimeSpan(colValue);

                        if (typedColValue != null)
                        {
                            var l1Msg = l1Messages[askBoard.Value];
                            l1Msg.ServerTime = (DateTime.Today + typedColValue.Value).ApplyTimeZone(TimeHelper.Est);
                            l1Msg.Add(Level1Fields.BestAskTime, l1Msg.ServerTime);
                        }
                    }
                    break;

                case Level1Fields.BestAskPrice:
                case Level1Fields.BestAskVolume:
                    if (types.Contains(column.Field))
                    {
                        l1Messages[askBoard.Value].TryAdd(column.Field, colValue.To <decimal?>());
                    }
                    break;

                case Level1Fields.OpenInterest:
                case Level1Fields.OpenPrice:
                case Level1Fields.HighPrice:
                case Level1Fields.LowPrice:
                case Level1Fields.ClosePrice:
                case Level1Fields.SettlementPrice:
                case Level1Fields.VWAP:
                    if (types.Contains(column.Field))
                    {
                        l1Messages[exchangeId].TryAdd(column.Field, colValue.To <decimal?>());
                    }
                    break;

                default:
                    if (types.Contains(column.Field))
                    {
                        var typedColValue = column.Convert(colValue);

                        if (typedColValue != null)
                        {
                            l1Messages[exchangeId].Add(column.Field, typedColValue);
                        }
                    }
                    break;
                }
            }

            foreach (var l1Msg in l1Messages.Values)
            {
                if (l1Msg.Changes.Count <= 0)
                {
                    continue;
                }

                yield return(new SecurityMessage {
                    SecurityId = l1Msg.SecurityId
                });

                if (l1Msg.ServerTime.IsDefault())
                {
                    l1Msg.ServerTime = CurrentTime.Convert(TimeHelper.Est);
                }

                yield return(l1Msg);
            }

            if (!types.Contains(Level1Fields.LastTrade) || !lastTradeDate.HasValue || !lastTradeTime.HasValue ||
                !lastTradeId.HasValue || !lastTradePrice.HasValue || !lastTradeVolume.HasValue)
            {
                yield break;
            }

            yield return(new ExecutionMessage
            {
                SecurityId = l1Messages[tradeBoard.Value].SecurityId,
                TradeId = lastTradeId.Value,
                ServerTime = (lastTradeDate.Value + lastTradeTime.Value).ApplyTimeZone(TimeHelper.Est),
                TradePrice = lastTradePrice.Value,
                Volume = lastTradeVolume.Value,
                ExecutionType = ExecutionTypes.Tick,
            });
        }
        private void ProcessSubscriptions()
        {
            if (_subscribedLevel1.Count > 0)
            {
                var tickerReply = _client.GetTickers(_subscribedLevel1.Cache.Select(id => id.SecurityCode.ToBtceCode()));

                foreach (var ticker in tickerReply.Items.Values)
                {
                    var l1Msg = new Level1ChangeMessage
                    {
                        SecurityId = new SecurityId
                        {
                            SecurityCode = ticker.Instrument.ToStockSharpCode(),
                            BoardCode    = _boardCode,
                        },
                        ServerTime = ticker.Timestamp.ApplyTimeZone(TimeHelper.Moscow)
                    }
                    .TryAdd(Level1Fields.Volume, (decimal)ticker.Volume)
                    .TryAdd(Level1Fields.HighPrice, (decimal)ticker.HighPrice)
                    .TryAdd(Level1Fields.LowPrice, (decimal)ticker.LowPrice)
                    .TryAdd(Level1Fields.LastTradePrice, (decimal)ticker.LastPrice)

                    // BTCE транслирует потенциальные цену для покупки и продажи
                    .TryAdd(Level1Fields.BestBidPrice, (decimal)ticker.Ask)
                    .TryAdd(Level1Fields.BestAskPrice, (decimal)ticker.Bid)
                    .TryAdd(Level1Fields.AveragePrice, (decimal)ticker.AveragePrice);

                    if (l1Msg.Changes.Count > 0)
                    {
                        SendOutMessage(l1Msg);
                    }
                }
            }

            if (_subscribedDepths.Count > 0)
            {
                foreach (var group in _subscribedDepths.CachedPairs.GroupBy(p => p.Value))
                {
                    var depthReply = _client.GetDepths(group.Key, group.Select(p => p.Key).Select(id => id.SecurityCode.ToBtceCode()));

                    foreach (var pair in depthReply.Items)
                    {
                        SendOutMessage(new QuoteChangeMessage
                        {
                            SecurityId = new SecurityId
                            {
                                SecurityCode = pair.Key.ToStockSharpCode(),
                                BoardCode    = _boardCode,
                            },
                            Bids       = pair.Value.Bids.Select(vp => vp.ToStockSharp(Sides.Buy)).ToArray(),
                            Asks       = pair.Value.Asks.Select(vp => vp.ToStockSharp(Sides.Sell)).ToArray(),
                            ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
                        });
                    }
                }
            }

            if (_subscribedTicks.Count > 0)
            {
                var tradeReply = _client.GetTrades(_tickCount, _subscribedTicks.Cache.Select(id => id.SecurityCode.ToBtceCode()));

                // меняем на глубину 50
                _tickCount = 50;

                foreach (var pair in tradeReply.Items)
                {
                    foreach (var trade in pair.Value.OrderBy(t => t.Id))
                    {
                        if (_lastTickId >= trade.Id)
                        {
                            continue;
                        }

                        _lastTickId = trade.Id;

                        SendOutMessage(new ExecutionMessage
                        {
                            SecurityId = new SecurityId
                            {
                                SecurityCode = pair.Key.ToStockSharpCode(),
                                BoardCode    = _boardCode,
                            },
                            ExecutionType = ExecutionTypes.Tick,
                            TradePrice    = (decimal)trade.Price,
                            Volume        = (decimal)trade.Volume,
                            TradeId       = trade.Id,
                            ServerTime    = trade.Timestamp.ApplyTimeZone(TimeHelper.Moscow),
                            OriginSide    = trade.Side.ToStockSharp()
                        });
                    }
                }
            }
        }
示例#29
0
        private IEnumerable <Message> ParseMessages(IQFeedWrapper feed, string str, MessageTypes type, long requestId)
        {
            switch (type)
            {
            case ExtendedMessageTypes.System:
                yield return(new IQFeedSystemMessage(feed, str));

                break;

            case ExtendedMessageTypes.SecurityType:
            {
                var parts = str.SplitByComma();
                yield return(new IQFeedSecurityTypeMessage(parts[0].To <int>(), parts[1], parts[2]));

                break;
            }

            case ExtendedMessageTypes.ListedMarket:
            {
                var parts = str.SplitByComma();
                yield return(new IQFeedListedMarketMessage(parts[0].To <int>(), parts[1], parts[2]));

                break;
            }

            case ExtendedMessageTypes.Data:
                yield return(new IQFeedDataMessage(str));

                break;

            case ExtendedMessageTypes.End:
                yield return(new IQFeedEndMessage());

                break;

            case MessageTypes.Time:
                yield return(new TimeMessage {
                    ServerTime = str.ToDateTime("yyyyMMdd HH:mm:ss").ApplyTimeZone(TimeHelper.Est)
                });

                break;

            case MessageTypes.Security:
            {
                var parts = str.SplitByComma();

                yield return(new SecurityMessage
                    {
                        SecurityId = CreateSecurityId(parts[0], parts[1].To <int>()),
                        Name = parts[3],
                        OriginalTransactionId = requestId,
                        SecurityType = _securityTypes[parts[2].To <int>()],
                    });

                break;
            }

            case ExtendedMessageTypes.Fundamental:
            {
                foreach (var result in ToSecurityFundamentalMessages(str))
                {
                    yield return(result);
                }

                break;
            }

            case MessageTypes.Level1Change:
            {
                foreach (var result in ToSecurityUpdateMessage(str))
                {
                    yield return(result);
                }

                break;
            }

            case MessageTypes.Execution:
            {
                yield return(ToLevel1(str, _secIds[requestId]));

                break;
            }

            case MessageTypes.News:
                yield return(ToNewsMessage(str));

                break;

            case ExtendedMessageTypes.NewsStory:
            {
                yield return(new NewsMessage
                    {
                        Id = _newsIds[requestId],
                        Story = str.StripBrackets("<BEGIN>", "<END>"),
                        ServerTime = CurrentTime.Convert(TimeHelper.Est)
                    });

                break;
            }

            case MessageTypes.CandleTimeFrame:
            case MessageTypes.CandleTick:
            case MessageTypes.CandleVolume:
            case ExtendedMessageTypes.HistoryExtraDayCandle:
            {
                var parts = str.SplitByComma();

                var tuple = _candleParsers[requestId];

                var candleMsg = tuple.Item1(parts);

                candleMsg.OriginalTransactionId = requestId;
                candleMsg.SecurityId            = _secIds[requestId];

                if (tuple.Item2 is TimeSpan)
                {
                    var tf = (TimeSpan)tuple.Item2;

                    if (tf == TimeSpan.FromDays(1))
                    {
                        candleMsg.OpenTime  = candleMsg.CloseTime;
                        candleMsg.CloseTime = candleMsg.OpenTime.EndOfDay();
                    }
                    else                            // if (tf == TimeSpan.FromDays(7) || tf.Ticks == TimeHelper.TicksPerMonth)
                    {
                        candleMsg.CloseTime -= TimeSpan.FromTicks(1);
                        candleMsg.OpenTime   = tf.GetCandleBounds(candleMsg.CloseTime.ToLocalTime(TimeHelper.Est)).Min;
                    }
                }
                else
                {
                    candleMsg.OpenTime = candleMsg.CloseTime;
                }

                yield return(candleMsg);

                break;
            }

            case MessageTypes.QuoteChange:
            {
                var l1Msg = ToLevel2(str);

                if (l1Msg != null)
                {
                    yield return(l1Msg);
                }

                break;
            }

            case MessageTypes.Error:
                yield return(new ErrorMessage {
                    Error = new InvalidOperationException(str)
                });

                break;

            default:
                throw new InvalidOperationException(LocalizedStrings.Str2142Params.Put(type));
            }
        }