void _client_NewTradesEvent(TradeResponse trades) { lock (_newTradesLoker) { if (trades.data == null) { return; } Trade trade = new Trade(); trade.SecurityNameCode = trades.stream.ToString().ToUpper().Split('@')[0]; if (trade.SecurityNameCode != trades.data.s) { return; } trade.Price = trades.data.p.ToDecimal(); trade.Id = trades.data.t.ToString(); trade.Time = new DateTime(1970, 1, 1).AddMilliseconds(Convert.ToDouble(trades.data.T)); trade.Volume = trades.data.q.ToDecimal(); trade.Side = trades.data.m == true ? Side.Sell : Side.Buy; NewTradesEvent?.Invoke(trade); } }
/// <summary> /// got new ticks from server /// с сервера пришли новые тики /// </summary> private void ClientOnNewTradesEvent(List <TransaqEntity.Trade> trades) { foreach (var t in trades) { try { Trade trade = new Trade() { SecurityNameCode = t.Seccode, Id = t.Secid, Price = Convert.ToDecimal(t.Price.Replace(".", ",")), Side = t.Buysell == "B" ? Side.Buy : Side.Sell, Volume = Convert.ToDecimal(t.Quantity.Replace(".", ",")), Time = DateTime.Parse(t.Time), }; NewTradesEvent?.Invoke(trade); } catch (Exception e) { SendLogMessage("" + e, LogMessageType.Error); } } }
/// <summary> /// takes messages from the shared queue, converts them to C# classes, and sends them to up /// берет сообщения из общей очереди, конвертирует их в классы C# и отправляет на верх /// </summary> public void Converter() { while (true) { try { if (_isDisposed) { return; } if (!_newMessage.IsEmpty) { string data; if (_newMessage.TryDequeue(out data)) { if (data.StartsWith("<pits>") || data.StartsWith("<sec_info")) { continue; } if (data.StartsWith("<server_status")) { ServerStatus status = Deserialize <ServerStatus>(data); if (status.Connected == "true") { IsConnected = true; Connected?.Invoke(); } else if (status.Connected == "false") { IsConnected = false; Disconnected?.Invoke(); } else if (status.Connected == "error") { SendLogMessage(status.Text, LogMessageType.Error); } } else if (data.StartsWith("<securities>")) { var securities = _deserializer.Deserialize <List <Security> >(new RestResponse() { Content = data }); UpdatePairs?.Invoke(securities); } else if (data.StartsWith("<united_portfolio")) { UnitedPortfolio unitedPortfolio = Deserialize <UnitedPortfolio>(data); UpdatePortfolio?.Invoke(unitedPortfolio); } else if (data.StartsWith("<positions")) { var positions = Deserialize <TransaqPositions>(data); UpdatePositions?.Invoke(positions); } else if (data.StartsWith("<clientlimits")) { var limits = Deserialize <Clientlimits>(data); UpdateMonoPortfolio?.Invoke(limits); } else if (data.StartsWith("<client")) { var clientInfo = _deserializer.Deserialize <Client>(new RestResponse() { Content = data }); ClientsInfo?.Invoke(clientInfo); } else if (data.StartsWith("<alltrades>")) { var allTrades = _deserializer.Deserialize <List <Trade> >(new RestResponse() { Content = data }); NewTradesEvent?.Invoke(allTrades); } else if (data.StartsWith("<quotes>")) { var quotes = _deserializer.Deserialize <List <Quote> >(new RestResponse() { Content = data }); UpdateMarketDepth?.Invoke(quotes); } else if (data.StartsWith("<orders>")) { var orders = _deserializer.Deserialize <List <Order> >(new RestResponse() { Content = data }); MyOrderEvent?.Invoke(orders); } else if (data.StartsWith("<trades>")) { var myTrades = _deserializer.Deserialize <List <Trade> >(new RestResponse() { Content = data }); MyTradeEvent?.Invoke(myTrades); } else if (data.StartsWith("<candles")) { Candles newCandles = Deserialize <Candles>(data); NewCandles?.Invoke(newCandles); } else if (data.StartsWith("<messages>")) { if (data.Contains("Время действия Вашего пароля истекло")) { NeedChangePassword?.Invoke(); } } } } } catch (Exception exception) { SendLogMessage(exception.ToString(), LogMessageType.Error); } Thread.Sleep(1); } }
/// <summary> /// takes messages from the common queue, converts them to C # classes and sends them to up /// берет сообщения из общей очереди, конвертирует их в классы C# и отправляет на верх /// </summary> public void Converter() { while (true) { if (_isDisposed) { return; } if (!_newMessage.IsEmpty) { protobuf.ws.WsResponse response; if (_newMessage.TryDequeue(out response)) { try { if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.TradeChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.TradeChannelSubscribedResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.TradeChannelSubscribedResponse>(messageStream); SendLogMessage("Успешная подписка на все сделки", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.TradeNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { try { protobuf.ws.TradeNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.TradeNotification>(messageStream); message.CurrencyPair = message.CurrencyPair.Replace('/', '_'); NewTradesEvent?.Invoke(message); } catch { // ignore } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.Error) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.ErrorResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.ErrorResponse>(messageStream); var token = response.Meta.Token; if (message.Message.StartsWith("Channel already subscribed")) { continue; } if (token.StartsWith("NewOrder")) { var order = new PrivateOrderRawEvent(); order.Id = -1; MyOrderEvent?.Invoke(Convert.ToInt32(token.Split('_')[1]), GetPortfolioName(), order); } if (message.Message.StartsWith("insufficient funds")) { continue; } SendLogMessage("WsClient error : " + message.Message, LogMessageType.Error); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.ChannelUnsubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.ChannelUnsubscribedResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.ChannelUnsubscribedResponse>(messageStream); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.LoginResponse) { IsConnected = true; if (Connected != null) { Connected(); } // SendLogMessage("Соединение через вебсокет успешно установлено", LogMessageType.System); } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.BalanceChangeChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateSubscribeBalanceChangeChannelRequest message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateSubscribeBalanceChangeChannelRequest>(messageStream); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.BalanceChangeNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateChangeBalanceNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateChangeBalanceNotification>(messageStream); if (UpdatePortfolio != null) { UpdatePortfolio(GetPortfolioName(), message); } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.OrderBookNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.OrderBookNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.OrderBookNotification>(messageStream); message.CurrencyPair = message.CurrencyPair.Replace('/', '_'); if (UpdateMarketDepth != null) { UpdateMarketDepth(message); } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.OrderBookChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.OrderBookChannelSubscribedResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.OrderBookChannelSubscribedResponse>(messageStream); // SendLogMessage("Успешная подписка на стакан котировок", LogMessageType.System); message.CurrencyPair = message.CurrencyPair.Replace('/', '_'); if (NewMarketDepth != null) { NewMarketDepth(message); } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateOrderRawChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { //SendLogMessage("Успешная подписка на мои ордера", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateOrderRawNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateOrderRawNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateOrderRawNotification>(messageStream); foreach (var ev in message.Datas) { if (!_myOrders.ContainsValue(ev.Id)) { ev.CurrencyPair = ev.CurrencyPair.Replace('/', '_'); _orderEvents.Add(ev); } else { var needNumberUser = _myOrders.First(o => o.Value == ev.Id); ev.CurrencyPair = ev.CurrencyPair.Replace('/', '_'); MyOrderEvent?.Invoke(needNumberUser.Key, GetPortfolioName(), ev); } } //SendLogMessage("Пришла информацияпо ордеру", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateTradeChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { //SendLogMessage("Успешная подписка на мои сделки", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateTradeNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateTradeNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateTradeNotification>(messageStream); //SendLogMessage("Пришла моя сделка", LogMessageType.System); foreach (var t in message.Datas) { t.CurrencyPair = t.CurrencyPair.Replace('/', '_'); if (!_myOrders.ContainsValue(t.OrderBuyId)) { _queueMyTradeEvents.Add(t); } else { MyTradeEvent?.Invoke(t.OrderBuyId.ToString(), t); } if (!_myOrders.ContainsValue(t.OrderSellId)) { _queueMyTradeEvents.Add(t); } else { MyTradeEvent?.Invoke(t.OrderSellId.ToString(), t); } } } }//PUT_LIMIT_ORDER_RESPONSE else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PutLimitOrderResponse) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PutLimitOrderResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PutLimitOrderResponse>(messageStream); var orderData = response.Meta.Token.Split('_'); int id = Convert.ToInt32(orderData[1]); _myOrders.Add(id, message.OrderId); HandleAllNeedEvents(message.OrderId); } } } catch (Exception exception) { SendLogMessage(exception.Message, LogMessageType.Error); SendLogMessage("Message type " + response.Meta.ResponseType, LogMessageType.Error); } } } else { Thread.Sleep(1); } } }
protected void OnTradeEvent(Trade trade) { NewTradesEvent?.Invoke(trade); }