Я использую GDAX API Websocket Stream, чтобы попытаться создать копию из полной книги заказов LEVEL3.
У меня есть очень простая реализация с использованием WebSocketSharp, и я в основном делаю что-то вроде этого.
private readonly WebSocket _webSocket = new WebSocket("wss://ws-feed.gdax.com");
_webSocket.OnMessage += WebSocket_OnMessage;
_webSocket.Connect();
_webSocket.Send(JsonConvert.SerializeObject(new BeginSubscriptionMessage()));
private void WebSocket_OnMessage(object sender, MessageEventArgs e)
{
var message = JsonConvert.DeserializeObject<BaseMessage>(e.Data);
switch (message.Type)
{
case "match": //A trade occurred between two orders.
MatchMessage matchMessage = JsonConvert.DeserializeObject<MatchMessage>(e.Data);
_receivedMatchQueue.Enqueue(matchMessage);
break;
case "received": //A valid order has been received and is now active. This message is emitted for every single valid order as soon as the matching engine receives it whether it fills immediately or not.
ReceivedMessage receivedMessage = JsonConvert.DeserializeObject<ReceivedMessage>(e.Data);
_receivedMessageQueue.Enqueue(receivedMessage);
break;
case "open": //The order is now open on the order book. This message will only be sent for orders which are not fully filled immediately. remaining_size will indicate how much of the order is unfilled and going on the book.
OpenMessage openMessage = JsonConvert.DeserializeObject<OpenMessage>(e.Data);
_receivedOpenQueue.Enqueue(openMessage);
break;
case "done": //The order is no longer on the order book. Sent for all orders for which there was a received message. This message can result from an order being canceled or filled.
DoneMessage doneMessage = JsonConvert.DeserializeObject<DoneMessage>(e.Data);
_receivedDoneQueue.Enqueue(doneMessage);
break;
case "change": //Existing order has been changed
ChangeMessage changeMessage = JsonConvert.DeserializeObject<ChangeMessage>(e.Data);
_receivedChangeQueue.Enqueue(changeMessage);
break;
case "activate": //Stop order placed
//Console.WriteLine("Stop Order Placed");
//ActivateMessage activateMessage = JsonConvert.DeserializeObject<ActivateMessage>(e.Data);
break;
case "subscriptions":
break;
case "ticker":
TickerMessage tickerMessage = JsonConvert.DeserializeObject<TickerMessage>(e.Data);
_receivedTickerQueue.Enqueue(tickerMessage);
break;
case "l2update":
break;
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что когда я смотрю на порядковые номера, полученные через сообщения RECEIVED и OPEN, я вижу, что они не являются последовательными (на основе следующей информации) предполагает, что сообщения пропускаются.
В основном вы получаете что-то вроде этого
Open Message SequenceId: 5359746354
Open Message SequenceId: 5359746358
Open Message SequenceId: 5359746361
Open Message SequenceId: 5359746363
Open Message SequenceId: 5359746365
Open Message SequenceId: 5359746370
Open Message SequenceId: 5359746372
Я попытался протестировать это на Azure, просто чтобы убедиться, что это не было ограничением пропускной способности с моей стороны, и результаты были в основном схожими.
Итак, учитывая это, как можно создать полную книгу заказов «в реальном времени», используя «полный» поток веб-сокетов, если сообщения будут удалены? Могу ли я просто безопасно игнорировать их? Или мне просто как-то очистить потерянные значения?
Любые советы от тех, кто делал что-то подобное, будут очень признательны.