/// <summary>
        /// сообщение содержит котировку: одну цену либо бид и аск сразу
        /// </summary>
        public static void ProcessMsgQuote(FixMessage msg)
        {
            loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                     LogMagicMarketData, 1000 * 60 * 60 * 2, "Quote: {0}", msg.ToString());

            string symbol = msg.GetValueString(FixMessage.TAG_SYMBOL);

            if (string.IsNullOrEmpty(symbol))
            {
                Logger.Debug("Quote msg: no symbol tag");
                return;
            }

            if (!ConvertFromProviderSymbolNaming(ref symbol))
            {
                return;
            }

            var bid = msg.GetValueFloat(FixMessage.TAG_BID_PRICE);
            var ask = msg.GetValueFloat(FixMessage.TAG_OFFER_PRICE);

            if (!bid.HasValue && ask.HasValue == false)
            {
                Logger.Debug("Quote msg: no bid - ask");
                return;
            }
            QuoteDistributor.Instance.UpdateQuote(symbol, bid, ask);
        }
        public static void ProcessMsgMarketDataFullRefresh(Message msgOrig, FixMessage msg)
        {
            loggerNoFlood.LogMessageFormatCheckFlood(
                LogEntryType.Info,
                LogMagicMarketData,
                1000 * 60 * 60 * 2, "Quote full: {0}", msg.ToString());

            // 8=FIX.4.4#9=128#35=W#34=2#49=XTB#52=20141125-16:12:33.269#56=PARTNER1#55=USDJPY..#262=USDJPY-25-16-12#268=2#269=0#270=117.906#10=097#

            try
            {
                var reqIdField = msgOrig.getField(new MDReqID());
                if (reqIdField == null)
                    throw new Exception("Поле MDReqID не прочитано");
                // инструмент указан в самом запросе
                var requestedSymbol = msg.GetValueString(FixMessage.TAG_SYMBOL);
                //requestedSymbol = TickerCodeDictionary.Instance.GetClearTickerName(requestedSymbol);
                // котировка будет исправлена в дальнейшем

                var groupHeader = new NoMDEntries();
                msgOrig.getField(groupHeader);
                var numGroups = groupHeader.getValue();

                if (numGroups == 0)
                    throw new Exception("Поле NoMDEntries не прочитано");

                var group = FixMessage.FixVersion == FixVersion.Fix42
                                ? new QuickFix42.MarketDataIncrementalRefresh.NoMDEntries()
                                : FixMessage.FixVersion == FixVersion.Fix43
                                      ? (Group)new QuickFix43.MarketDataIncrementalRefresh.NoMDEntries()
                                      : new QuickFix44.MarketDataIncrementalRefresh.NoMDEntries();

                float bid = 0, ask = 0;
                for (var i = 1; i <= numGroups; i++)
                {
                    var groupTicker = msgOrig.getGroup((uint)i, group);
                    // тип (бид или аск)
                    var isBid = true;
                    var typeField = groupTicker.getField(new MDEntryType());
                    if (typeField == null)
                        throw new Exception("Поле MDEntryType не прочитано");
                    isBid = typeField.getValue() == '0';
                    // цена
                    var priceField = group.getField(new MDEntryPx());
                    if (priceField == null)
                        throw new Exception("Поле MDEntryPx не прочитано");
                    var price = priceField.getValue();
                    if (isBid)
                        bid = (float)price;
                    else
                        ask = (float)price;
                }
                // цены прочитаны?
                if (bid == 0 || ask == 0)
                {
                    loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                             LogMagicLackPrice,
                                                             1000 * 60 * 10, "MarketDataFullRefresh - нет цены (" +
                                                             bid.ToStringUniformPriceFormat() + ", " + ask.ToStringUniformPriceFormat() + ")");
                    return;
                }

                // обновить котировку
                QuoteDistributor.Instance.UpdateQuote(requestedSymbol, bid, ask);

                loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                         LogMagicParseMarketDataSuccess,
                                                         1000 * 60 * 10,
                                                         "Обработан пакет MarketDataFullRefresh - {0}: {1}/{2}",
                                                         requestedSymbol, bid, ask);
            }
            catch (Exception ex)
            {
                loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                         LogMagicParseMarketDataError,
                                                         1000 * 60 * 10, "Ошибка разбора MarketDataFullRefresh: {0}", ex);
            }
        }
        public static void ProcessMsgMarketDataFullRefresh(Message msgOrig, FixMessage msg)
        {
            loggerNoFlood.LogMessageFormatCheckFlood(
                LogEntryType.Info,
                LogMagicMarketData,
                1000 * 60 * 60 * 2, "Quote full: {0}", msg.ToString());

            // 8=FIX.4.4#9=128#35=W#34=2#49=XTB#52=20141125-16:12:33.269#56=PARTNER1#55=USDJPY..#262=USDJPY-25-16-12#268=2#269=0#270=117.906#10=097#

            try
            {
                var reqIdField = msgOrig.getField(new MDReqID());
                if (reqIdField == null)
                {
                    throw new Exception("Поле MDReqID не прочитано");
                }
                // инструмент указан в самом запросе
                var requestedSymbol = msg.GetValueString(FixMessage.TAG_SYMBOL);
                //requestedSymbol = TickerCodeDictionary.Instance.GetClearTickerName(requestedSymbol);
                // котировка будет исправлена в дальнейшем

                var groupHeader = new NoMDEntries();
                msgOrig.getField(groupHeader);
                var numGroups = groupHeader.getValue();

                if (numGroups == 0)
                {
                    throw new Exception("Поле NoMDEntries не прочитано");
                }

                var group = FixMessage.FixVersion == FixVersion.Fix42
                                ? new QuickFix42.MarketDataIncrementalRefresh.NoMDEntries()
                                : FixMessage.FixVersion == FixVersion.Fix43
                                      ? (Group) new QuickFix43.MarketDataIncrementalRefresh.NoMDEntries()
                                      : new QuickFix44.MarketDataIncrementalRefresh.NoMDEntries();

                float bid = 0, ask = 0;
                for (var i = 1; i <= numGroups; i++)
                {
                    var groupTicker = msgOrig.getGroup((uint)i, group);
                    // тип (бид или аск)
                    var isBid     = true;
                    var typeField = groupTicker.getField(new MDEntryType());
                    if (typeField == null)
                    {
                        throw new Exception("Поле MDEntryType не прочитано");
                    }
                    isBid = typeField.getValue() == '0';
                    // цена
                    var priceField = group.getField(new MDEntryPx());
                    if (priceField == null)
                    {
                        throw new Exception("Поле MDEntryPx не прочитано");
                    }
                    var price = priceField.getValue();
                    if (isBid)
                    {
                        bid = (float)price;
                    }
                    else
                    {
                        ask = (float)price;
                    }
                }
                // цены прочитаны?
                if (bid == 0 || ask == 0)
                {
                    loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                             LogMagicLackPrice,
                                                             1000 * 60 * 10, "MarketDataFullRefresh - нет цены (" +
                                                             bid.ToStringUniformPriceFormat() + ", " + ask.ToStringUniformPriceFormat() + ")");
                    return;
                }

                // обновить котировку
                QuoteDistributor.Instance.UpdateQuote(requestedSymbol, bid, ask);

                loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                         LogMagicParseMarketDataSuccess,
                                                         1000 * 60 * 10,
                                                         "Обработан пакет MarketDataFullRefresh - {0}: {1}/{2}",
                                                         requestedSymbol, bid, ask);
            }
            catch (Exception ex)
            {
                loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                         LogMagicParseMarketDataError,
                                                         1000 * 60 * 10, "Ошибка разбора MarketDataFullRefresh: {0}", ex);
            }
        }
        /// <summary>
        /// сообщение содержит котировку: одну цену либо бид и аск сразу
        /// </summary>        
        public static void ProcessMsgQuote(FixMessage msg)
        {
            loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                LogMagicMarketData, 1000 * 60 * 60 * 2, "Quote: {0}", msg.ToString());

            string symbol = msg.GetValueString(FixMessage.TAG_SYMBOL);
            if (string.IsNullOrEmpty(symbol))
            {
                Logger.Debug("Quote msg: no symbol tag");
                return;
            }

            if (!ConvertFromProviderSymbolNaming(ref symbol)) return;

            var bid = msg.GetValueFloat(FixMessage.TAG_BID_PRICE);
            var ask = msg.GetValueFloat(FixMessage.TAG_OFFER_PRICE);
            if (!bid.HasValue && ask.HasValue == false)
            {
                Logger.Debug("Quote msg: no bid - ask");
                return;
            }
            QuoteDistributor.Instance.UpdateQuote(symbol, bid, ask);
        }