/// <summary> /// Deserialize JSON and raise <see cref="DepthUpdateEventArgs"/> event. /// </summary> /// <param name="json"></param> /// <param name="token"></param> /// <param name="callback"></param> protected override void DeserializeJsonAndRaiseEvent(string json, CancellationToken token, Action <DepthUpdateEventArgs> callback = null) { Throw.IfNullOrWhiteSpace(json, nameof(json)); Logger?.LogDebug($"{nameof(DepthWebSocketClient)}: \"{json}\""); try { var jObject = JObject.Parse(json); var eventType = jObject["e"]?.Value <string>(); DepthUpdateEventArgs eventArgs = null; if (eventType == null) // partial order book stream. { // Simulate event time. var eventTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var lastUpdateId = jObject["lastUpdateId"].Value <long>(); var bids = jObject["bids"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList(); var asks = jObject["asks"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList(); eventArgs = new DepthUpdateEventArgs(eventTime, token, Symbol, lastUpdateId, lastUpdateId, bids, asks); } else if (eventType == "depthUpdate") { var symbol = jObject["s"].Value <string>(); var eventTime = jObject["E"].Value <long>(); var firstUpdateId = jObject["U"].Value <long>(); var lastUpdateId = jObject["u"].Value <long>(); var bids = jObject["b"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList(); var asks = jObject["a"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList(); eventArgs = new DepthUpdateEventArgs(eventTime, token, symbol, firstUpdateId, lastUpdateId, bids, asks); } else { Logger?.LogWarning($"{nameof(DepthWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}: Unexpected event type ({eventType})."); return; } try { callback?.Invoke(eventArgs); DepthUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(DepthWebSocketClient)}: Unhandled depth update event handler exception."); } } } catch (OperationCanceledException) { } catch (Exception e) { if (!token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(DepthWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}"); } } }
protected override void OnWebSocketEvent(WebSocketStreamEventArgs args, IEnumerable <Action <DepthUpdateEventArgs> > callbacks) { Logger?.LogDebug($"{nameof(DepthWebSocketClient)}: \"{args.Json}\""); try { var jObject = JObject.Parse(args.Json); var eventType = jObject["e"]?.Value <string>(); DepthUpdateEventArgs eventArgs; switch (eventType) { case null: // partial depth stream. { var symbol = args.StreamName.Split('@')[0].ToUpperInvariant(); // Simulate event time. var eventTime = DateTime.UtcNow.ToTimestampK().ToDateTimeK(); var lastUpdateId = jObject["lastUpdateId"].Value <long>(); var bids = jObject["bids"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); var asks = jObject["asks"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); eventArgs = new DepthUpdateEventArgs(eventTime, args.Token, symbol, lastUpdateId, lastUpdateId, bids, asks); break; } case "depthUpdate": { var symbol = jObject["s"].Value <string>(); var eventTime = jObject["E"].Value <long>().ToDateTimeK(); var firstUpdateId = jObject["U"].Value <long>(); var lastUpdateId = jObject["u"].Value <long>(); var bids = jObject["b"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); var asks = jObject["a"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); eventArgs = new DepthUpdateEventArgs(eventTime, args.Token, symbol, firstUpdateId, lastUpdateId, bids, asks); break; } default: Logger?.LogWarning($"{nameof(DepthWebSocketClient)}.{nameof(OnWebSocketEvent)}: Unexpected event type ({eventType})."); return; } try { if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } DepthUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!args.Token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(DepthWebSocketClient)}: Unhandled depth update event handler exception."); } } } catch (OperationCanceledException) { } catch (Exception e) { if (!args.Token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(DepthWebSocketClient)}.{nameof(OnWebSocketEvent)}"); } } }
protected override void HandleMessage(IEnumerable <Action <DepthUpdateEventArgs> > callbacks, string stream, string json) { try { var jObject = JObject.Parse(json); var eventType = jObject["e"]?.Value <string>(); DepthUpdateEventArgs eventArgs; switch (eventType) { case null: // partial depth stream. { var symbol = stream.Split('@')[0].ToUpperInvariant(); // Simulate event time. var eventTime = DateTime.UtcNow.ToTimestamp().ToDateTime(); var lastUpdateId = jObject["lastUpdateId"].Value <long>(); var bids = jObject["bids"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); var asks = jObject["asks"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); eventArgs = new DepthUpdateEventArgs(eventTime, symbol, lastUpdateId, lastUpdateId, bids, asks); break; } case "depthUpdate": { var symbol = jObject["s"].Value <string>(); var eventTime = jObject["E"].Value <long>().ToDateTime(); var firstUpdateId = jObject["U"].Value <long>(); var lastUpdateId = jObject["u"].Value <long>(); var bids = jObject["b"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); var asks = jObject["a"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToArray(); eventArgs = new DepthUpdateEventArgs(eventTime, symbol, firstUpdateId, lastUpdateId, bids, asks); break; } default: Logger?.LogWarning($"{nameof(DepthClient)}.{nameof(HandleMessage)}: Unexpected event type ({eventType})."); return; } try { if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } DepthUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { /* ignore */ } catch (Exception e) { Logger?.LogWarning(e, $"{nameof(DepthClient)}.{nameof(HandleMessage)}: Unhandled depth update event handler exception."); } } catch (OperationCanceledException) { /* ignore */ } catch (Exception e) { Logger?.LogError(e, $"{nameof(DepthClient)}.{nameof(HandleMessage)}"); } }
void exchangeConnection_GoxDepthHandlers(DepthUpdate depthUpdate) { try { if (depthUpdate.Currency != Currency.USD) { return; } if (depthUpdate.Volume <= 0) { return; } int idOrderType; if (depthUpdate.TypeString == "ask") { if (depthUpdate.Price > (double)(2 * m_decLastPrice)) { return; } if (depthUpdate.Volume < (double)0.02) { return; } idOrderType = 2; lblAsk.Invoke((Action)(() => { lblAsk.Text = depthUpdate.Price.ToString(); })); } else { if (depthUpdate.Price < (double)(0.5 * (double)m_decLastPrice)) { return; } if (depthUpdate.Volume < (double)0.02) { return; } idOrderType = 1; lblBid.Invoke((Action)(() => { lblBid.Text = depthUpdate.Price.ToString(); })); } lblLastResultOrder.Invoke((Action)(() => { lblLastResultOrder.Text = System.DateTime.Now.ToString("M/dd/yyyy hh:mm:ss tt"); })); Decimal decPrice = Convert.ToDecimal(depthUpdate.Price); Decimal decVolume = Convert.ToDecimal(depthUpdate.Volume); RecordBidAsk(decPrice, decVolume, idOrderType, depthUpdate.TimeStamp.ToString()); int cBidAsk = Convert.ToInt16(lblBidAskCount.Text.Length == 0 ? "0" : lblBidAskCount.Text); ++cBidAsk; lblBidAskCount.Invoke((Action)(() => { lblBidAskCount.Text = cBidAsk.ToString(); })); lblLastResult.Invoke((Action)(() => { lblLastResult.Text = System.DateTime.Now.ToString("M/dd/yyyy hh:mm:ss tt"); })); } catch (Exception ex) { Logger.Logger.LogException(ex); } }