public void Update(Ticker ticker, IncrementalUpdateInfo info)
 {
     for (int i = 0; i < info.BidsUpdates.Count; i++)
     {
         string[] item = info.BidsUpdates[i];
         ticker.OrderBook.ApplyIncrementalUpdate(OrderBookEntryType.Bid, item[1], item[2]);
     }
     for (int i = 0; i < info.AsksUpdates.Count; i++)
     {
         string[] item = info.AsksUpdates[i];
         ticker.OrderBook.ApplyIncrementalUpdate(OrderBookEntryType.Ask, item[1], item[2]);
     }
     for (int i = 0; i < info.TradeUpdates.Count; i++)
     {
         string[]      item  = info.TradeUpdates[i];
         TradeInfoItem trade = new TradeInfoItem(null, ticker)
         {
             Type         = item[1][0] == 'S' ? TradeType.Sell : TradeType.Buy,
             RateString   = item[2],
             AmountString = item[3],
             Time         = new DateTime(Convert.ToInt64(item[4])).ToLocalTime()
         };
         ticker.AddTradeHistoryItem(trade);//.InsertTradeHistoryItem(trade);
         CandleStickChartHelper.UpdateVolumes(ticker.CandleStickData, trade, ticker.CandleStickPeriodMin);
     }
     ticker.OnApplyIncrementalUpdate();
 }
Exemple #2
0
 public void Update(Ticker ticker, IncrementalUpdateInfo info)
 {
     foreach (string[] item in info.Updates)
     {
         if (item[0][0] == 'o')
         {
             ticker.OrderBook.ApplyIncrementalUpdate(
                 item[1][0] == '1' ? OrderBookEntryType.Bid : OrderBookEntryType.Ask,
                 item[2],
                 item[3]);
         }
         else if (item[0][0] == 't')
         {
             TradeInfoItem trade = new TradeInfoItem(null, ticker)
             {
                 Type         = item[2][0] == '0' ? TradeType.Sell : TradeType.Buy,
                 RateString   = item[3],
                 AmountString = item[4],
                 Time         = new DateTime(Convert.ToInt64(item[5]))
             };
             ticker.TradeHistory.Insert(0, trade);
             CandleStickChartHelper.UpdateVolumes(ticker.CandleStickData, trade, ticker.CandleStickPeriodMin);
         }
     }
     ticker.OnApplyIncrementalUpdate();
 }
        public List <TradeInfoItem> GetTradeVolumesForCandleStick(Ticker ticker, long start, long end)
        {
            List <TradeInfoItem> trades = new List <TradeInfoItem>();
            string address = string.Format("https://api.binance.com/api/v1/aggTrades?symbol={0}&limit={1}&startTime={2}&endTime={3}", Uri.EscapeDataString(ticker.CurrencyPair), 1000, start, end);

            byte[] data = ((Ticker)ticker).DownloadBytes(address);
            if (data == null || data.Length == 0)
            {
                return(trades);
            }

            int             parseIndex = 0;
            List <string[]> items      = JSonHelper.Default.DeserializeArrayOfObjects(data, ref parseIndex, AggTradesItem);

            for (int i = items.Count - 1; i >= 0; i--)
            {
                string[] item = items[i];
                DateTime time = FromUnixTime(FastValueConverter.ConvertPositiveLong(item[5]));

                TradeInfoItem t     = new TradeInfoItem(null, ticker);
                bool          isBuy = item[6][0] != 't';
                t.AmountString = item[2];
                t.Time         = time;
                t.Type         = isBuy ? TradeType.Buy : TradeType.Sell;
                trades.Add(t);
            }
            return(trades);
        }
Exemple #4
0
 public void Update(Ticker ticker, IncrementalUpdateInfo info)
 {
     for (int i = 0; i < info.Updates.Count; i++)
     {
         string[] item = info.Updates[i];
         if (item[0][0] == 'o')
         {
             ticker.OrderBook.ApplyIncrementalUpdate(item[1][0] == '1' ? OrderBookEntryType.Bid : OrderBookEntryType.Ask, item[2], item[3]);
         }
         else if (item[0][0] == 't')
         {
             TradeInfoItem trade = new TradeInfoItem(null, ticker)
             {
                 Type = item[2][0] == '0' ? TradeType.Sell : TradeType.Buy, RateString = item[3], AmountString = item[4], Time = ticker.Exchange.FromUnixTimestamp(Convert.ToInt64(item[5]))
             };
             if (trade.Time.Year == 1)
             {
                 throw new InvalidOperationException();
             }
             ticker.TradeHistory.Insert(0, trade);
             CandleStickChartHelper.UpdateVolumes(ticker.CandleStickData, trade, ticker.CandleStickPeriodMin);
         }
     }
     ticker.OnApplyIncrementalUpdate();
 }
