public void UpdateSubscribtions()
 {
     for (int i = 0; i < Subscribtions.Count; i++)
     {
         WebSocketSubscribeInfo info = Subscribtions[i];
         Telemetry.Default.TrackEvent(LogType.Warning, LogObject, "updating subscribtion", info.Type.ToString());
         SubscribeCore(info);
     }
 }
        public void Subscribe(WebSocketSubscribeInfo info)
        {
            WebSocketSubscribeInfo exist = Subscribtions.FirstOrDefault(s => s.Command.channel == info.Command.channel && s.Command.command == info.Command.command && s.Command.userID == info.Command.userID);

            if (exist != null)
            {
                exist.AddRef();
                return;
            }
            info.ShouldUpdateSubscribtion = true;
            Subscribtions.Add(info);
            info.AddRef();
            SubscribeCore(info);
        }
        void UnsubscribeCore(WebSocketSubscribeInfo info)
        {
            object logOwner = info.Ticker == null ? (object)Exchange : (object)info.Ticker;

            if (info.Type == SocketSubscribeType.OrderBook)
            {
                info.Ticker.IsOrderBookSubscribed = false;
                Telemetry.Default.TrackEvent(LogType.Log, logOwner, "order book channel unsubscibed", "");
            }
            else if (info.Type == SocketSubscribeType.TradeHistory)
            {
                info.Ticker.IsTradeHistorySubscribed = false;
                Telemetry.Default.TrackEvent(LogType.Log, logOwner, "trade history channel unsubscibed", "");
            }
            else if (info.Type == SocketSubscribeType.Kline)
            {
                info.Ticker.IsKlineSubscribed = false;
                Telemetry.Default.TrackEvent(LogType.Log, logOwner, "kline channel unsubscibed", "");
            }

            if (SocketType == SocketType.WebSocket)
            {
                string command = JsonConvert.SerializeObject(info.Command);
                Debug.WriteLine("send command = " + command);
                Socket.Send(command);
            }
            else
            {
                if (info.Type == SocketSubscribeType.OrderBook)
                {
                    info.Ticker.IsOrderBookSubscribed = false;
                }
                if (info.Type == SocketSubscribeType.TradeHistory)
                {
                    info.Ticker.IsTradeHistorySubscribed = false;
                }
                if (info.Type == SocketSubscribeType.Kline)
                {
                    info.Ticker.IsKlineSubscribed = false;
                }
            }
        }
        public void Unsubscribe(WebSocketSubscribeInfo info)
        {
            if (Signal != null)
            {
                return;
            }
            WebSocketSubscribeInfo found = Subscribtions.FirstOrDefault(s => s.Command.channel == info.Command.channel && s.Command.userID == info.Command.userID);

            if (found == null)
            {
                return;
            }
            found.Release();
            if (found.RefCount > 0)
            {
                return;
            }
            Subscribtions.Remove(found);
            UnsubscribeCore(info);
        }
        void SubscribeCore(WebSocketSubscribeInfo info)
        {
            object logOwner = info.Ticker == null ? (object)Exchange : (object)info.Ticker;

            if (!info.ShouldUpdateSubscribtion)
            {
                return;
            }
            if (State != SocketConnectionState.Connected)
            {
                info.ShouldUpdateSubscribtion = true;
                return;
            }
            info.ShouldUpdateSubscribtion = false;
            if (SocketType == SocketType.WebSocket)
            {
                if (info.Type == SocketSubscribeType.OrderBook)
                {
                    info.Ticker.IsOrderBookSubscribed = true;
                    info.Ticker.OrderBook.Clear();
                    Telemetry.Default.TrackEvent(LogType.Log, logOwner, "order book channel subscibed", "");
                }
                else if (info.Type == SocketSubscribeType.TradeHistory)
                {
                    info.Ticker.IsTradeHistorySubscribed = true;
                    info.Ticker.ClearTradeHistory();
                    Telemetry.Default.TrackEvent(LogType.Log, logOwner, "trade history channel subscibed", "");
                }
                else if (info.Type == SocketSubscribeType.Kline)
                {
                    info.Ticker.IsKlineSubscribed = true;
                    info.Ticker.CandleStickData.Clear();
                    Telemetry.Default.TrackEvent(LogType.Log, logOwner, "kline channel subscibed", "");
                }
                string command = JsonConvert.SerializeObject(info.Command);
                Debug.WriteLine("send command = " + command);
                Socket.Send(command);
            }
            else
            {
                if (info.Type == SocketSubscribeType.Tickers)
                {
                    SubscribeToMarketsState(() => {
                        Telemetry.Default.TrackEvent(LogType.Log, Exchange, "tickers channel subscibed", "");
                        if (info.AfterConnect != null)
                        {
                            info.AfterConnect();
                        }
                    });
                }
                else if (info.Type == SocketSubscribeType.OrderBook)
                {
                    SubscribeToExchangeDeltas(info.Ticker, (t) => {
                        t.IsOrderBookSubscribed = true;
                        QueryExchangeState(t.Name);
                        Telemetry.Default.TrackEvent(LogType.Log, logOwner, "order book channel subscibed", "");
                        if (info.AfterConnect != null)
                        {
                            info.AfterConnect();
                        }
                    });
                }
                else if (info.Type == SocketSubscribeType.TradeHistory)
                {
                    SubscribeToExchangeDeltas(info.Ticker, (t) => {
                        t.IsOrderBookSubscribed = true;
                        QueryExchangeState(t.Name);
                        Telemetry.Default.TrackEvent(LogType.Log, logOwner, "trade history channel subscibed", "");
                        if (info.AfterConnect != null)
                        {
                            info.AfterConnect();
                        }
                    });
                }
            }
        }