Пример #1
0
        public static void ReadSecurityId(this IBSocket socket, SecurityId securityId)
        {
            var count = socket.ReadInt();

            for (var i = 0; i < count; i++)
            {
                var idType = socket.ReadStr();
                switch (idType)
                {
                case "CUSIP":
                    securityId.Cusip = socket.ReadStr();
                    break;

                case "ISIN":
                    securityId.Isin = socket.ReadStr();
                    break;

                case "SEDOL":
                    securityId.Sedol = socket.ReadStr();
                    break;

                case "RIC":
                    securityId.Ric = socket.ReadStr();
                    break;

                default:
                    throw new InvalidOperationException(LocalizedStrings.Str2509Params.Put(idType));
                }
            }
        }
		private void ReadPortfolioPosition(IBSocket socket, ServerVersions version)
		{
			var contractId = version >= ServerVersions.V6 ? socket.ReadInt() : -1;

			var secName = socket.ReadStr();
			var type = socket.ReadSecurityType();
			var expiryDate = socket.ReadExpiry();
			var strike = socket.ReadDecimal();
			var optionType = socket.ReadOptionType();
			var multiplier = version >= ServerVersions.V7 ? socket.ReadMultiplier() : null;
			var boardCode = version >= ServerVersions.V7 ? socket.ReadBoardCode() : null;
			var currency = socket.ReadCurrency();

			var secCode = (version >= ServerVersions.V2) ? socket.ReadStr() : secName;

			var secClass = (version >= ServerVersions.V8) ? socket.ReadStr() : null;

			var position = socket.ReadDecimal();
			var marketPrice = socket.ReadDecimal();
			var marketValue = socket.ReadDecimal();

			var averagePrice = 0m;
			var unrealizedPnL = 0m;
			var realizedPnL = 0m;
			if (version >= ServerVersions.V3)
			{
				averagePrice = socket.ReadDecimal();
				unrealizedPnL = socket.ReadDecimal();
				realizedPnL = socket.ReadDecimal();
			}

			var portfolio = version >= ServerVersions.V4 ? socket.ReadStr() : null;

			if (version == ServerVersions.V6 && socket.ServerVersion == ServerVersions.V39)
				boardCode = socket.ReadBoardCode();

			var secId = new SecurityId
			{
				SecurityCode = secCode,
				BoardCode = GetBoardCode(boardCode),
				InteractiveBrokers = contractId,
			};

			SendOutMessage(new SecurityMessage
			{
				SecurityId = secId,
				Name = secName,
				SecurityType = type,
				ExpiryDate = expiryDate,
				Strike = strike,
				OptionType = optionType,
				Currency = currency,
				Multiplier = multiplier ?? 0,
				Class = secClass
			});

			if (portfolio.IsEmpty())
				return;

			SendOutMessage(
				this
					.CreatePositionChangeMessage(portfolio, secId)
						.Add(PositionChangeTypes.CurrentValue, position)
						.Add(PositionChangeTypes.CurrentPrice, marketPrice)
						.Add(PositionChangeTypes.AveragePrice, averagePrice)
						.Add(PositionChangeTypes.UnrealizedPnL, unrealizedPnL)
						.Add(PositionChangeTypes.RealizedPnL, realizedPnL));

			// TODO
			//pos.SetMarketValue(marketValue);
		}
		private void ReadAccountSummaryEnd(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			SendOutMessage(new PortfolioLookupResultMessage { OriginalTransactionId = requestId });
		}
		private void ReadPosition(IBSocket socket, ServerVersions version)
		{
			var account = socket.ReadStr();

			var contractId = socket.ReadInt();
			var secName = socket.ReadStr();
			var type = socket.ReadSecurityType();
			var expiryDate = socket.ReadExpiry();
			var strike = socket.ReadDecimal();
			var optionType = socket.ReadOptionType();
			var multiplier = socket.ReadMultiplier();
			var boardCode = socket.ReadBoardCode();
			var currency = socket.ReadCurrency();
			var secCode = socket.ReadLocalCode(secName);
			var secClass = (version >= ServerVersions.V2) ? socket.ReadStr() : null;

			var pos = socket.ReadDecimal();

			var avgCost = 0m;
			if (version >= ServerVersions.V3)
				avgCost = socket.ReadDecimal();

			var secId = new SecurityId
			{
				SecurityCode = secCode,
				BoardCode = GetBoardCode(boardCode),
				InteractiveBrokers = contractId,
			};

			SendOutMessage(new SecurityMessage
			{
				SecurityId = secId,
				Name = secName,
				SecurityType = type,
				ExpiryDate = expiryDate,
				Strike = strike,
				OptionType = optionType,
				Currency = currency,
				Multiplier = multiplier ?? 0,
				Class = secClass
			});

			SendOutMessage(this
				.CreatePositionChangeMessage(account, secId)
					.Add(PositionChangeTypes.CurrentValue, pos)
					.Add(PositionChangeTypes.AveragePrice, avgCost));
		}
		private void ReadMyTrade(IBSocket socket, ServerVersions version)
		{
			/* requestId */
			if (version >= ServerVersions.V7)
				socket.ReadInt();

			// http://www.interactivebrokers.com/en/software/api/apiguide/java/execution.htm

			var transactionId = socket.ReadInt();

			//Handle the 2^31-1 == 0 bug
			if (transactionId == int.MaxValue)
				transactionId = 0;

			//Read Contract Fields
			var contractId = version >= ServerVersions.V5 ? socket.ReadInt() : -1;

			var secName = socket.ReadStr();
			var type = socket.ReadSecurityType();
			var expiryDate = socket.ReadExpiry();
			var strike = socket.ReadDecimal();
			var optionType = socket.ReadOptionType();
			var multiplier = version >= ServerVersions.V9 ? socket.ReadMultiplier() : null;
			var boardCode = socket.ReadBoardCode();
			var currency = socket.ReadCurrency();
			var secCode = socket.ReadLocalCode(secName);
			var secClass = (version >= ServerVersions.V10) ? socket.ReadStr() : null;

			var tradeId = socket.ReadStr();
			var time = socket.ReadDateTime("yyyyMMdd  HH:mm:ss");
			var portfolio = socket.ReadStr();
			/* exchange */
			socket.ReadStr();
			var side = socket.ReadTradeSide();
			var volume = socket.ReadDecimal();
			var price = socket.ReadDecimal();
			var permId = version >= ServerVersions.V2 ? socket.ReadInt() : (int?)null;
			var clientId = version >= ServerVersions.V3 ? socket.ReadInt() : (int?)null;
			var liquidation = version >= ServerVersions.V4 ? socket.ReadInt() : (int?)null;
			var cumulativeQuantity = version >= ServerVersions.V6 ? socket.ReadInt() : (int?)null;
			var averagePrice = version >= ServerVersions.V6 ? socket.ReadDecimal() : (decimal?)null;
			var orderRef = version >= ServerVersions.V8 ? socket.ReadStr() : null;
			var evRule = version >= ServerVersions.V9 ? socket.ReadStr() : null;
			var evMultiplier = version >= ServerVersions.V9 ? socket.ReadDecimal() : (decimal?)null;

			var secId = new SecurityId
			{
				SecurityCode = secCode,
				BoardCode = GetBoardCode(boardCode),
				InteractiveBrokers = contractId,
			};

			SendOutMessage(new SecurityMessage
			{
				SecurityId = secId,
				Name = secName,
				SecurityType = type,
				ExpiryDate = expiryDate,
				Strike = strike,
				OptionType = optionType,
				Currency = currency,
				Multiplier = multiplier ?? 0,
				Class = secClass
			});

			// заявка была создана руками
			if (transactionId == 0)
				return;

			_secIdByTradeIds[tradeId] = secId;

			var execMsg = new ExecutionMessage
			{
				ExecutionType = ExecutionTypes.Transaction,
				OriginalTransactionId = transactionId,
				TradeStringId = tradeId,
				OriginSide = side,
				TradePrice = price,
				TradeVolume = volume,
				PortfolioName = portfolio,
				ServerTime = time,
				SecurityId = secId,
				HasTradeInfo = true,
			};

			if (permId != null)
				execMsg.SetPermId(permId.Value);

			if (clientId != null)
				execMsg.SetClientId(clientId.Value);

			if (liquidation != null)
				execMsg.SetLiquidation(liquidation.Value);

			if (cumulativeQuantity != null)
				execMsg.SetCumulativeQuantity(cumulativeQuantity.Value);

			if (averagePrice != null)
				execMsg.SetAveragePrice(averagePrice.Value);

			if (orderRef != null)
				execMsg.SetOrderRef(orderRef);

			if (evRule != null)
				execMsg.SetEvRule(evRule);

			if (evMultiplier != null)
				execMsg.SetEvMultiplier(evMultiplier.Value);

			SendOutMessage(execMsg);
		}
		private void ReadTickGeneric(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			var field = (FieldTypes)socket.ReadInt();
			var valueRenamed = socket.ReadDecimal();

			ProcessTick(requestId, field, valueRenamed, null);

			//tickGeneric(tickerId, (FieldTypes) tickType, valueRenamed);
		}
		private void ReadTickVolume(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			var volumeType = (FieldTypes)socket.ReadInt();
			var volume = socket.ReadInt();

			ProcessTick(requestId, volumeType, 0, volume);
		}
		private void ReadFinancialAdvice(IBSocket socket)
		{
			var type = socket.ReadInt();
			var xml = socket.ReadStr();

			SendOutMessage(new FinancialAdviseMessage
			{
				AdviseType = type,
				Data = xml
			});
		}
		private void ReadBondInfo(IBSocket socket, ServerVersions version)
		{
			var requestId = version >= ServerVersions.V3 ? socket.ReadInt() : -1;

			var secCode = socket.ReadStr();
			var type = socket.ReadSecurityType();
			var cusip = socket.ReadStr();
			var coupon = socket.ReadDecimal();
			var maturity = socket.ReadStr();
			var issueDate = socket.ReadStr();
			var ratings = socket.ReadStr();
			var bondType = socket.ReadStr();
			var couponType = socket.ReadStr();
			var convertible = socket.ReadBool();
			var callable = socket.ReadBool();
			var putable = socket.ReadBool();
			var description = socket.ReadStr();
			var boardCode = socket.ReadBoardCode();
			var currency = socket.ReadCurrency();
			var marketName = socket.ReadStr();
			var secClass = socket.ReadStr();
			var contractId = socket.ReadInt();
			var priceStep = socket.ReadDecimal();
			var orderTypes = socket.ReadStr();
			var validExchanges = socket.ReadStr();

			var nextOptionDate = version >= ServerVersions.V2 ? socket.ReadStr() : null;
			var nextOptionType = version >= ServerVersions.V2 ? socket.ReadStr() : null;
			var nextOptionPartial = version >= ServerVersions.V2 ? socket.ReadBool() : (bool?)null;
			var notes = version >= ServerVersions.V2 ? socket.ReadStr() : null;

			var name = version >= ServerVersions.V4 ? socket.ReadStr() : null;
			var evRule = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var evMultiplier = version >= ServerVersions.V6 ? socket.ReadDecimal() : (decimal?)null;
			
			var secId = new SecurityId
			{
				SecurityCode = secCode,
				BoardCode = GetBoardCode(boardCode),
				InteractiveBrokers = contractId,
			};

			if (version >= ServerVersions.V5)
				socket.ReadSecurityId(secId);

			var secMsg = new SecurityMessage
			{
				SecurityId = secId,
				//Name = secName,
				SecurityType = type,
				Currency = currency,
				Class = secClass,
				PriceStep = priceStep,
			};

			secMsg.SetMarketName(marketName);
			secMsg.SetOrderTypes(orderTypes);
			secMsg.SetValidExchanges(validExchanges);

			// TODO
			//s.SetBondCusip(cusip);
			//s.SetCoupon(coupon);
			//s.SetMaturity(maturity);
			//s.SetIssueDate(issueDate);
			//s.SetRatings(ratings);
			//s.SetBondType(bondType);
			//s.SetCouponType(couponType);
			//s.SetConvertible(convertible);
			//s.SetCallable(callable);
			//s.SetPutable(putable);
			//s.SetDescription(description);

			//if (nextOptionDate != null)
			//	s.SetNextOptionDate(nextOptionDate);

			//if (nextOptionType != null)
			//	s.SetNextOptionType(nextOptionType);

			//if (nextOptionPartial != null)
			//	s.SetNextOptionPartial(nextOptionPartial.Value);

			//if (notes != null)
			//	s.SetNotes(notes);

			if (evRule != null)
				secMsg.SetEvRule(evRule);

			if (evMultiplier != null)
				secMsg.SetEvMultiplier(evMultiplier.Value);

			SendOutMessage(secMsg);
		}
		private void ReadSecurityInfo(IBSocket socket, ServerVersions version)
		{
			var requestId = version >= ServerVersions.V3 ? socket.ReadInt() : -1;

			var secName = socket.ReadStr();
			var type = socket.ReadSecurityType();
			var expiryDate = socket.ReadExpiry();
			var strike = socket.ReadDecimal();
			var optionType = socket.ReadOptionType();
			var boardCode = socket.ReadBoardCode();
			var currency = socket.ReadCurrency();
			var secCode = version >= ServerVersions.V2 ? socket.ReadLocalCode(secName) : null;
			var marketName = socket.ReadStr();
			var secClass = socket.ReadStr();
			var contractId = socket.ReadInt();
			var priceStep = socket.ReadDecimal();
			var multiplier = socket.ReadMultiplier();
			var orderTypes = socket.ReadStr();
			var validExchanges = socket.ReadStr();
			var priceMagnifier = version >= ServerVersions.V2 ? socket.ReadInt() : (int?)null;
			var underlyingSecurityNativeId = version >= ServerVersions.V4 ? socket.ReadInt() : (int?)null;
			var name = version >= ServerVersions.V4 ? socket.ReadStr() : null;
			var routingExchange = version >= ServerVersions.V4 ? socket.ReadBoardCode() : null;
			var contractMonth = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var industry = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var category = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var subCategory = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var timeZoneId = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var tradingHours = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var liquidHours = version >= ServerVersions.V6 ? socket.ReadStr() : null;
			var evRule = version >= ServerVersions.V8 ? socket.ReadStr() : null;
			var evMultiplier = version >= ServerVersions.V8 ? socket.ReadDecimal() : (decimal?)null;

			var secId = new SecurityId
			{
				SecurityCode = secCode,
				BoardCode = GetBoardCode(boardCode),
				InteractiveBrokers = contractId,
			};

			if (version >= ServerVersions.V7)
				socket.ReadSecurityId(secId);

			var secMsg = new SecurityMessage
			{
				SecurityId = secId,
				Name = secName,
				SecurityType = type,
				ExpiryDate = expiryDate,
				Strike = strike,
				OptionType = optionType,
				Currency = currency,
				Multiplier = multiplier ?? 0,
				Class = secClass,
				OriginalTransactionId = requestId,
				PriceStep = priceStep,
			};

			secMsg.SetMarketName(marketName);
			secMsg.SetOrderTypes(orderTypes);
			secMsg.SetValidExchanges(validExchanges);

			if (priceMagnifier != null)
				secMsg.SetPriceMagnifier(priceMagnifier.Value);

			if (!routingExchange.IsEmpty())
				secMsg.SetRoutingBoard(routingExchange);

			if (contractMonth != null)
				secMsg.SetContractMonth(contractMonth);

			if (industry != null)
				secMsg.SetIndustry(industry);

			if (category != null)
				secMsg.SetCategory(category);

			if (subCategory != null)
				secMsg.SetSubCategory(subCategory);

			if (timeZoneId != null)
				secMsg.SetTimeZoneId(timeZoneId);

			if (tradingHours != null)
				secMsg.SetTradingHours(tradingHours);

			if (liquidHours != null)
				secMsg.SetLiquidHours(liquidHours);

			if (evRule != null)
				secMsg.SetEvRule(evRule);

			if (evMultiplier != null)
				secMsg.SetEvMultiplier(evMultiplier.Value);

			// TODO
			//if (underlyingSecurityNativeId != null)
			//	ProcessSecurityAction(null, SecurityIdGenerator.GenerateId(underlyingSecurityNativeId.Value.To<string>(), exchangeBoard), underSec => security.UnderlyingSecurityId = underSec.Id);

			SendOutMessage(secMsg);
		}
		private void ReadScannerData(IBSocket socket, ServerVersions version)
		{
			var requestId = socket.ReadInt();
			var count = socket.ReadInt();

			var tmp = Enumerable
				.Range(0, count)
				.Select(s =>
				{
					var rank = socket.ReadInt();
					var contractId = version >= ServerVersions.V3 ? socket.ReadInt() : -1;

					var secName = socket.ReadStr();
					var type = socket.ReadSecurityType();
					var expiryDate = socket.ReadExpiry();
					var strike = socket.ReadDecimal();
					var optionType = socket.ReadOptionType();
					var boardCode = socket.ReadBoardCode();
					var currency = socket.ReadCurrency();
					var secCode = socket.ReadLocalCode(secName);
					var marketName = socket.ReadStr();
					var secClass = socket.ReadStr();

					var distance = socket.ReadStr();
					var benchmark = socket.ReadStr();
					var projection = socket.ReadStr();
					var legs = version >= ServerVersions.V2 ? socket.ReadStr() : null;

					return new
					{
						Rank = rank,
						ContractId = contractId,
						SecName = secName,
						SecCode = secCode,
						Type = type,
						ExpiryDate = expiryDate,
						Strike = strike,
						OptionType = optionType,
						BoardCode = boardCode,
						Currency = currency,
						MarketName = marketName,
						SecClass = secClass,
						Distance = distance,
						Benchmark = benchmark,
						Projection = projection,
						Legs = legs,
					};
				})
				.ToArray();

			var results = tmp.Select(t =>
			{
				var secId = new SecurityId
				{
					SecurityCode = t.SecCode,
					BoardCode = GetBoardCode(t.BoardCode),
					InteractiveBrokers = t.ContractId,
				};

				SendOutMessage(new SecurityMessage
				{
					SecurityId = secId,
					Name = t.SecName,
					SecurityType = t.Type,
					ExpiryDate = t.ExpiryDate,
					Strike = t.Strike,
					OptionType = t.OptionType,
					Currency = t.Currency,
					Class = t.SecClass
				});

				var result = new ScannerResult
				{
					Rank = t.Rank,
					SecurityId = secId,
					Distance = t.Distance,
					Benchmark = t.Benchmark,
					Projection = t.Projection,
					Legs = t.Legs
				};

				return result;
			}).ToArray();

			SendOutMessage(new ScannerResultMessage
			{
				Results = results,
				OriginalTransactionId = requestId,
			});
		}
		private void ReadTickEfp(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			var fieldType = (FieldTypes)socket.ReadInt();
			var basisPoints = socket.ReadDecimal();
			var formattedBasisPoints = socket.ReadStr();
			var impliedFuturesPrice = socket.ReadDecimal();
			var holdDays = socket.ReadInt();
			var futureExpiry = socket.ReadStr();
			var dividendImpact = socket.ReadDecimal();
			var dividendsToExpiry = socket.ReadDecimal();
			//tickEfp(requestId, fieldType, basisPoints, formattedBasisPoints, impliedFuturesPrice,
			//        holdDays, futureExpiry, dividendImpact, dividendsToExpiry);

			var l1Msg = GetLevel1Message(requestId)
				.TryAdd(Level1Fields.StepPrice, basisPoints)
				.TryAdd(Level1Fields.Yield, dividendsToExpiry);

			SendOutMessage(l1Msg);
		}
		private void ReadTickString(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			var field = (FieldTypes)socket.ReadInt();
			var valueRenamed = socket.ReadStr();

			//GetLevel1Message(requestId);
			//tickString(requestId, fieldType, valueRenamed);
		}
		private bool OnProcessResponse(IBSocket socket)
		{
			var str = socket.ReadStr(false);

			if (str.IsEmpty())
			{
				socket.AddErrorLog(LocalizedStrings.Str2524);
				return false;
			}

			var message = (ResponseMessages)str.To<int>();

			socket.AddDebugLog("Msg: {0}", message);

			if (message == ResponseMessages.Error)
				return false;

			var version = (ServerVersions)socket.ReadInt();

			switch (message)
			{
				case ResponseMessages.CurrentTime:
				{
					// http://www.interactivebrokers.com/en/software/api/apiguide/java/currenttime.htm

					var time = socket.ReadLongDateTime();
					OnProcessTimeShift(TimeHelper.NowWithOffset - time);

					break;
				}
				case ResponseMessages.ErrorMessage:
				{
					if (version < ServerVersions.V2)
					{
						OnProcessMarketDataError(socket.ReadStr());
					}
					else
					{
						var id = socket.ReadInt();
						var code = socket.ReadInt();
						var msg = socket.ReadStr();

						socket.AddInfoLog(() => msg);

						if (id == -1)
							break;

						switch ((NotifyCodes)code)
						{
							case NotifyCodes.OrderCancelled:
							{
								OnProcessOrderCancelled(id);
								break;
							}
							case NotifyCodes.OrderCannotTransmit:
							case NotifyCodes.OrderCannotTransmitId:
							case NotifyCodes.OrderCannotTransmitIncomplete:
							case NotifyCodes.OrderDuplicateId:
							case NotifyCodes.OrderFilled:
							case NotifyCodes.OrderNotMatchPrev:
							case NotifyCodes.OrderPriceOutOfRange:
							case NotifyCodes.OrderSubmitFailed:
							case NotifyCodes.OrderVolumeTooSmall:
							case NotifyCodes.Rejected:
							{
								OnProcessOrderError(id, msg);
								break;
							}
							case NotifyCodes.SecurityNoDefinition:
								OnProcessSecurityLookupNoFound(id);
								break;
							default:
								OnProcessMarketDataError(LocalizedStrings.Str2525Params.Put(msg, id, code));
								break;
						}
					}

					break;
				}
				case ResponseMessages.VerifyMessageApi:
				{
					/*int version =*/
					socket.ReadInt();
					/*var apiData = */
					socket.ReadStr();

					//eWrapper().verifyMessageAPI(apiData);
					break;
				}
				case ResponseMessages.VerifyCompleted:
				{
					/*int version =*/
					socket.ReadInt();
					var isSuccessfulStr = socket.ReadStr();
					var isSuccessful = "true".CompareIgnoreCase(isSuccessfulStr);
					/*var errorText = */
					socket.ReadStr();

					if (isSuccessful)
					{
						throw new NotSupportedException();
						//m_parent.startAPI();
					}

					//eWrapper().verifyCompleted(isSuccessful, errorText);
					break;
				}
				case ResponseMessages.DisplayGroupList:
				{
					/*int version =*/
					socket.ReadInt();
					/*var reqId = */
					socket.ReadInt();
					/*var groups = */
					socket.ReadStr();

					//eWrapper().displayGroupList(reqId, groups);
					break;
				}
				case ResponseMessages.DisplayGroupUpdated:
				{
					/*int version =*/
					socket.ReadInt();
					/*var reqId = */
					socket.ReadInt();
					/*var contractInfo = */
					socket.ReadStr();

					//eWrapper().displayGroupUpdated(reqId, contractInfo);
					break;
				}
				default:
				{
					if (!message.IsDefined())
						return false;

					var handled = ProcessTransactionResponse(socket, message, version);

					if (!handled)
						handled = ProcessMarketDataResponse(socket, message, version);

					if (!handled)
						throw new InvalidOperationException(LocalizedStrings.Str1622Params.Put(message));

					break;
				}
			}

			return true;
		}
		/// <summary>
		/// Send message.
		/// </summary>
		/// <param name="message">Message.</param>
		protected override void OnSendInMessage(Message message)
		{
			switch (message.Type)
			{
				case MessageTypes.Reset:
				{
					_depths.Clear();
					_secIdByTradeIds.Clear();

					if (_socket != null)
					{
						try
						{
							_socket.Dispose();
						}
						catch (Exception ex)
						{
							SendOutError(ex);
						}

						_socket = null;
					}

					SendOutMessage(new ResetMessage());

					break;
				}

				case MessageTypes.Connect:
				{
					if (_socket != null)
						throw new InvalidOperationException(LocalizedStrings.Str1619);

					_socket = new IBSocket { Parent = this };
					_socket.ProcessResponse += OnProcessResponse;
					_socket.Connect(Address);

					_socket.Send((int)_clientVersion);

					_socket.ServerVersion = (ServerVersions)_socket.ReadInt();

					if (_socket.ServerVersion >= ServerVersions.V20)
					{
						var str = _socket.ReadStr();
						ConnectedTime = str.Substring(0, str.LastIndexOf(' ')).ToDateTime("yyyyMMdd HH:mm:ss");
					}

					if (_socket.ServerVersion < _minimumServerVersion)
					{
						throw new InvalidOperationException(LocalizedStrings.Str2513Params
							.Put((int)_socket.ServerVersion, (int)_minimumServerVersion));
					}

					if (_socket.ServerVersion >= ServerVersions.V3)
					{
						if (_socket.ServerVersion >= ServerVersions.V70)
						{
							if (!ExtraAuth)
							{
								_socket.Send((int)RequestMessages.StartApi);
								_socket.Send((int)ServerVersions.V2);
								_socket.Send(ClientId);

								if (_socket.ServerVersion >= ServerVersions.V72)
								{
									_socket.Send(OptionalCapabilities);
								}
							}
						}
						else
							_socket.Send(ClientId);
					}

					_socket.StartListening(error => SendOutMessage(new ConnectMessage { Error = error }));
					
					SendOutMessage(new ConnectMessage());

					// отправляется автоматически 
					//RequestIds(1);

					SetServerLogLevel();
					SetMarketDataType();

					RequestCurrentTime();

					break;
				}

				case MessageTypes.Disconnect:
				{
					if (_socket == null)
						throw new InvalidOperationException(LocalizedStrings.Str1856);

					UnSubscribePosition();
					UnSubscribeAccountSummary(_pfRequests.GetAndRemove("ALL"));

					_socket.Dispose();
					_socket = null;

					SendOutMessage(new DisconnectMessage());

					break;
				}

				case MessageTypes.OrderRegister:
				{
					RegisterOrder((OrderRegisterMessage)message);
					break;
				}

				case MessageTypes.OrderCancel:
				{
					var cancelMsg = (OrderCancelMessage)message;
					ProcessRequest(RequestMessages.CancelOrder, 0, ServerVersions.V1, socket => socket.Send((int)cancelMsg.OrderTransactionId));
					break;
				}

				case MessageTypes.OrderGroupCancel:
				{
					RequestGlobalCancel();
					break;
				}

				case MessageTypes.SecurityLookup:
				{
					RequestSecurityInfo((SecurityLookupMessage)message);
					break;
				}

				case MessageTypes.MarketData:
				{
					ProcessMarketDataMessage((MarketDataMessage)message);
					break;
				}

				case MessageTypes.PortfolioLookup:
				{
					var pfMsg = (PortfolioLookupMessage)message;

					// отправляется автоматически
					//RequestPortfolios();

					SubscribePosition();

					_pfRequests.Add("ALL", pfMsg.TransactionId);
					SubscribeAccountSummary(pfMsg.TransactionId, "ALL", Enumerator.GetValues<AccountSummaryTag>());

					break;
				}

				case MessageTypes.Portfolio:
				{
					var pfMsg = (PortfolioMessage)message;
					SubscribePortfolio(pfMsg.PortfolioName, pfMsg.IsSubscribe);
					break;
				}

				case MessageTypes.OrderStatus:
				{
					var orderMsg = (OrderStatusMessage)message;

					RequestOpenOrders();
					RequestAllOpenOrders();
					//RequestAutoOpenOrders(ClientId == 0);
					ReqeustMyTrades(orderMsg.TransactionId, new MyTradeFilter());

					break;
				}
			}
		}
		private void ReadMarketDataType(IBSocket socket)
		{
			/* requestId */
			socket.ReadInt();

			IsRealTimeMarketData = socket.ReadBool();

			//marketDataType(reqId, mdt);
		}
		private void ReadMarketDepth(IBSocket socket, ResponseMessages message)
		{
			var requestId = socket.ReadInt();

			var secId = GetSecurityId(requestId);

			/* position */
			var pos = socket.ReadInt();

			if (message == ResponseMessages.MarketDepthL2)
			{
				/* marketMaker */
				secId.BoardCode = socket.ReadBoardCode();
			}

			var operation = socket.ReadInt();

			var side = socket.ReadBool() ? Sides.Buy : Sides.Sell;
			var price = socket.ReadDecimal();
			var volume = socket.ReadInt();

			var prevQuotes = _depths.SafeAdd(secId, key =>
				Tuple.Create(new SortedDictionary<decimal, decimal>(new BackwardComparer<decimal>()), new SortedDictionary<decimal, decimal>()));

			var quotes = side == Sides.Buy ? prevQuotes.Item1 : prevQuotes.Item2;

			this.AddDebugLog("MD {0} {1} POS {2} PRICE {3} VOL {4}", secId, operation, pos, price, volume);

			switch (operation)
			{
				case 0: // insert
				{
					if (!CollectionHelper.TryAdd(quotes, price, volume))
						quotes[price] += volume;

					break;
				}
				case 1: // update
				{
					if (quotes.Count > (pos + 1))
					{
						var sign = side == Sides.Buy ? 1 : -1;

						if (quotes[pos + 1] * sign >= price * sign)
						{
							for (var i = quotes.Count - 1; i >= pos + 1; i--)
								quotes.Remove(quotes[quotes.Keys.ElementAt(i)]);
						}
					}

					if (quotes.Count > pos)
					{
						//if (quotes[quotes.Keys.ElementAt(pos)] == price)
						//	quotes[price] = volume;
						//else
						//{
						//	depth.Remove(quotes[pos]);
						//	depth.AddQuote(quote);
						//}

						quotes[price] = volume;
					}
					else
					{
						if (!CollectionHelper.TryAdd(quotes, price, volume))
							quotes[price] += volume;
					}

					break;
				}
				case 2: // delete
				{
					if (quotes.Count > pos)
						quotes.Remove(quotes.Keys.ElementAt(pos));

					break;
				}
			}

			SendOutMessage(new QuoteChangeMessage
			{
				SecurityId = secId,
				Bids = prevQuotes.Item1.Select(p => new QuoteChange(Sides.Buy, p.Key, p.Value)).ToArray(),
				Asks = prevQuotes.Item2.Select(p => new QuoteChange(Sides.Sell, p.Key, p.Value)).ToArray(),
				ServerTime = this.CurrentTime.Convert(TimeZoneInfo.Utc),
			});
		}
		private void ReadTickPrice(IBSocket socket, ServerVersions version)
		{
			var requestId = socket.ReadInt();
			var priceField = (FieldTypes)socket.ReadInt();
			var price = socket.ReadDecimal();
			var volume = version >= ServerVersions.V2 ? socket.ReadInt() : (decimal?)null;
			var canAutoExecute = version >= ServerVersions.V3 ? socket.ReadBool() : (bool?)null;

			ProcessTick(requestId, priceField, price, volume);
		}
		private void ReadNewsBulletins(IBSocket socket)
		{
			var newsId = socket.ReadInt();
			var newsType = (ExchangeNewsTypes)socket.ReadInt();
			var newsMessage = socket.ReadStr();
			var originatingExch = socket.ReadBoardCode();

			SendOutMessage(new NewsMessage
			{
				Id = newsId.To<string>(),
				BoardCode = originatingExch,
				Headline = newsMessage,
				ExtensionInfo = new Dictionary<object, object> { { "Type", newsType } },
				ServerTime = this.CurrentTime.Convert(TimeHelper.Est)
			});
		}
		private void ReadTickOptionComputation(IBSocket socket, ServerVersions version)
		{
			var requestId = socket.ReadInt();
			var fieldType = (FieldTypes)socket.ReadInt();

			decimal? impliedVol = socket.ReadDecimal();
			if (impliedVol < 0)
			{
				// -1 is the "not yet computed" indicator
				impliedVol = null;
			}

			decimal? delta = socket.ReadDecimal();
			if (Math.Abs(delta.Value) > 1)
			{
				// -2 is the "not yet computed" indicator
				delta = null;
			}

			decimal? optPrice = null;
			decimal? pvDividend = null;
			decimal? gamma = null;
			decimal? vega = null;
			decimal? theta = null;
			decimal? undPrice;

			if (version >= ServerVersions.V6 || fieldType == FieldTypes.ModelOption)
			{
				// introduced in version == 5
				optPrice = socket.ReadDecimal();
				if (optPrice < 0)
				{
					// -1 is the "not yet computed" indicator
					optPrice = null;
				}

				pvDividend = socket.ReadDecimal();
				if (pvDividend < 0)
				{
					// -1 is the "not yet computed" indicator
					pvDividend = null;
				}
			}

			if (version >= ServerVersions.V6)
			{
				gamma = socket.ReadDecimal();
				if (Math.Abs(gamma.Value) > 1)
				{
					// -2 is the "not yet computed" indicator
					gamma = null;
				}

				vega = socket.ReadDecimal();
				if (Math.Abs(vega.Value) > 1)
				{
					// -2 is the "not yet computed" indicator
					vega = null;
				}

				theta = socket.ReadDecimal();
				if (Math.Abs(theta.Value) > 1)
				{
					// -2 is the "not yet computed" indicator
					theta = null;
				}

				undPrice = socket.ReadDecimal();
				if (undPrice < 0)
				{
					// -1 is the "not yet computed" indicator
					undPrice = null;
				}
			}

			var l1Msg = GetLevel1Message(requestId)
				.TryAdd(Level1Fields.Delta, delta)
				.TryAdd(Level1Fields.Gamma, gamma)
				.TryAdd(Level1Fields.Vega, vega)
				.TryAdd(Level1Fields.Theta, theta)
				.TryAdd(Level1Fields.ImpliedVolatility, impliedVol)
				.TryAdd(Level1Fields.TheorPrice, optPrice)
				.TryAdd(Level1Fields.Yield, pvDividend);

			SendOutMessage(l1Msg);

			//tickOptionComputation(tickerId, tickType, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta,
			//                      undPrice);
		}
		private void ReadHistoricalData(IBSocket socket, ServerVersions version)
		{
			var requestId = socket.ReadInt();

			if (version >= ServerVersions.V2)
			{
				//Read Start Date String
				/*String startDateStr = */
				socket.ReadStr();
				/*String endDateStr   = */
				socket.ReadStr();
				//completedIndicator += ("-" + startDateStr + "-" + endDateStr);
			}

			var secId = GetSecurityId(requestId);

			var itemCount = socket.ReadInt();
			for (var i = 0; i < itemCount; i++)
			{
				//Comes in as seconds
				//2 - dates are returned as a long integer specifying the number of seconds since 1/1/1970 GMT.
				var time = socket.ReadLongDateTime();

				var open = socket.ReadDecimal();
				var high = socket.ReadDecimal();
				var low = socket.ReadDecimal();
				var close = socket.ReadDecimal();
				var volume = socket.ReadInt();
				var wap = socket.ReadDecimal();
				/* hasGaps */
				socket.ReadStr().To<bool>();

				var barCount = -1;

				if (version >= ServerVersions.V3)
					barCount = socket.ReadInt();

				SendOutMessage(new TimeFrameCandleMessage
				{
					OpenPrice = open,
					HighPrice = high,
					LowPrice = low,
					ClosePrice = close,
					TotalVolume = volume,
					OpenTime = time,
					TotalTicks = barCount,
					SecurityId = secId,
					OriginalTransactionId = requestId,
					State = CandleStates.Finished,
					IsFinished = i == (itemCount - 1)
				});
			}
		}
		private void ReadNextOrderId(IBSocket socket)
		{
			((IncrementalIdGenerator)TransactionIdGenerator).Current = socket.ReadInt();
		}
		private void ReadRealTimeBars(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			var time = socket.ReadLongDateTime();
			var open = socket.ReadDecimal();
			var high = socket.ReadDecimal();
			var low = socket.ReadDecimal();
			var close = socket.ReadDecimal();
			var volume = socket.ReadLong();
			var wap = socket.ReadDecimal();
			var count = socket.ReadInt();

			SendOutMessage(new TimeFrameCandleMessage
			{
				OpenPrice = open,
				HighPrice = high,
				LowPrice = low,
				ClosePrice = close,
				TotalVolume = volume,
				OpenTime = time,
				CloseVolume = count,
				SecurityId = GetSecurityId(requestId),
				OriginalTransactionId = requestId,
			});

			//realTimeBar(reqId, time, open, high, low, close, volume, wap, count);
		}
		private void ReadMyTradeEnd(IBSocket socket)
		{
			/* requestId */
			socket.ReadInt();
			//executionDataEnd(reqId);
		}
		private void ReadFundamentalData(IBSocket socket)
		{
			var requestId = socket.ReadInt();
			var data = socket.ReadStr();

			SendOutMessage(new FundamentalReportMessage
			{
				Data = data,
				OriginalTransactionId = requestId,
			});
		}
		private void ReadAccountSummary(IBSocket socket)
		{
			/* requestId */
			socket.ReadInt();

			var account = socket.ReadStr();
			var tag = socket.ReadStr().To<AccountSummaryTag>();
			var value = socket.ReadStr();
			var currency = socket.ReadCurrency();

			var msg = this.CreatePortfolioChangeMessage(account);

			msg.Add(PositionChangeTypes.Currency, currency);

			switch (tag)
			{
				case AccountSummaryTag.TotalCashValue:
					msg.Add(PositionChangeTypes.CurrentValue, value.To<decimal>());
					break;
				case AccountSummaryTag.SettledCash:
					msg.Add(PositionChangeTypes.BlockedValue, value.To<decimal>());
					break;
				case AccountSummaryTag.AccruedCash:
					msg.Add(PositionChangeTypes.VariationMargin, value.To<decimal>());
					break;
				case AccountSummaryTag.InitMarginReq:
					msg.Add(PositionChangeTypes.BeginValue, value.To<decimal>());
					break;
				case AccountSummaryTag.Leverage:
					msg.Add(PositionChangeTypes.Leverage, value.To<decimal>());
					break;
			}

			SendOutMessage(msg);
		}
		private void ReadSecurityInfoEnd(IBSocket socket)
		{
			SendOutMessage(new SecurityLookupResultMessage { OriginalTransactionId = socket.ReadInt() });
		}
		private void ReadOrderStatus(IBSocket socket, ServerVersions version)
		{
			var id = socket.ReadInt();

			var status = socket.ReadOrderStatus();
			/* filled */
			socket.ReadInt();
			var balance = socket.ReadDecimal();
			var avgPrice = socket.ReadDecimal();
			var permId = version >= ServerVersions.V2 ? socket.ReadInt() : (int?)null;
			var parentId = version >= ServerVersions.V3 ? socket.ReadInt() : (int?)null;
			var lastTradePrice = version >= ServerVersions.V4 ? socket.ReadDecimal() : (decimal?)null;
			var clientId = version >= ServerVersions.V5 ? socket.ReadInt() : (int?)null;
			var whyHeld = version >= ServerVersions.V6 ? socket.ReadStr() : null;

			var execMsg = new ExecutionMessage
			{
				ExecutionType = ExecutionTypes.Transaction,
				OriginalTransactionId = id,
				Balance = balance,
				OrderStatus = status,
				OrderState = status.ToOrderState(),
				HasOrderInfo = true,
			};

			execMsg.SetAveragePrice(avgPrice);

			if (permId != null)
				execMsg.SetPermId(permId.Value);

			if (parentId != null)
				execMsg.Condition = new IBOrderCondition { ParentId = parentId.Value };

			if (lastTradePrice != null)
				execMsg.SetLastTradePrice(lastTradePrice.Value);

			if (clientId != null)
				execMsg.SetClientId(clientId.Value);

			if (whyHeld != null)
				execMsg.SetWhyHeld(whyHeld);

			SendOutMessage(execMsg);
		}
		private void ReadDeltaNuetralValidation(IBSocket socket)
		{
			/* requestId */
			socket.ReadInt();

			//UnderComp underComp = new UnderComp();
			//underComp.ConId = 
			socket.ReadInt();
			//underComp.Delta = 
			socket.ReadDecimal();
			//underComp.Price = 
			socket.ReadDecimal();

			//deltaNuetralValidation(reqId, underComp);
		}
		private void ReadOpenOrder(IBSocket socket, ServerVersions version)
		{
			var transactionId = socket.ReadInt();

			var contractId = version >= ServerVersions.V17 ? socket.ReadInt() : -1;

			var secCode = socket.ReadStr();
			var type = socket.ReadSecurityType();
			var expiryDate = socket.ReadExpiry();
			var strike = socket.ReadDecimal();
			var optionType = socket.ReadOptionType();
			var multiplier = version >= ServerVersions.V32 ? socket.ReadMultiplier() : null;
			var boardCode = socket.ReadBoardCode();
			var currency = socket.ReadCurrency();
			secCode = version >= ServerVersions.V2 ? socket.ReadLocalCode(secCode) : null;
			var secClass = (version >= ServerVersions.V32) ? socket.ReadStr() : null;

			var ibCon = new IBOrderCondition();

			// read order fields
			var direction = socket.ReadOrderSide();
			var volume = socket.ReadDecimal();

			OrderTypes orderType;
			IBOrderCondition.ExtendedOrderTypes? extendedType;
			socket.ReadOrderType(out orderType, out extendedType);
			ibCon.ExtendedType = extendedType;

			var price = socket.ReadDecimal();
			ibCon.StopPrice = socket.ReadDecimal();
			var expiration = socket.ReadStr();
			ibCon.Oca.Group = socket.ReadStr();
			var portfolio = socket.ReadStr();
			ibCon.IsOpenOrClose = socket.ReadStr() == "O";
			ibCon.Origin = (IBOrderCondition.OrderOrigins)socket.ReadInt();
			var comment = socket.ReadStr();

			var clientId = version >= ServerVersions.V3 ? socket.ReadInt() : (int?)null;
			int? permId = null;

			if (version >= ServerVersions.V4)
			{
				permId = socket.ReadInt();

				if (version < ServerVersions.V18)
				{
					// will never happen
					/* order.m_ignoreRth = */
					socket.ReadBool();
				}
				else
					ibCon.OutsideRth = socket.ReadBool();

				ibCon.Hidden = socket.ReadBool();
				ibCon.SmartRouting.DiscretionaryAmount = socket.ReadDecimal();
			}

			if (version >= ServerVersions.V5)
				ibCon.GoodAfterTime = socket.ReadNullDateTime(IBSocketHelper.TimeFormat);

			if (version >= ServerVersions.V6)
			{
				// skip deprecated sharesAllocation field
				socket.ReadStr();
			}

			if (version >= ServerVersions.V7)
			{
				ibCon.FinancialAdvisor.Group = socket.ReadStr();
				ibCon.FinancialAdvisor.Allocation = socket.ReadFinancialAdvisor();
				ibCon.FinancialAdvisor.Percentage = socket.ReadStr();
				ibCon.FinancialAdvisor.Profile = socket.ReadStr();
			}

			var orderExpiryDate = version >= ServerVersions.V8 ? socket.ReadNullDateTime(IBSocketHelper.TimeFormat) : null;
			var visibleVolume = volume;

			if (version >= ServerVersions.V9)
			{
				ibCon.Agent = socket.ReadAgent();
				ibCon.PercentOffset = socket.ReadDecimal();
				ibCon.Clearing.SettlingFirm = socket.ReadStr();
				ibCon.ShortSale.Slot = (IBOrderCondition.ShortSaleSlots)socket.ReadInt();
				ibCon.ShortSale.Location = socket.ReadStr();

				if (socket.ServerVersion == ServerVersions.V51)
					socket.ReadInt(); //exempt code
				else if (version >= ServerVersions.V23)
					ibCon.ShortSale.ExemptCode = socket.ReadInt();

				ibCon.AuctionStrategy = (IBOrderCondition.AuctionStrategies)socket.ReadInt();
				ibCon.StartingPrice = socket.ReadDecimal();
				ibCon.StockRefPrice = socket.ReadDecimal();
				ibCon.Delta = socket.ReadDecimal();
				ibCon.StockRangeLower = socket.ReadDecimal();
				ibCon.StockRangeUpper = socket.ReadDecimal();
				visibleVolume = socket.ReadInt();

				if (version < ServerVersions.V18)
				{
					// will never happen
					/* order.m_rthOnly = */
					socket.ReadBool();
				}

				ibCon.BlockOrder = socket.ReadBool();
				ibCon.SweepToFill = socket.ReadBool();
				ibCon.AllOrNone = socket.ReadBool();
				ibCon.MinVolume = socket.ReadInt();
				ibCon.Oca.Type = (IBOrderCondition.OcaTypes)socket.ReadInt();
				ibCon.SmartRouting.ETradeOnly = socket.ReadBool();
				ibCon.SmartRouting.FirmQuoteOnly = socket.ReadBool();
				ibCon.SmartRouting.NbboPriceCap = socket.ReadDecimal();
			}

			if (version >= ServerVersions.V10)
			{
				ibCon.ParentId = socket.ReadInt();
				ibCon.TriggerMethod = (IBOrderCondition.TriggerMethods)socket.ReadInt();
			}

			if (version >= ServerVersions.V11)
			{
				ibCon.Volatility.Volatility = socket.ReadDecimal();
				ibCon.Volatility.VolatilityTimeFrame = socket.ReadVolatilityType();

				if (version == ServerVersions.V11)
				{
					if (!socket.ReadBool())
						ibCon.Volatility.ExtendedOrderType = IBOrderCondition.ExtendedOrderTypes.Empty;
					else
						ibCon.Volatility.OrderType = OrderTypes.Market;
				}
				else
				{
					OrderTypes volOrdertype;
					IBOrderCondition.ExtendedOrderTypes? volExtendedType;
					socket.ReadOrderType(out volOrdertype, out volExtendedType);
					ibCon.Volatility.OrderType = volOrdertype;
					ibCon.Volatility.ExtendedOrderType = volExtendedType;

					ibCon.Volatility.StopPrice = socket.ReadDecimal();

					if (volExtendedType != IBOrderCondition.ExtendedOrderTypes.Empty)
					{
						if (version >= ServerVersions.V27)
						{
							ibCon.Volatility.ConId = socket.ReadInt();
							ibCon.Volatility.SettlingFirm = socket.ReadStr();

							var portfolioName = socket.ReadStr();
							if (!portfolioName.IsEmpty())
								ibCon.Volatility.ClearingPortfolio = portfolioName;

							ibCon.Volatility.ClearingIntent = socket.ReadStr();
						}

						if (version >= ServerVersions.V31)
						{
							var isOpenOrCloseStr = socket.ReadStr();
							ibCon.Volatility.ShortSale.IsOpenOrClose = isOpenOrCloseStr == "?" ? (bool?)null : isOpenOrCloseStr.To<int>() == 1;
							ibCon.Volatility.IsShortSale = socket.ReadBool();
							ibCon.Volatility.ShortSale.Slot = (IBOrderCondition.ShortSaleSlots)socket.ReadInt();
							ibCon.Volatility.ShortSale.Location = socket.ReadStr();
						}
					}
				}

				ibCon.Volatility.ContinuousUpdate = socket.ReadBool();

				if (socket.ServerVersion == ServerVersions.V26)
				{
					ibCon.StockRangeLower = socket.ReadDecimal();
					ibCon.StockRangeUpper = socket.ReadDecimal();
				}

				ibCon.Volatility.IsAverageBestPrice = socket.ReadBool();
			}

			if (version >= ServerVersions.V13)
				ibCon.TrailStopPrice = socket.ReadDecimal();

			if (version >= ServerVersions.V30)
				ibCon.TrailStopVolumePercentage = socket.ReadNullDecimal();

			if (version >= ServerVersions.V14)
			{
				ibCon.Combo.BasisPoints = socket.ReadDecimal();
				ibCon.Combo.BasisPointsType = socket.ReadInt();
				ibCon.Combo.LegsDescription = socket.ReadStr();
			}

			if (version >= ServerVersions.V29)
			{
				var comboLegsCount = socket.ReadInt();
				if (comboLegsCount > 0)
				{
					//contract.m_comboLegs = new Vector(comboLegsCount);
					for (var i = 0; i < comboLegsCount; ++i)
					{
						//int conId = 
						socket.ReadInt();
						//int ratio = 
						socket.ReadInt();
						//String action = 
						socket.ReadStr();
						//String exchange = 
						socket.ReadStr();
						//int openClose = 
						socket.ReadInt();
						//int shortSaleSlot = 
						socket.ReadInt();
						//String designatedLocation = 
						socket.ReadStr();
						//int exemptCode = 
						socket.ReadInt();

						//ComboLeg comboLeg = new ComboLeg(conId, ratio, action, exchange, openClose,
						//		shortSaleSlot, designatedLocation, exemptCode);
						//contract.m_comboLegs.add(comboLeg);
					}
				}

				var orderComboLegsCount = socket.ReadInt();
				if (orderComboLegsCount > 0)
				{
					//order.m_orderComboLegs = new Vector(orderComboLegsCount);
					for (var i = 0; i < orderComboLegsCount; ++i)
					{
						//var comboPrice = 
						socket.ReadNullDecimal();
						//OrderComboLeg orderComboLeg = new OrderComboLeg(comboPrice);
						//order.m_orderComboLegs.add(orderComboLeg);
					}
				}
			}

			if (version >= ServerVersions.V26)
			{
				var smartComboRoutingParamsCount = socket.ReadInt();
				if (smartComboRoutingParamsCount > 0)
				{
					var @params = new List<Tuple<string, string>>();

					for (var i = 0; i < smartComboRoutingParamsCount; ++i)
						@params.Add(Tuple.Create(socket.ReadStr(), socket.ReadStr()));

					ibCon.SmartRouting.ComboParams = @params;
				}
			}

			if (version >= ServerVersions.V15)
			{
				if (version >= ServerVersions.V20)
				{
					ibCon.Scale.InitLevelSize = socket.ReadNullInt();
					ibCon.Scale.SubsLevelSize = socket.ReadNullInt();
				}
				else
				{
					/* int notSuppScaleNumComponents = */
					socket.ReadNullInt();
					ibCon.Scale.InitLevelSize = socket.ReadNullInt();
				}

				ibCon.Scale.PriceIncrement = socket.ReadNullDecimal();
			}

			if (version >= ServerVersions.V28 && ibCon.Scale.PriceIncrement > 0)
			{
				ibCon.Scale.PriceAdjustValue = socket.ReadNullDecimal();
				ibCon.Scale.PriceAdjustInterval = socket.ReadInt();
				ibCon.Scale.ProfitOffset = socket.ReadNullDecimal();
				ibCon.Scale.AutoReset = socket.ReadBool();
				ibCon.Scale.InitPosition = socket.ReadNullInt();
				ibCon.Scale.InitFillQty = socket.ReadNullInt();
				ibCon.Scale.RandomPercent = socket.ReadBool();
			}

			if (version >= ServerVersions.V24)
				socket.ReadHedge(ibCon);

			if (version >= ServerVersions.V25)
				ibCon.SmartRouting.OptOutSmartRouting = socket.ReadBool();

			if (version >= ServerVersions.V19)
			{
				var portfolioName = socket.ReadStr();

				if (!portfolioName.IsEmpty())
					ibCon.Clearing.ClearingPortfolio = portfolioName;

				ibCon.Clearing.Intent = socket.ReadIntent();
			}

			if (version >= ServerVersions.V22)
				ibCon.SmartRouting.NotHeld = socket.ReadBool();

			if (version >= ServerVersions.V20)
			{
				if (socket.ReadBool())
				{
					//UnderlyingComponent underComp = new UnderlyingComponent();
					//underComp.ContractId = 
					socket.ReadInt();
					//underComp.Delta = 
					socket.ReadDecimal();
					//underComp.Price = 
					socket.ReadDecimal();
					//contract.UnderlyingComponent = underComp;
				}
			}

			if (version >= ServerVersions.V21)
			{
				ibCon.Algo.Strategy = socket.ReadStr();

				if (!ibCon.Algo.Strategy.IsEmpty())
				{
					var algoParamsCount = socket.ReadInt();

					if (algoParamsCount > 0)
					{
						var algoParams = new List<Tuple<string, string>>();

						for (var i = 0; i < algoParamsCount; i++)
							algoParams.Add(Tuple.Create(socket.ReadStr(), socket.ReadStr()));

						ibCon.Algo.Params = algoParams;
					}
				}
			}

			//OrderState orderState = new OrderState();

			OrderStatus? status = null;

			if (version >= ServerVersions.V16)
			{
				socket.ReadStr();
				//order.WhatIf = !(string.IsNullOrEmpty(rstr) || rstr == "0");

				status = socket.ReadOrderStatus();
				//orderState.InitMargin = 
				socket.ReadStr();
				//orderState.MaintMargin = 
				socket.ReadStr();
				//orderState.EquityWithLoan = 
				socket.ReadStr();
				//orderState.IbCommission = 
				socket.ReadNullDecimal();
				//orderState.MinCommission = 
				socket.ReadNullDecimal();
				//orderState.MaxCommission = 
				socket.ReadNullDecimal();
				//orderState.CommissionCurrency = 
				socket.ReadStr();
				//orderState.WarningText = 
				socket.ReadStr();
			}

			var secId = new SecurityId
			{
				SecurityCode = secCode,
				BoardCode = GetBoardCode(boardCode),
				InteractiveBrokers = contractId,
			};

			SendOutMessage(new SecurityMessage
			{
				SecurityId = secId,
				ExpiryDate = expiryDate,
				Strike = strike,
				OptionType = optionType,
				Class = secClass,
				SecurityType = type,
				Currency = currency,
				Multiplier = multiplier ?? 0,
			});

			var orderMsg = new ExecutionMessage
			{
				ExecutionType = ExecutionTypes.Transaction,
				SecurityId = secId,
				OriginalTransactionId = transactionId,
				OrderType = orderType,
				Side = direction,
				OrderVolume = volume,
				OrderPrice = price,
				Condition = ibCon,
				ExpiryDate = orderExpiryDate,
				VisibleVolume = visibleVolume,
				PortfolioName = portfolio,
				Comment = comment,
				OrderStatus = status,
				OrderState = status?.ToOrderState(),
				HasOrderInfo = true,
			};

			if (orderMsg.OrderState == OrderStates.Active || orderMsg.OrderState == OrderStates.Done)
				orderMsg.OrderId = transactionId;

			switch (expiration)
			{
				case "DAY":
					orderMsg.TimeInForce = TimeInForce.PutInQueue;
					break;
				case "GTC":
					//orderMsg.ExpiryDate = DateTimeOffset.MaxValue;
					break;
				case "IOC":
					orderMsg.TimeInForce = TimeInForce.CancelBalance;
					break;
				case "FOK":
					orderMsg.TimeInForce = TimeInForce.MatchOrCancel;
					break;
				case "GTD":
					break;
				case "OPG":
					ibCon.IsMarketOnOpen = true;
					break;
				default:
					throw new InvalidOperationException(LocalizedStrings.Str2515Params.Put(expiration));
			}

			if (clientId != null)
				orderMsg.SetClientId(clientId.Value);

			if (permId != null)
				orderMsg.SetPermId(permId.Value);

			SendOutMessage(orderMsg);
		}
		private void ReadTickSnapshotEnd(IBSocket socket)
		{
			/*var requestId = */socket.ReadInt();
			//SendOutMessage(_level1Messages.GetAndRemove(requestId));
		}