Exemple #5
0
        public override bool UpdateTrades(Ticker info)
        {
            string address = string.Format("https://bittrex.com/api/v1.1/public/getmarkethistory?market={0}", Uri.EscapeDataString(info.MarketName));

            byte[] bytes = null;
            try {
                bytes = GetDownloadBytes(address);
            }
            catch (Exception) {
                return(false);
            }
            if (bytes == null)
            {
                return(false);
            }

            int startIndex = 1;

            if (!JSonHelper.Default.SkipSymbol(bytes, ':', 3, ref startIndex))
            {
                return(false);
            }

            long            lastId       = info.TradeHistory.Count > 0 ? info.TradeHistory.First().Id : -1;
            string          lastIdString = lastId.ToString();
            List <string[]> res          = JSonHelper.Default.DeserializeArrayOfObjects(bytes, ref startIndex, new string[] { "Id", "TimeStamp", "Quantity", "Price", "Total", "FillType", "OrderType" },
                                                                                        (itemIndex, paramIndex, value) => {
                return(paramIndex != 0 || lastIdString != value);
            });

            if (res == null || res.Count == 0)
            {
                return(true);
            }

            int index = 0;

            lock (info) {
                foreach (string[] obj in res)
                {
                    TradeInfoItem item = new TradeInfoItem(null, info);
                    item.Id           = Convert.ToInt64(obj[0]);
                    item.Time         = Convert.ToDateTime(obj[1]);
                    item.AmountString = obj[2];
                    item.RateString   = obj[3];
                    item.Total        = FastValueConverter.Convert(obj[4]);
                    item.Type         = obj[6].Length == 3 ? TradeType.Buy : TradeType.Sell;
                    item.Fill         = obj[5].Length == 4 ? TradeFillType.Fill : TradeFillType.PartialFill;
                    info.TradeHistory.Insert(index, item);
                    index++;
                }
            }
            info.RaiseTradeHistoryAdd();
            return(true);
        }
Exemple #6
0
        public void ApplySnapshot(Dictionary <string, object> jObject, Ticker ticker)
        {
            ticker.OrderBook.Clear();
            OrderBook orderBook = ticker.OrderBook;

            List <object> jbids = (List <object>)jObject["Z"];
            List <object> jasks = (List <object>)jObject["S"];

            List <OrderBookEntry> entries         = orderBook.Asks;
            List <OrderBookEntry> entriesInverted = orderBook.AsksInverted;

            foreach (Dictionary <string, object> item in jasks)
            {
                entries.Add(new OrderBookEntry()
                {
                    ValueString = (string)item["R"], AmountString = (string)item["Q"]
                });
                entriesInverted.Insert(0, new OrderBookEntry()
                {
                    ValueString = (string)item["R"], AmountString = (string)item["Q"]
                });
            }

            entries = orderBook.Bids;
            foreach (Dictionary <string, object> item in jbids)
            {
                entries.Add(new OrderBookEntry()
                {
                    ValueString = (string)item["R"], AmountString = (string)item["Q"]
                });
            }

            orderBook.UpdateEntries();
            orderBook.RaiseOnChanged(new IncrementalUpdateInfo());

            ticker.TradeHistory.Clear();
            List <object> jtrades = (List <object>)jObject["f"];

            foreach (Dictionary <string, object> item in jtrades)
            {
                TradeInfoItem t = new TradeInfoItem(null, ticker);
                t.AmountString = (string)item["Q"];
                t.RateString   = (string)item["P"];
                t.Time         = new DateTime(Convert.ToInt64((string)item["T"])).ToLocalTime();
                t.TimeString   = t.Time.ToLongTimeString();
                t.Total        = t.Rate * t.Amount;
                t.Type         = ((string)item["OT"]) == "BUY"? TradeType.Buy: TradeType.Sell;
                ticker.TradeHistory.Add(t);
            }

            ticker.RaiseTradeHistoryAdd();
        }
        public override ResizeableArray <TradeInfoItem> GetTrades(Ticker ticker, DateTime starTime)
        {
            string address = string.Format("https://api.binance.com/api/v1/depth?symbol={0}&limit={1}",
                                           Uri.EscapeDataString(ticker.CurrencyPair), 1000);
            string text = ((Ticker)ticker).DownloadString(address);

            if (string.IsNullOrEmpty(text))
            {
                return(null);
            }

            JArray trades = JsonConvert.DeserializeObject <JArray>(text);

            if (trades.Count == 0)
            {
                return(null);
            }

            ResizeableArray <TradeInfoItem> list = new ResizeableArray <TradeInfoItem>(1000);
            int index = 0;

            for (int i = 0; i < trades.Count; i++)
            {
                JObject  obj     = (JObject)trades[i];
                DateTime time    = new DateTime(obj.Value <Int64>("time"));
                int      tradeId = obj.Value <int>("id");
                if (time < starTime)
                {
                    break;
                }
                TradeInfoItem item  = new TradeInfoItem(null, ticker);
                bool          isBuy = obj.Value <string>("type").Length == 3;
                item.AmountString = obj.Value <string>("qty");
                item.Time         = time;
                item.Type         = isBuy ? TradeType.Buy : TradeType.Sell;
                item.RateString   = obj.Value <string>("price");
                item.Id           = tradeId;
                double price  = item.Rate;
                double amount = item.Amount;
                item.Total = price * amount;
                list.Add(item);
                index++;
            }
            if (ticker.HasTradeHistorySubscribers)
            {
                ticker.RaiseTradeHistoryChanged(new TradeHistoryChangedEventArgs()
                {
                    NewItems = list
                });
            }
            return(list);
        }
        void OnTradeHistoryItemRecv(Ticker ticker, string[] str)
        {
            TradeInfoItem item = new TradeInfoItem(null, ticker);

            item.Id           = FastValueConverter.ConvertPositiveInteger(str[3]);
            item.RateString   = str[4];
            item.AmountString = str[5];
            item.Time         = FromUnixTime(FastValueConverter.ConvertPositiveLong(str[8]));
            item.Type         = str[9][0] == 't' ? TradeType.Sell : TradeType.Buy;

            ticker.TradeHistory.Insert(0, item);
            ticker.RaiseTradeHistoryAdd();
        }
Exemple #9
0
        public override List <TradeInfoItem> GetTrades(Ticker info, DateTime starTime)
        {
            string address = string.Format("https://bittrex.com/api/v1.1/public/getmarkethistory?market={0}", Uri.EscapeDataString(info.MarketName));

            byte[] bytes = null;
            try {
                bytes = GetDownloadBytes(address);
            }
            catch (Exception) {
                return(null);
            }
            if (bytes == null)
            {
                return(null);
            }

            int startIndex = 1;

            if (!JSonHelper.Default.SkipSymbol(bytes, ':', 3, ref startIndex))
            {
                return(null);
            }

            List <string[]> res = JSonHelper.Default.DeserializeArrayOfObjects(bytes, ref startIndex, new string[] { "Id", "TimeStamp", "Quantity", "Price", "Total", "FillType", "OrderType" },
                                                                               (itemIndex, paramIndex, value) => {
                return(paramIndex != 1 || Convert.ToDateTime(value) >= starTime);
            });

            if (res == null)
            {
                return(null);
            }
            List <TradeInfoItem> list = new List <TradeInfoItem>();

            int index = 0;

            foreach (string[] obj in res)
            {
                TradeInfoItem item = new TradeInfoItem(null, info);
                item.Id           = Convert.ToInt64(obj[0]);
                item.Time         = Convert.ToDateTime(obj[1]);
                item.AmountString = obj[2];
                item.RateString   = obj[3];
                item.Total        = FastValueConverter.Convert(obj[4]);
                item.Type         = obj[6].Length == 3 ? TradeType.Buy : TradeType.Sell;
                item.Fill         = obj[5].Length == 4 ? TradeFillType.Fill : TradeFillType.PartialFill;
                list.Insert(index, item);
                index++;
            }
            return(list);
        }
