protected override void DoRunLoopSubscriptions(string resp) { WebSocketSubscriptionEvent eventSubscr = JsonConvert.DeserializeObject <WebSocketSubscriptionEvent>(resp); if (ResponseRequestSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { if (eventSubscr.table == _ORDER && EventSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { WebSocketExecutionReportEvent execReportEvent = JsonConvert.DeserializeObject <WebSocketExecutionReportEvent>(resp); WebSocketSubscriptionEvent subscrEvent = EventSubscriptions[eventSubscr.GetSubscriptionEvent()]; subscrEvent.RunEvent(execReportEvent); } else if (eventSubscr.table == _EXECUTIONS && EventSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { WebSocketExecutionReportEvent execReportEvent = JsonConvert.DeserializeObject <WebSocketExecutionReportEvent>(resp); WebSocketSubscriptionEvent subscrEvent = EventSubscriptions[eventSubscr.GetSubscriptionEvent()]; subscrEvent.RunEvent(execReportEvent); } else { //Log what we are receiving here because we are getting events that we didn't expect } } }
protected void ProcessExecutionReports(WebSocketSubscriptionEvent subscrEvent) { WebSocketExecutionReportEvent reports = (WebSocketExecutionReportEvent)subscrEvent; foreach (zHFT.OrderRouters.Bitmex.Common.DTO.ExecutionReport execReportDTO in reports.data) { try { string clOrdId = ""; if (OrderIdMappers.ContainsKey(execReportDTO.OrderID)) { clOrdId = OrderIdMappers[execReportDTO.OrderID]; if (BitMexActiveOrders.ContainsKey(clOrdId)) { Order order = BitMexActiveOrders[clOrdId]; lock (tLock) { if (execReportDTO.ExecType == ExecType.New.ToString()) { order.OrderId = execReportDTO.OrderID; } if (execReportDTO.ExecType == ExecType.Replaced.ToString()) { BitMexActiveOrders.Remove(clOrdId); order.ClOrdId = order.PendingClOrdId; order.PendingClOrdId = null; BitMexActiveOrders.Add(order.ClOrdId, order); OrderIdMappers[execReportDTO.OrderID] = order.ClOrdId; } if (execReportDTO.ExecType == ExecType.Canceled.ToString() || execReportDTO.ExecType == ExecType.Stopped.ToString() || execReportDTO.ExecType == ExecType.Rejected.ToString() || execReportDTO.ExecType == ExecType.Suspended.ToString() || execReportDTO.ExecType == ExecType.Expired.ToString()) { BitMexActiveOrders.Remove(order.ClOrdId); OrderIdMappers.Remove(order.OrderId); } } WSExecutionReportWrapper wrapper = new WSExecutionReportWrapper(execReportDTO, order); OnMessageRcv(wrapper); } } else { DoLog(string.Format("Unknown order processing execution report for OrderId {0} ", execReportDTO.OrderID), Main.Common.Util.Constants.MessageType.Information); } } catch (Exception ex) { DoLog(string.Format("Error processing execution report for ClOrdId {0}:{1} ", execReportDTO.ClOrdID, ex.Message), Main.Common.Util.Constants.MessageType.Error); } } }
//We update an orderBook in memory and publish protected void UpdateOrderBook(WebSocketSubscriptionEvent subscrEvent) { if (subscrEvent is WebSocketErrorMessage) { ProcessSubscrError((WebSocketErrorMessage)subscrEvent); return; } WebSocketOrderBookL2Event orderBookEvent = (WebSocketOrderBookL2Event)subscrEvent; try { zHFT.InstructionBasedMarketClient.BitMex.Common.DTO.OrderBookEntry[] bids = orderBookEvent.data.Where(x => x.IsBuy()).OrderByDescending(x => x.price).ToArray(); zHFT.InstructionBasedMarketClient.BitMex.Common.DTO.OrderBookEntry[] asks = orderBookEvent.data.Where(x => x.IsSell()).OrderBy(x => x.price).ToArray(); SendOrderBookEntries(orderBookEvent.action, bids, asks); OrderBookHandler.DoUpdateOrderBooks(orderBookEvent.action, bids, asks); //string symbol = ""; //if (bids.Length > 0) // symbol = bids[0].symbol; //else if (asks.Length > 0) // symbol = asks[0].symbol; //else // return; //if (ActiveSecuritiesQuotes.Values.Any(x => x.Symbol == symbol) && OrderBookHandler.OrderBooks.ContainsKey(symbol)) //{ // Security sec = ActiveSecuritiesQuotes.Values.Where(x => x.Symbol == symbol).FirstOrDefault(); // OrderBookDictionary dict = OrderBookHandler.OrderBooks[symbol]; // zHFT.InstructionBasedMarketClient.BitMex.Common.DTO.OrderBookEntry bestBid = dict.Entries.Values.Where(x => x.IsBuy() && x.size > 0).OrderByDescending(x => x.price).FirstOrDefault(); // zHFT.InstructionBasedMarketClient.BitMex.Common.DTO.OrderBookEntry bestAsk = dict.Entries.Values.Where(x => x.IsSell() && x.size > 0).OrderBy(x => x.price).FirstOrDefault(); // sec.MarketData.BestBidPrice = Convert.ToDouble(bestBid.price); // sec.MarketData.BestBidSize = Convert.ToInt64(bestBid.size); // sec.MarketData.BestAskPrice = Convert.ToDouble(bestAsk.price); // sec.MarketData.BestAskSize = Convert.ToInt64(bestAsk.size); // //DoLog(string.Format("@{5}:Publishing Market Data for symbol {0}: Best Bid Size={1} Best Bid Price={2} Best Ask Size={3} Best Ask Price={4}", // // symbol, bestBid.size.ToString("##.########"), bestBid.price.ToString("##.##"), // // bestAsk.size.ToString("##.########"), bestAsk.price.ToString("##.##"), // // BitmexConfiguration.Name), Main.Common.Util.Constants.MessageType.Information); // MarketDataWrapper wrapper = new MarketDataWrapper(sec, GetConfig()); // OnMessageRcv(wrapper); //} } catch (Exception ex) { DoLog(string.Format("@{0}:Error processing order book :{1}", BitmexConfiguration.Name, ex.Message), Main.Common.Util.Constants.MessageType.Error); } }
public void OnEvent(string resp) { WebSocketResponseMessage wsResp = wsResp = JsonConvert.DeserializeObject <WebSocketResponseMessage>(resp); lock (tSubscrLock) { if (wsResp.IsResponse())//We have the response to a subscription { WebSocketSubscriptionResponse requestRespSubscr = JsonConvert.DeserializeObject <WebSocketSubscriptionResponse>(resp); if (ResponseRequestSubscriptions.ContainsKey(requestRespSubscr.GetSubscriptionEvent())) { WebSocketSubscriptionResponse requestRespEvent = ResponseRequestSubscriptions[requestRespSubscr.GetSubscriptionEvent()]; requestRespEvent.RunSubscritionEvent(requestRespSubscr); } } else if (resp.Contains("error")) { WebSocketErrorMessage wsError = JsonConvert.DeserializeObject <WebSocketErrorMessage>(resp); if (wsError.request != null) { foreach (string ev in wsError.request.args) { string[] fields = ev.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries); string key = fields[0]; string symbol = fields.Length > 1 ? fields[1] : null; WebSocketSubscriptionEvent subscrEvent = EventSubscriptions[key]; if (subscrEvent != null) { wsError.Symbol = symbol; subscrEvent.RunEvent(wsError); } } } else { ProcessSubscriptionEvent(resp); } } else //We have an event from a subscription { ProcessSubscriptionEvent(resp); } } }
public void SubscribeEvents(string topic, OnEvent pOnSubscriptionEvent) { WebSocketSubscriptionEvent msg = new WebSocketSubscriptionEvent() { topic = topic, }; msg.SetEvent(pOnSubscriptionEvent); if (EventSubscriptions == null) { throw new Exception(string.Format("Event Subscriptions Dictionary has not been initialized")); } EventSubscriptions.Add(topic, msg); }
protected override void DoRunLoopSubscriptions(string resp) { WebSocketSubscriptionEvent eventSubscr = JsonConvert.DeserializeObject <WebSocketSubscriptionEvent>(resp); if (ResponseRequestSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { if (eventSubscr.table == _ORDERBOOK_L2 && EventSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { WebSocketOrderBookL2Event orderBookL2Event = JsonConvert.DeserializeObject <WebSocketOrderBookL2Event>(resp); WebSocketSubscriptionEvent subscrEvent = EventSubscriptions[eventSubscr.GetSubscriptionEvent()]; subscrEvent.RunEvent(orderBookL2Event); } else if (eventSubscr.table == _TRADE && EventSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { WebSocketTradeEvent tradeEvent = JsonConvert.DeserializeObject <WebSocketTradeEvent>(resp); WebSocketSubscriptionEvent subscrEvent = EventSubscriptions[eventSubscr.GetSubscriptionEvent()]; subscrEvent.RunEvent(tradeEvent); } else if (eventSubscr.table == _QUOTE && EventSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { WebSocketQuoteEvent quoteEvent = JsonConvert.DeserializeObject <WebSocketQuoteEvent>(resp); WebSocketSubscriptionEvent subscrEvent = EventSubscriptions[eventSubscr.GetSubscriptionEvent()]; subscrEvent.RunEvent(quoteEvent); } else if (eventSubscr.table == _1_DAY_TRADE_BINS && EventSubscriptions.ContainsKey(eventSubscr.GetSubscriptionEvent())) { //TODO: I have to ask BitMex why aren't they retrieveing high and low for the 1 day bin //and they are for the 1 hour bin } else { //Log what we are receiving here because we are getting events that we didn't expect } } }
protected void UpdateTrade(WebSocketSubscriptionEvent subscrEvent) { if (subscrEvent is WebSocketErrorMessage) { ProcessSubscrError((WebSocketErrorMessage)subscrEvent); return; } WebSocketTradeEvent trades = (WebSocketTradeEvent)subscrEvent; foreach (zHFT.InstructionBasedMarketClient.BitMex.Common.DTO.Trade trade in trades.data.OrderBy(x => x.timestamp)) { try { if (ActiveSecuritiesQuotes.Values.Where(x => x.Symbol == trade.symbol).FirstOrDefault() != null) { Security sec = ActiveSecuritiesQuotes.Values.Where(x => x.Symbol == trade.symbol).FirstOrDefault(); sec.MarketData.Trade = Convert.ToDouble(trade.price); sec.MarketData.MDTradeSize = Convert.ToDouble(trade.size); sec.MarketData.LastTradeDateTime = trade.timestamp; sec.ProcessStatistics(); DoLog(string.Format("@{5}:NEW TRADE for symbol {0}: Side={1} Size={2} Price={3} TickDirection={4}", trade.symbol, trade.side, trade.size.ToString("##.##"), trade.price.ToString("##.########"), trade.tickDirection, BitmexConfiguration.Name), Main.Common.Util.Constants.MessageType.Information); MarketDataTradesWrapper wrapper = new MarketDataTradesWrapper(sec, GetConfig()); OnMessageRcv(wrapper); } } catch (Exception ex) { DoLog(string.Format("@{0}:Error processing trade for symbol {1}:{2}", BitmexConfiguration.Name, trade.symbol, ex.Message), Main.Common.Util.Constants.MessageType.Error); } } }
protected void UpdateQuotes(WebSocketSubscriptionEvent subscrEvent) { if (subscrEvent is WebSocketErrorMessage) { ProcessSubscrError((WebSocketErrorMessage)subscrEvent); return; } WebSocketQuoteEvent quotes = (WebSocketQuoteEvent)subscrEvent; foreach (Quote quote in quotes.data.OrderBy(x => x.timestamp)) { try { if (ActiveSecuritiesQuotes.Values.Where(x => x.Symbol == quote.symbol).FirstOrDefault() != null) { Security sec = ActiveSecuritiesQuotes.Values.Where(x => x.Symbol == quote.symbol).FirstOrDefault(); sec.MarketData.BestAskSize = quote.askSize.HasValue ? (long?)Convert.ToInt64(quote.askSize.Value) : null; sec.MarketData.BestBidSize = quote.bidSize.HasValue ? (long?)Convert.ToInt64(quote.bidSize.Value) : null; sec.MarketData.BestAskPrice = quote.askPrice; sec.MarketData.BestBidPrice = quote.bidPrice; DoLog(string.Format("@{1}:NEW Quote for symbol {0}", quote.symbol, BitmexConfiguration.Name), Main.Common.Util.Constants.MessageType.Information); MarketDataQuoteWrapper wrapper = new MarketDataQuoteWrapper(sec, GetConfig()); OnMessageRcv(wrapper); } } catch (Exception ex) { DoLog(string.Format("@{0}:Error processing quote for symbol {1}:{2}", BitmexConfiguration.Name, quote.symbol, ex.Message), Main.Common.Util.Constants.MessageType.Error); } } }