internal void OnTradeCall(Trade trade) { OnTrade?.Invoke(trade); if (Trades == null) { Trades = new List <Trade>(); } Trades.Add(trade); }
private async Task HandleTransactionEventsAsync(string txHash) { var receipt = await _web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash); if (receipt.Status.Value.IsZero) { return; } var events = receipt.DecodeAllEvents <TransferEvent>(); events = events.Where(e => e.Event.From != e.Event.To).ToList(); if (events.Count < 2) { return; } foreach (var eo in events) { foreach (var ei in events) { if (eo.Event.From == ei.Event.To && eo.Event.To == ei.Event.From && eo.Log.Address != ei.Log.Address) { var trade = await ConstructTradeFromEvents(eo, ei, receipt); if (trade == null) { continue; } var _1stTrader = trade.Token1Holder.Address; var _2ndTrader = trade.Token2Holder.Address; var _1stTraderIsContract = await _blockchainAccessor.IsSmartContractAsync(_1stTrader); var _2ndTraderIsContract = await _blockchainAccessor.IsSmartContractAsync(_2ndTrader); if (_2ndTraderIsContract && _2ndTraderIsContract) { continue; } OnTrade?.Invoke(this, new OnTradeEventArgs() { Trade = trade }); } } } }
private void Process(ReadOnlySpan <char> record) { switch (record[6]) { case 'Q': OnQuote?.Invoke(Quote.Parse(record)); break; case 'T': OnTrade?.Invoke(Trade.Parse(record)); break; } }
internal void OnTradeCall(Trade trade) { OnTrade?.Invoke(trade); // invoke event specific for the transaction string correlationId = trade.Comment; // ignore unknown transactions if (string.IsNullOrWhiteSpace(correlationId)) { return; } #region Totally untested code or handling manual transactions if (!QuikService.Storage.Contains(correlationId)) { correlationId = "manual:" + trade.OrderNum + ":" + correlationId; var fakeTrans = new Transaction() { Comment = correlationId, IsManual = true // TODO map order properties back to transaction // ideally, make C# property names consistent (Lua names are set as JSON.NET properties via an attribute) }; QuikService.Storage.Set <Transaction>(correlationId, fakeTrans); } #endregion Totally untested code or handling manual transactions var tr = QuikService.Storage.Get <Transaction>(trade.Comment); if (tr != null) { lock (tr) { tr.OnTradeCall(trade); // persist transaction with added trade QuikService.Storage.Set(trade.Comment, tr); } } // ignore unknown transactions //Trace.Assert(tr != null, "Transaction must exist in persistent storage until it is completed and all trades messages are recieved"); }
private void ProcessElement(ReadOnlySpan <char> element, out int processedElementLength) { if (element.ToString().Contains("},{")) { Debugger.Break(); } if (element[1] == 'e' && element[2] == 'v' && element[0] == '"' && element[3] == '"') { switch (element[6]) { case 'Q': Quote q = ProcessQuote(element, out processedElementLength); OnQuote?.Invoke(q); return; case 'T': Trade t = ProcessTrade(element, out processedElementLength); OnTrade?.Invoke(t); return; case 's': string status = "status"; if (element.Slice(6, status.Length).SequenceEqual(status)) { OnStatus?.Invoke(element.ToString()); processedElementLength = element.IndexOf('}'); return; } break; } } OnUnknown?.Invoke(element.ToString()); processedElementLength = element.IndexOf('}'); }
private void StartReceiving(ClientWebSocket webSocket) { new Thread(async() => { string receivedMessage; WebSocketReceiveResult result; var message = new ArraySegment <byte>(new byte[ReceiveChunkSize]); try { while (webSocket.State == WebSocketState.Open) { receivedMessage = string.Empty; do { result = await webSocket.ReceiveAsync(message, CancellationToken.None); if (result.MessageType == WebSocketMessageType.Close) { Disconnect(webSocket); break; } else { receivedMessage += Encoding.UTF8.GetString(message.Take(result.Count).ToArray()); } }while (!result.EndOfMessage); if (string.IsNullOrEmpty(receivedMessage)) { continue; } var token = JToken.Parse(receivedMessage); var messageKey = token.SelectToken("k").Value <string>(); var messageValueToken = token.SelectToken("v"); switch (messageKey) { case "book": OnMarketBook?.Invoke(this, new EventArgs <MarketBook>() { Data = messageValueToken.ToObject <MarketBook[]>() }); break; case "bookdelta": OnBookDeltaItem?.Invoke(this, new EventArgs <BookDeltaItem>() { Data = messageValueToken.ToObject <BookDeltaItem[]>() }); break; case "trade": OnTrade?.Invoke(this, new EventArgs <Trade>() { Data = messageValueToken.ToObject <Trade[]>() }); break; case "allorders": OnAllOrders?.Invoke(this, new EventArgs <Order>() { Data = messageValueToken.ToObject <Order[]>() }); break; case "order": OnOrder?.Invoke(this, new EventArgs <Order>() { Data = messageValueToken.ToObject <Order[]>() }); break; } } } catch { OnDisconnected?.Invoke(this, new EventArgs()); } finally { webSocket.Dispose(); } }).Start(); }
void OnMessage(TimestampedMsg <WebSocket.IMessageIn> msg) { Condition.Requires(msg, "msg").IsNotNull(); Condition.Requires(msg.Value, "msg.Value").IsNotNull(); Condition.Requires(msg.Value.ProductId, "msg.Value.ProductId").IsNotNullOrEmpty(); Condition.Requires(_products.ContainsKey(msg.Value.ProductId)); bool myFill = _orderManager.OnMessage(msg); OrderBookBuilder book = _products[msg.Value.ProductId]; OrderBookDelta delta = null; Trade trade = null; bool ok = false; try { ok = book.OnOrderUpdate(msg.Value, out delta, out trade); } catch (Exception e) { _log.Error(e, "Unable to process order update"); } if (ok) { if (!myFill && trade != null && trade.Size > 0m) { try { OnTrade?.Invoke( msg.Value.ProductId, new TimestampedMsg <Trade>() { Received = msg.Received, Value = trade }); } catch (Exception e) { _log.Warn(e, "Ignoring exception from OnTrade"); } } if (delta != null && (delta.Bids.Any() || delta.Asks.Any())) { try { OnOrderBook?.Invoke( msg.Value.ProductId, new TimestampedMsg <OrderBookDelta>() { Received = msg.Received, Value = delta }); } catch (Exception e) { _log.Warn(e, "Ignoring exception from OnOrderBook"); } } } else { RefreshOrderBook(msg.Value.ProductId, book); } }