예제 #1
0
        private void Client_MyOrderEvent(int numUser, string portfolio, PrivateOrderRawEvent orderInfo)
        {
            lock (_orderLocker)
            {
                var needOrder = _myOrders.Find(o => o.NumberUser == numUser);

                if (needOrder == null)
                {
                    return;
                }

                var order = new OsEngine.Entity.Order();
                order.NumberUser       = numUser;
                order.PortfolioNumber  = portfolio;
                order.SecurityNameCode = needOrder.SecurityNameCode;

                if (orderInfo.Id == -1)
                {
                    order.State        = OrderStateType.Fail;
                    order.Price        = needOrder.Price;
                    order.Volume       = needOrder.Volume;
                    order.Side         = needOrder.Side;
                    order.NumberMarket = needOrder.NumberMarket;

                    MyOrderEvent?.Invoke(order);

                    return;
                }

                order.NumberMarket = orderInfo.Id.ToString();
                order.Price        = ParseDecimal(orderInfo.Price);
                order.TimeCallBack = new DateTime(1970, 1, 1).AddMilliseconds(Convert.ToDouble(orderInfo.Timestamp));
                order.Volume       = needOrder.Volume;
                order.Side         = orderInfo.order_type == PrivateOrderRawEvent.OrderType.Bid ? Side.Buy : Side.Sell;

                decimal quantity     = ParseDecimal(orderInfo.Quantity);
                decimal cancelVolume = ParseDecimal(orderInfo.QuantityLeftBeforeCancellation);

                if (quantity == 0 && cancelVolume == needOrder.Volume)
                {
                    order.State = OrderStateType.Cancel;
                    DelOrder(needOrder);
                }
                else if (quantity == 0 && cancelVolume == 0)
                {
                    order.State = OrderStateType.Done;
                    DelOrder(needOrder);
                }
                else if (quantity == order.Volume)
                {
                    order.State = OrderStateType.Activ;
                }
                else if (needOrder.Volume != quantity && quantity != 0)
                {
                    order.State = OrderStateType.Patrial;
                }

                MyOrderEvent?.Invoke(order);
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }