public void Deserialize_CheckCorrectOnlyBuy() { var bid = new List <KeyValuePair <Price, Quantity> >() { new KeyValuePair <Price, Quantity>(9, 10), new KeyValuePair <Price, Quantity>(8, 9) }; var ask = new List <KeyValuePair <Price, Quantity> >() { }; var book = new BookDepth(3, 11000, bid, ask); Span <byte> bytes = stackalloc byte[95]; BookSerializer.Serialize(book, bytes); var messageLength = BitConverter.ToInt32(bytes.Slice(0)); Assert.Equal(95, messageLength); var bookDepth = BookSerializer.Deserialize(bytes); Assert.Equal(11000, bookDepth.LTP); Assert.Equal(2, bookDepth.Bid.Count); Assert.Empty(bookDepth.Ask); Assert.Equal(9, bookDepth.Bid[0].Key); Assert.Equal(10, bookDepth.Bid[0].Value); Assert.Equal(8, bookDepth.Bid[1].Key); Assert.Equal(9, bookDepth.Bid[1].Value); }
public static BookDepth Deserialize(ReadOnlySpan <byte> bytes) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } if (bytes.Length < minMessageSize) { throw new Exception("Book Message must be greater than of Size : " + minMessageSize); } var messageType = (MessageType)(bytes[messageTypeOffset]); if (messageType != MessageType.Book) { throw new Exception(Constant.INVALID_MESSAGE); } var version = BitConverter.ToInt16(bytes.Slice(versionOffset)); if (version != BookSerializer.version) { throw new Exception(Constant.INVALID_VERSION); } var timeStamp = BitConverter.ToInt32(bytes.Slice(timeStampOffset)); Price?ltp = ReadPrice(bytes.Slice(ltpOffset)); if (ltp == 0) { ltp = null; } var bidCount = BitConverter.ToInt16(bytes.Slice(bidCountOffset)); var askCount = BitConverter.ToInt16(bytes.Slice(askCountOffset)); List <KeyValuePair <Price, Quantity> > bid = new List <KeyValuePair <Price, Quantity> >(bidCount); List <KeyValuePair <Price, Quantity> > ask = new List <KeyValuePair <Price, Quantity> >(askCount); for (int i = 0; i < bidCount; i++) { var price = ReadPrice(bytes.Slice(bidStartOffset + (i * sizeOfLevel))); var quantity = ReadQuantity(bytes.Slice(bidStartOffset + (i * sizeOfLevel) + sizeOfPrice)); bid.Add(new KeyValuePair <Price, Quantity>(price, quantity)); } var askStartOffset = bidStartOffset + (bidCount * sizeOfLevel); for (int i = 0; i < askCount; i++) { var price = ReadPrice(bytes.Slice(askStartOffset + (i * sizeOfLevel))); var quantity = ReadQuantity(bytes.Slice(askStartOffset + (i * sizeOfLevel) + sizeOfPrice)); ask.Add(new KeyValuePair <Price, Quantity>(price, quantity)); } var book = new BookDepth(timeStamp, ltp, bid, ask); return(book); }
public void Deserialize_CheckCorrectBidCountAskFullBook() { var bid = new List <KeyValuePair <Price, Quantity> >() { new KeyValuePair <Price, Quantity>(10, 1), new KeyValuePair <Price, Quantity>(9, 2), new KeyValuePair <Price, Quantity>(8, 3), new KeyValuePair <Price, Quantity>(7, 4), new KeyValuePair <Price, Quantity>(6, 5) }; var ask = new List <KeyValuePair <Price, Quantity> >() { new KeyValuePair <Price, Quantity>(11, 11), new KeyValuePair <Price, Quantity>(12, 12), new KeyValuePair <Price, Quantity>(13, 13), new KeyValuePair <Price, Quantity>(14, 14), new KeyValuePair <Price, Quantity>(15, 15) }; var book = new BookDepth(3, 10, bid, ask); Span <byte> bytes = stackalloc byte[351]; BookSerializer.Serialize(book, bytes); var messageLength = BitConverter.ToInt32(bytes.Slice(0)); Assert.Equal(351, messageLength); var bookDepth = BookSerializer.Deserialize(bytes); Assert.Equal(10, bookDepth.LTP); Assert.Equal(5, bookDepth.Bid.Count); Assert.Equal(10, bookDepth.Bid[0].Key); Assert.Equal(1, bookDepth.Bid[0].Value); Assert.Equal(9, bookDepth.Bid[1].Key); Assert.Equal(2, bookDepth.Bid[1].Value); Assert.Equal(8, bookDepth.Bid[2].Key); Assert.Equal(3, bookDepth.Bid[2].Value); Assert.Equal(7, bookDepth.Bid[3].Key); Assert.Equal(4, bookDepth.Bid[3].Value); Assert.Equal(6, bookDepth.Bid[4].Key); Assert.Equal(5, bookDepth.Bid[4].Value); Assert.Equal(11, bookDepth.Ask[0].Key); Assert.Equal(11, bookDepth.Ask[0].Value); Assert.Equal(12, bookDepth.Ask[1].Key); Assert.Equal(12, bookDepth.Ask[1].Value); Assert.Equal(13, bookDepth.Ask[2].Key); Assert.Equal(13, bookDepth.Ask[2].Value); Assert.Equal(14, bookDepth.Ask[3].Key); Assert.Equal(14, bookDepth.Ask[3].Value); Assert.Equal(15, bookDepth.Ask[4].Key); Assert.Equal(15, bookDepth.Ask[4].Value); }
public static void Serialize(BookDepth book, Span <byte> bytes) { if (book == null) { throw new ArgumentNullException(nameof(book)); } if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } var sizeOfMessage = GetMessageSize(book); if (bytes.Length != sizeOfMessage) { throw new ArgumentException(Constant.INVALID_SIZE, nameof(book)); } Write(bytes.Slice(messageLengthOffset), sizeOfMessage); bytes[messageTypeOffset] = (byte)MessageType.Book; Write(bytes.Slice(versionOffset), version); Write(bytes.Slice(timeStampOffset), book.TimeStamp); Write(bytes.Slice(ltpOffset), book.LTP ?? 0); Write(bytes.Slice(bidCountOffset), (short)book.Bid.Count); Write(bytes.Slice(askCountOffset), (short)book.Ask.Count); int i = 0; foreach (var level in book.Bid) { var start = bidStartOffset + (i * sizeOfLevel); Write(bytes.Slice(start), level.Key); Write(bytes.Slice(start + sizeOfPrice), level.Value); if (++i == book.Bid.Count) { break; } } i = 0; foreach (var level in book.Ask) { var start = bidStartOffset + (book.Bid.Count * sizeOfLevel) + (i * sizeOfLevel); Write(bytes.Slice(start), level.Key); Write(bytes.Slice(start + sizeOfPrice), level.Value); if (++i == book.Ask.Count) { break; } } }
public void Serialize_Doesnotthrowexception_EmptyBook() { var bid = new List <KeyValuePair <Price, Quantity> >() { }; var ask = new List <KeyValuePair <Price, Quantity> >() { }; var book = new BookDepth(3, 10, bid, ask); Span <byte> bytes = stackalloc byte[31]; BookSerializer.Serialize(book, bytes); }
public static int GetMessageSize(BookDepth book) { if (book == null) { throw new ArgumentNullException(nameof(book)); } var bidCount = (short)(book.Bid.Count); var askCount = (short)(book.Ask.Count); var sizeOfMessage = sizeOfMessageLength + sizeOfMessageType + sizeOfVersion + sizeOfTimeStamp + Price.SizeOfPrice + sizeOfAskCount + sizeOfBidCount + (sizeOfLevel * (bidCount + askCount)); return(sizeOfMessage); }
public void Serialize_Doesnotthrowexception_OnlyAskOrder() { var ask = new List <KeyValuePair <Price, Quantity> >() { new KeyValuePair <Price, Quantity>(10, 20) }; var bid = new List <KeyValuePair <Price, Quantity> >() { }; var book = new BookDepth(10, 10, bid, ask); Span <byte> bytes = stackalloc byte[63]; BookSerializer.Serialize(book, bytes); }
public void Deserialize_CheckCorrectBidCountAskCountForEmpty() { var bid = new List <KeyValuePair <Price, Quantity> >() { }; var ask = new List <KeyValuePair <Price, Quantity> >() { }; var book = new BookDepth(3, 1010, bid, ask);; Span <byte> bytes = stackalloc byte[31]; BookSerializer.Serialize(book, bytes); var messageLength = BitConverter.ToInt32(bytes.Slice(0)); Assert.Equal(31, messageLength); var bookDepth = BookSerializer.Deserialize(bytes); Assert.Equal(1010, bookDepth.LTP); Assert.Equal(3, bookDepth.TimeStamp); Assert.Empty(bookDepth.Bid); Assert.Empty(bookDepth.Ask); }
public void Deserialize_CheckCorrectOnlyAsk() { var bid = new List <KeyValuePair <Price, Quantity> >() { }; var ask = new List <KeyValuePair <Price, Quantity> >() { new KeyValuePair <Price, Quantity>(10, 10) }; var book = new BookDepth(3, 11000, bid, ask); Span <byte> bytes = stackalloc byte[63]; BookSerializer.Serialize(book, bytes); var messageLength = BitConverter.ToInt32(bytes.Slice(0)); Assert.Equal(63, messageLength); var bookDepth = BookSerializer.Deserialize(bytes); Assert.Equal(11000, bookDepth.LTP); Assert.Empty(bookDepth.Bid); Assert.Single(bookDepth.Ask); Assert.Equal(10, bookDepth.Ask[0].Key); Assert.Equal(10, bookDepth.Ask[0].Value); }
public WebsocketClient(Network network) { var networkEnv = BinanceEnvironment.GetEnvironment(network); _ws = new WebSocket(networkEnv.WssApiAddress); _ws.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12; _ws.EmitOnPing = true; _ws.OnMessage += _ws_OnMessage; _ws.OnError += _ws_OnError; BlockHeight = new BlockHeight(this); AllMiniTicker = new AllMiniTicker(this); IndividualMiniTicker = new IndividualMiniTicker(this); AllTicker = new AllTicker(this); IndividualTicker = new IndividualTicker(this); Klines = new Klines(this); BookDepth = new BookDepth(this); DiffDepth = new DiffDepth(this); Trades = new Trades(this); Transfer = new Transfer(this); Account = new Account(this); Orders = new Orders(this); }
private void _ws_OnMessage(object sender, MessageEventArgs e) { //Pre-parsing message. Doesn't fully deserialize now to dynamic to improve performance if (e.Data.StartsWith("{\"stream\":\"orders\"")) { Orders.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"trades\"")) { Trades.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"accounts\"")) { Account.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"marketDiff\"")) { DiffDepth.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"marketDepth\"")) { BookDepth.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"blockheight\"")) { BlockHeight.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"allMiniTickers\"")) { AllMiniTicker.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"miniTicker\"")) { IndividualMiniTicker.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"allTickers\"")) { AllTicker.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"ticker\"")) { IndividualTicker.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"kline_")) { Klines.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"transfers\"")) { Transfer.ProcessRecievedMessage(e.Data); } else if (e.Data.StartsWith("{\"stream\":\"transfers\"")) { Transfer.ProcessRecievedMessage(e.Data); } else if (!string.IsNullOrWhiteSpace(e.Data)) { //We might received an error text from backend, have to raise attention if so. if (e.Data.Contains("error")) { throw new WebSocketConnectionException(string.Format("Websocket DEX backend sent error message: {0}", e.Data)); } } }
public SerializeBenchmark() { book = new Book(); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = true, OpenQuantity = 1000, OrderId = 3434, Price = 234 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = true, OpenQuantity = 1000, OrderId = 3434, Price = 235 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = true, OpenQuantity = 1000, OrderId = 3435, Price = 236 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = true, OpenQuantity = 1000, OrderId = 3436, Price = 237 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = true, OpenQuantity = 1000, OrderId = 3437, Price = 238 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = false, OpenQuantity = 1000, OrderId = 3438, Price = 239 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = false, OpenQuantity = 1000, OrderId = 3439, Price = 240 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = false, OpenQuantity = 1000, OrderId = 3440, Price = 241 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = false, OpenQuantity = 1000, OrderId = 3441, Price = 242 }); book.AddOrderOpenBook(new Order { CancelOn = 1000, IsBuy = false, OpenQuantity = 1000, OrderId = 3442, Price = 243 }); bid = book.BidSide.Select(x => new KeyValuePair <Price, Quantity>(x.Key, x.Value.Quantity)).ToList(); ask = book.AskSide.Select(x => new KeyValuePair <Price, Quantity>(x.Key, x.Value.Quantity)).ToList(); var order = new Order() { CancelOn = 12345678, IsBuy = true, OrderId = 56789, Price = 404, OpenQuantity = 1000, OrderCondition = OrderCondition.ImmediateOrCancel, StopPrice = 9534, TotalQuantity = 7878234 }; orderJsonString = JsonConvert.SerializeObject(order); orderBinarySerialized = new byte[OrderSerializer.MessageSize]; OrderSerializer.Serialize(order, orderBinarySerialized); orderMsgPck = MessagePackSerializer.Serialize(new Order2 { IsBuy = true, IsTip = false, OpenQuantity = 100, OrderId = 1001, Price = 400, Quantity = 100, Sequnce = 0, StopPrice = 0 }); fillJsonString = JsonConvert.SerializeObject(new Fill { MakerOrderId = 10001, MatchQuantity = 2000, MatchRate = 2400, TakerOrderId = 9999, Timestamp = 10303 }); fillBinary = new byte[FillSerializer.MessageSize]; FillSerializer.Serialize(new Fill { MakerOrderId = 10001, MatchQuantity = 2000, MatchRate = 2400, TakerOrderId = 9999, Timestamp = 10303 }, fillBinary); cancelJsonString = JsonConvert.SerializeObject(new CancelledOrder { OrderId = 1201, CancelReason = CancelReason.UserRequested, RemainingQuantity = 2000, Timestamp = 234 }); cancelBinary = new byte[CancelledOrderSerializer.MessageSize]; CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = 1201, CancelReason = CancelReason.UserRequested, RemainingQuantity = 2000, Timestamp = 234 }, cancelBinary); cancelRequestJsonString = JsonConvert.SerializeObject(new CancelRequest { OrderId = 1023 }); cancelRequestBinary = new byte[CancelRequestSerializer.MessageSize]; CancelRequestSerializer.Serialize(new CancelRequest { OrderId = 1023 }, cancelRequestBinary); orderTriggerBinary = new byte[OrderTriggerSerializer.MessageSize]; OrderTriggerSerializer.Serialize(new OrderTrigger { OrderId = 3453, Timestamp = 35345 }, orderTriggerBinary); orderTriggerJsonString = JsonConvert.SerializeObject(new OrderTrigger { OrderId = 3453, Timestamp = 35345 }); bookRequestBinary = new byte[BookRequestSerializer.MessageSize]; BookRequestSerializer.Serialize(new BookRequest { }, bookRequestBinary); bookRequestJsonString = JsonConvert.SerializeObject(new BookRequest { }); bookRequest2Bytes = MessagePackSerializer.Serialize(new BookRequest2 { }); bookDepth = new BookDepth(1234, 100, bid, ask); bookJsonString = JsonConvert.SerializeObject(bookDepth); bookBinary = new byte[OrderSerializer.MessageSize]; BookSerializer.Serialize(bookDepth, bookBinary); fill = new Fill { MakerOrderId = 10001, MatchQuantity = 2000, MatchRate = 2400, TakerOrderId = 9999, Timestamp = 10303 }; order2 = new Order2 { IsBuy = true, IsTip = false, OpenQuantity = 100, OrderId = 1001, Price = 400, Quantity = 100, Sequnce = 0, StopPrice = 0 }; this.order = new Order { IsBuy = true, OpenQuantity = 100, OrderId = 1001, Price = 400, Sequnce = 0, TotalQuantity = 100, OrderCondition = OrderCondition.None, StopPrice = 0 }; cancelledOrder = new CancelledOrder { OrderId = 1201, CancelReason = CancelReason.UserRequested, RemainingQuantity = 2000, Timestamp = 234 }; cancelRequest = new CancelRequest { OrderId = 1023 }; orderTrigger = new OrderTrigger { OrderId = 3453, Timestamp = 35345 }; bookRequest = new BookRequest { LevelCount = 50 }; bookRequest2 = new BookRequest2 { LevelCount = 50 }; }