Exemple #10
0
        protected override TradeInfoItem InitializeAccountTradeInfoItem(string[] item, Ticker ticker)
        {
            DateTime time = FromUnixTime(FastValueConverter.ConvertPositiveLong(item[13]));

            TradeInfoItem t = new TradeInfoItem(null, ticker);

            t.OrderNumber  = item[5];
            t.AmountString = item[7];
            t.Time         = time;
            t.Type         = String2TradeType(item[10]);
            t.RateString   = item[6];
            t.IdString     = item[3];
            return(t);
        }
Exemple #11
0
        protected override TradeInfoItem InitializeTradeInfoItem(string[] item, Ticker ticker)
        {
            DateTime time = FromUnixTime(FastValueConverter.ConvertPositiveLong(item[4]));

            TradeInfoItem t     = new TradeInfoItem(null, ticker);
            bool          isBuy = item[4][0] != 't';

            t.AmountString = item[2];
            t.Time         = time;
            t.Type         = isBuy ? TradeType.Buy : TradeType.Sell;
            t.RateString   = item[1];
            t.IdString     = item[0];

            return(t);
        }
Exemple #12
0
        bool OnGetAccountTrades(AccountInfo account, Ticker ticker, byte[] bytes) {
            if(bytes == null)
                return false;

            int startIndex = 1;
            if(!JSonHelper.Default.SkipSymbol(bytes, ':', 3, ref startIndex))
                return false;

            string tradeUuid = ticker.MyTradeHistory.Count == 0 ? null : ticker.MyTradeHistory.First().IdString;
            List<string[]> res = JSonHelper.Default.DeserializeArrayOfObjects(bytes, ref startIndex, new string[] {
                "OrderUuid", // 0
                "Exchange",  // 1
                "TimeStamp",  // 2
                "OrderType", // 3
                "Limit",     // 4
                "Quantity",  // 5
                "QuantityRemaining", // 6
                "Commission", // 7
                "Price",  // 8
                "PricePerUnit",  // 9
                "IsConditional",
                "Condition",
                "ConditionTarget",
                "ImmediateOrCancel",
            },
            (itemIndex, paramIndex, value) => {
                return paramIndex != 0 || value != tradeUuid;
            });
            if(res == null)
                return false;
            if(res.Count == 0)
                return true;
            int index = 0;
            for(int i = 0; i < res.Count; i++) {
                string[] obj = res[i];
                TradeInfoItem item = new TradeInfoItem(account, ticker);
                item.IdString = obj[0];
                item.Type = obj[3] == "LIMIT_BUY" ? TradeType.Buy : TradeType.Sell;
                item.AmountString = obj[5];
                item.RateString = obj[9];
                item.Fee = FastValueConverter.Convert(obj[7]);
                item.Total = FastValueConverter.Convert(obj[8]);
                item.TimeString = obj[2];
                ticker.MyTradeHistory.Insert(index, item);
                index++;
            }
            return true;
        }
Exemple #13
0
        public bool GetTrades(BitFinexTicker info)
        {
            string address = string.Format("https://bittrex.com/api/v1.1/public/getmarkethistory?market={0}", Uri.EscapeDataString(info.MarketName));

            byte[] bytes = null;
            try {
                bytes = GetDownloadBytes(address);
            }
            catch (Exception) {
                return(false);
            }
            if (bytes == null)
            {
                return(false);
            }

            int startIndex = 1;

            if (!JSonHelper.Default.SkipSymbol(bytes, ':', 3, ref startIndex))
            {
                return(false);
            }

            List <string[]> res = JSonHelper.Default.DeserializeArrayOfObjects(bytes, ref startIndex, new string[] { "Id", "TimeStamp", "Quantity", "Price", "Total", "FillType", "OrderType" });

            if (res == null)
            {
                return(false);
            }
            lock (info) {
                info.TradeHistory.Clear();
                foreach (string[] obj in res)
                {
                    TradeInfoItem item = new TradeInfoItem(null, info);
                    item.Id           = Convert.ToInt64(obj[0]);;
                    item.Time         = Convert.ToDateTime(obj[1]);
                    item.AmountString = obj[2];
                    item.RateString   = obj[3];
                    item.Total        = FastValueConverter.Convert(obj[4]);
                    item.Type         = obj[6].Length == 3 ? TradeType.Buy : TradeType.Sell;
                    item.Fill         = obj[5].Length == 4 ? TradeFillType.Fill : TradeFillType.PartialFill;
                    info.TradeHistory.Add(item);
                }
            }
            info.RaiseTradeHistoryAdd();
            return(true);
        }
        protected internal override void OnTradeHistorySocketMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            LastWebSocketRecvTime = DateTime.Now;
            SocketConnectionInfo info = TradeHistorySockets.FirstOrDefault(c => c.Key == sender);

            if (info == null)
            {
                return;
            }
            Ticker t = info.Ticker;

            if (t.IsUpdatingTrades)
            {
                return;
            }

            if (t.CaptureData)
            {
                t.CaptureDataCore(CaptureStreamType.TradeHistory, CaptureMessageType.Incremental, e.Message);
            }

            JObject obj   = JsonConvert.DeserializeObject <JObject>(e.Message);
            JArray  items = obj.Value <JArray>("data");

            if (items == null)
            {
                return;
            }
            foreach (JObject item in items)
            {
                TradeInfoItem ti = new TradeInfoItem(null, t);
                ti.TimeString   = item.Value <string>("timestamp");
                ti.Type         = String2TradeType(item.Value <string>("side"));
                ti.AmountString = item.Value <string>("size");
                ti.RateString   = item.Value <string>("price");
                t.AddTradeHistoryItem(ti); //.InsertTradeHistoryItem(ti);
            }

            if (t.HasTradeHistorySubscribers)
            {
                TradeHistoryChangedEventArgs ee = new TradeHistoryChangedEventArgs()
                {
                    NewItem = t.TradeHistory.First()
                };
                t.RaiseTradeHistoryChanged(ee);
            }
        }
        public override bool UpdateTrades(Ticker ticker)
        {
            string address = string.Format("https://api.binance.com/api/v1/trades?symbol={0}&limit={1}",
                                           Uri.EscapeDataString(ticker.CurrencyPair), 1000);

            byte[] data = ((Ticker)ticker).DownloadBytes(address);
            if (data == null || data.Length == 0)
            {
                return(false);
            }

            ticker.TradeHistory.Clear();
            ticker.TradeStatistic.Clear();

            int             index = 0, parseIndex = 0;
            List <string[]> items = JSonHelper.Default.DeserializeArrayOfObjects(data, ref parseIndex, TradeItemString);
            ResizeableArray <TradeInfoItem> newItems = new ResizeableArray <TradeInfoItem>(items.Count);

            for (int i = items.Count - 1; i >= 0; i--)
            {
                string[] item    = items[i];
                DateTime time    = FromUnixTime(FastValueConverter.ConvertPositiveLong(item[3]));
                int      tradeId = FastValueConverter.ConvertPositiveInteger(item[0]);

                TradeInfoItem t     = new TradeInfoItem(null, ticker);
                bool          isBuy = item[4][0] != 't';
                t.AmountString = item[2];
                t.Time         = time;
                t.Type         = isBuy ? TradeType.Buy : TradeType.Sell;
                t.RateString   = item[1];
                t.Id           = tradeId;
                double price  = t.Rate;
                double amount = t.Amount;
                t.Total = price * amount;
                ticker.TradeHistory.Add(t);
                newItems.Add(t);
                index++;
            }
            if (ticker.HasTradeHistorySubscribers)
            {
                ticker.RaiseTradeHistoryChanged(new TradeHistoryChangedEventArgs()
                {
                    NewItems = newItems
                });
            }
            return(true);
        }
        protected override bool GetTradesCore(ResizeableArray <TradeInfoItem> list, Ticker ticker, DateTime startTime, DateTime endTime)
        {
            string address = string.Format("https://www.bitmex.com/api/v1/trade?symbol={0}&count=1000&startTime={1}&endTime={2}", ticker.Name, DateToString(startTime), DateToString(endTime));
            string text    = string.Empty;

            try {
                text = GetDownloadString(address);

                if (string.IsNullOrEmpty(text))
                {
                    return(false);
                }
                if (text[0] == '{')
                {
                    JObject obj = JsonConvert.DeserializeObject <JObject>(text);
                    LogManager.Default.Add(LogType.Error, this, Type.ToString(), "error in GetTradesCore", obj.Value <string>("message"));
                    return(false);
                }
                JArray res = JsonConvert.DeserializeObject <JArray>(text);
                foreach (JObject obj in res.Children())
                {
                    TradeInfoItem item = new TradeInfoItem();
                    item.Ticker       = ticker;
                    item.RateString   = obj.Value <string>("price");
                    item.AmountString = obj.Value <string>("size");
                    item.Type         = obj.Value <string>("side")[0] == 'S' ? TradeType.Sell : TradeType.Buy;
                    item.TimeString   = obj.Value <string>("timestamp");
                    DateTime time = item.Time;
                    if (list.Last() == null || list.Last().Time <= time)
                    {
                        list.Add(item);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch (Exception) {
                return(false);
            }
            return(true);
        }
        void OnTradeHistoryItemRecv(Ticker ticker, string[] str)
        {
            TradeInfoItem item = new TradeInfoItem(null, ticker);

            item.Id           = FastValueConverter.ConvertPositiveInteger(str[3]);
            item.RateString   = str[4];
            item.AmountString = str[5];
            item.Time         = FromUnixTime(FastValueConverter.ConvertPositiveLong(str[8]));
            item.Type         = str[9][0] == 't' ? TradeType.Sell : TradeType.Buy;

            ticker.TradeHistory.Insert(0, item);
            if (ticker.HasTradeHistorySubscribers)
            {
                TradeHistoryChangedEventArgs e = new TradeHistoryChangedEventArgs()
                {
                    NewItem = item
                };
                ticker.RaiseTradeHistoryChanged(e);
            }
        }
Exemple #18
0
        protected override bool GetTradesCore(ResizeableArray <TradeInfoItem> list, Ticker ticker, DateTime start, DateTime end)
        {
            string address = string.Format("https://api.binance.com/api/v1/aggTrades?symbol={0}&limit={1}&startTime={2}&endTime={3}",
                                           Uri.EscapeDataString(ticker.CurrencyPair), 1000, ToUnixTimestampMs(start), ToUnixTimestampMs(end));

            byte[] data = ((Ticker)ticker).DownloadBytes(address);
            if (data == null || data.Length == 0)
            {
                return(false);
            }

            int             parseIndex = 0;
            List <string[]> items      = JSonHelper.Default.DeserializeArrayOfObjects(data, ref parseIndex, AggTradeItemString);

            for (int i = 0; i < items.Count; i++)
            {
                string[] item = items[i];
                DateTime time = FromUnixTimestampMs(FastValueConverter.ConvertPositiveLong(item[5]));
                //if(time > end)
                //    break;
                int tradeId = FastValueConverter.ConvertPositiveInteger(item[0]);

                TradeInfoItem t     = new TradeInfoItem(null, ticker);
                bool          isBuy = item[6][0] != 't';
                t.AmountString = item[2];
                t.Time         = time;
                t.Type         = isBuy ? TradeType.Buy : TradeType.Sell;
                t.RateString   = item[1];
                t.Id           = tradeId;
                double price  = t.Rate;
                double amount = t.Amount;
                t.Total = price * amount;
                if (list.Last() == null || list.Last().Time < time)
                {
                    list.Add(t);
                }
            }
            return(true);
        }
        ResizeableArray <TickerTradeHistoryInfoItem> CalcItems()
        {
            if (TradeHistory.Count == 0)
            {
                return(new ResizeableArray <TickerTradeHistoryInfoItem>());
            }
            DateTime min = TradeHistory[0].Time;
            DateTime max = TradeHistory.Last().Time;

            if (min > max)
            {
                DateTime tmp = min; min = max; max = tmp;
            }
            int interval = HistogrammIntervalSec * 1000;
            int count    = (int)((max - min).TotalMilliseconds / interval + 0.5);

            ResizeableArray <TickerTradeHistoryInfoItem> list = new ResizeableArray <TickerTradeHistoryInfoItem>(count + 1);
            double k = 1.0 / interval;

            for (int i = 0; i < count + 1; i++)
            {
                list[i] = new TickerTradeHistoryInfoItem()
                {
                    Time = min.AddMilliseconds(i * interval)
                };
                list[i].Low       = double.MaxValue;
                list[i].OpenTime  = list[i].Time.AddMilliseconds(interval);
                list[i].CloseTime = list[i].Time;
            }

            for (int i = 0; i < TradeHistory.Count; i++)
            {
                DateTime time  = TradeHistory[i].Time;
                int      index = (int)((time - min).TotalMilliseconds * k);
                TickerTradeHistoryInfoItem item = list[index];
                TradeInfoItem trade             = TradeHistory[i];
                item.TradeCount++;
                item.TradeVolume += trade.Amount;

                if (TradeHistory[i].Type == TradeType.Sell)
                {
                    item.SellCount--;
                    item.SellVolume -= trade.Amount;
                }
                else
                {
                    item.BuyCount++;
                    item.BuyVolume += trade.Amount;
                }
                if (item.Low > trade.Rate)
                {
                    item.Low = trade.Rate;
                }
                if (item.High < trade.Rate)
                {
                    item.High = trade.Rate;
                }
                if (item.OpenTime >= trade.Time)
                {
                    item.OpenTime = trade.Time;
                    item.Open     = trade.Rate;
                }
                if (item.CloseTime <= trade.Time)
                {
                    item.CloseTime = trade.Time;
                    item.Close     = trade.Rate;
                }
            }
            TickerTradeHistoryInfoItem last = null;

            for (int i = 0; i < count + 1; i++)
            {
                if (list[i].TradeCount == 0)
                {
                    if (last != null)
                    {
                        list[i].Open = list[i].Close = list[i].High = list[i].Low = last.Close;
                    }
                    else
                    {
                        list[i].Open = list[i].Close = list[i].High = list[i].Low = 0;
                    }
                }
                else
                {
                    last = list[i];
                }
            }

            for (int i = 0; i < list.Count; i++)
            {
                CalculateTrendInfo(list, i);
            }

            return(list);
        }
        public void ApplySnapshot(JObject jObject, Ticker ticker)
        {
            ticker.OrderBook.BeginUpdate();
            try {
                ticker.OrderBook.Clear();
                OrderBook orderBook = ticker.OrderBook;

                JArray jbids = jObject.Value <JArray>("Z");
                JArray jasks = jObject.Value <JArray>("S");

                List <OrderBookEntry> entries         = orderBook.Asks;
                List <OrderBookEntry> entriesInverted = orderBook.AsksInverted;
                for (int i = 0; i < jasks.Count; i++)
                {
                    JObject item = (JObject)jasks[i];
                    entries.Add(new OrderBookEntry()
                    {
                        ValueString = item.Value <string>("R"), AmountString = item.Value <string>("Q")
                    });
                    if (entriesInverted != null)
                    {
                        entriesInverted.Insert(0, new OrderBookEntry()
                        {
                            ValueString = item.Value <string>("R"), AmountString = item.Value <string>("Q")
                        });
                    }
                }
                entries = orderBook.Bids;
                for (int i = 0; i < jbids.Count; i++)
                {
                    JObject item = (JObject)jbids[i];
                    entries.Add(new OrderBookEntry()
                    {
                        ValueString = item.Value <string>("R"), AmountString = item.Value <string>("Q")
                    });
                }
            }
            finally {
                ticker.OrderBook.IsDirty = false;
                ticker.OrderBook.EndUpdate();
            }

            ticker.ClearTradeHistory();
            JArray jtrades = jObject.Value <JArray>("f");

            foreach (JObject item in jtrades)
            {
                TradeInfoItem t = new TradeInfoItem(null, ticker);
                t.AmountString = item.Value <string>("Q");
                t.RateString   = item.Value <string>("P");
                t.Time         = new DateTime(Convert.ToInt64(item.Value <string>("T"))).ToLocalTime();
                t.TimeString   = t.Time.ToLongTimeString();
                t.Type         = (item.Value <string>("OT")) == "BUY" ? TradeType.Buy : TradeType.Sell;
                ticker.AddTradeHistoryItem(t);
            }

            if (ticker.HasTradeHistorySubscribers)
            {
                ticker.RaiseTradeHistoryChanged(new TradeHistoryChangedEventArgs()
                {
                    NewItems = ticker.TradeHistory
                });
            }
        }