/// <summary> /// /// </summary> /// <param name="cco"></param> /// <returns></returns> private async ValueTask <bool> mergeCompleteOrder(SCompleteOrders cco) { var _result = false; if (__gmconfig.UsePublishTrade == true) { await publishTrading(cco); } if (cco.symbol != null) { SOrderBooks _qob; if (__qOrderBooks.TryGetValue(cco.symbol, out _qob) == true) { _qob.stream = cco.stream; if (cco.result != null) { var _settings = GetSettings(cco.symbol); _result = await updateCompleteOrder(_qob, cco, _settings); } } } return(_result); }
private async ValueTask publishTrading(SCompleteOrders sco) { await Task.Delay(0); var _json_data = JsonConvert.SerializeObject(sco); __trading.Write(this, GMConfig.DealerName, _json_data); }
/// <summary> /// Fetch array of recent trades data /// </summary> /// <param name="base_name">The type of trading base-currency of which information you want to query for.</param> /// <param name="quote_name">The type of trading quote-currency of which information you want to query for.</param> /// <param name="limits">maximum number of items (optional): default 20</param> /// <returns></returns> public async ValueTask <SCompleteOrders> GetCompleteOrders(string base_name, string quote_name, int limits = 20) { var _result = new SCompleteOrders { symbol = $"{quote_name}-{base_name}" }; var _params = new Dictionary <string, object>(); { _params.Add("market", _result.symbol); _params.Add("count", limits); } var _response = await publicClient.CallApiGet2Async($"/trades/ticks", _params); if (_response != null) { #if RAWJSON _result.rawJson = _response.Content; #endif if (_response.IsSuccessful == true) { var _trades = publicClient.DeserializeObject <List <UACompleteOrderItem> >(_response.Content); { _result.sequentialId = _trades.Max(t => t.sequential_id); _result.result = _trades.Select(t => { return(new SCompleteOrderItem { timestamp = t.timestamp, sideType = t.sideType, price = t.price, quantity = t.quantity }); }) .ToList(); } _result.SetSuccess(); } else { var _message = publicClient.GetResponseMessage(_response); _result.SetFailure(_message.message); } } return(_result); }
private async ValueTask <bool> updateCompleteOrder(SOrderBooks qob, SCompleteOrders cco, Settings settings) { var _nob = new SOrderBooks { exchange = cco.exchange, stream = "difftrade", symbol = cco.symbol, action = cco.action, sequentialId = cco.sequentialId, result = new SOrderBook { timestamp = cco.result.Max(o => o.timestamp), askSumQty = 0, bidSumQty = 0 } }; lock (__qOrderBooks) { settings.before_trade_ask_size = qob.result.asks.Sum(o => o.quantity); settings.before_trade_bid_size = qob.result.bids.Sum(o => o.quantity); foreach (var _t in cco.result.OrderBy(t => t.timestamp)) { if (settings.last_trade_id >= _t.timestamp) { continue; } settings.last_trade_id = _t.timestamp; var _ask = qob.result.asks.Where(o => o.price == _t.price).SingleOrDefault(); if (_ask != null) { if (_ask.quantity <= _t.quantity) { _nob.result.asks.Add(new SOrderBookItem { action = "delete", id = _ask.id, price = _ask.price, quantity = _ask.quantity, amount = _ask.price * _ask.quantity, count = 1 }); _nob.result.askSumQty -= _ask.quantity; _ask.quantity = 0; _ask.amount = 0; } else { _ask.quantity -= _t.quantity; _ask.amount = _ask.price * _ask.quantity; _nob.result.asks.Add(new SOrderBookItem { action = "update", id = _ask.id, price = _ask.price, quantity = _ask.quantity, amount = _ask.price * _ask.quantity, count = 1 }); _nob.result.askSumQty += _ask.quantity; } } var _bid = qob.result.bids.Where(o => o.price == _t.price).SingleOrDefault(); if (_bid != null) { if (_bid.quantity <= _t.quantity) { _nob.result.bids.Add(new SOrderBookItem { action = "delete", id = _bid.id, price = _bid.price, quantity = _bid.quantity, amount = _bid.price * _bid.quantity, count = 1 }); _nob.result.bidSumQty -= _bid.quantity; _bid.quantity = 0; _bid.amount = 0; } else { _bid.quantity -= _t.quantity; _bid.amount = _bid.price * _bid.quantity; _nob.result.bids.Add(new SOrderBookItem { action = "update", id = _bid.id, price = _bid.price, quantity = _bid.quantity, amount = _bid.price * _bid.quantity, count = 1 }); _nob.result.bidSumQty += _bid.quantity; } } //cleanOrderbook(qob, _nob, _t.price); } qob.sequentialId = _nob.sequentialId; qob.result.asks.RemoveAll(o => o.quantity == 0); qob.result.bids.RemoveAll(o => o.quantity == 0); } _nob.result.asks.RemoveAll(o => o.quantity == 0); _nob.result.bids.RemoveAll(o => o.quantity == 0); if (_nob.result.asks.Count + _nob.result.bids.Count > 0) { await publishOrderbook(_nob); settings.orderbook_count = 0; settings.trades_flag = true; } return(true); }
public async ValueTask Start(CancellationToken cancelToken) { BTLogger.SNG.WriteO(this, $"processing service start..."); var _processing = Task.Run(async() => { var _last_polling_trade = 0L; while (true) { try { await Task.Delay(0); var _message = (QMessage)null; if (ReceiveQ.TryDequeue(out _message) == false) { var _cancelled = cancelToken.WaitHandle.WaitOne(0); if (_cancelled == true) { break; } await Task.Delay(10); continue; } if (_message.command == "WS") { if (_message.stream == "trade") { var _w_trade = JsonConvert.DeserializeObject <UWCompleteOrderItem>(_message.payload ?? ""); var _s_trade = new SCompleteOrders { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _w_trade.timestamp, result = new List <SCompleteOrderItem> { new SCompleteOrderItem { timestamp = _w_trade.timestamp, sideType = _w_trade.sideType, price = _w_trade.price, quantity = _w_trade.quantity } } }; if (_s_trade.result.Count() > 0) { _last_polling_trade = _s_trade.sequentialId; await mergeCompleteOrder(_s_trade); } } else if (_message.stream == "orderbook") { var _w_orderbook = JsonConvert.DeserializeObject <UWOrderBook>(_message.payload ?? ""); var _s_orderbooks = new SOrderBooks { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _w_orderbook.timestamp, result = new SOrderBook { timestamp = _w_orderbook.timestamp, askSumQty = _w_orderbook.askSumQty, bidSumQty = _w_orderbook.bidSumQty, asks = _w_orderbook.asks, bids = _w_orderbook.bids } }; await mergeOrderbook(_s_orderbooks); } } else if (_message.command == "AP") { if (_message.stream == "trade") { var _a_trades = JsonConvert.DeserializeObject <List <UACompleteOrderItem> >(_message.payload ?? ""); var _s_trade = new SCompleteOrders { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _a_trades.Max(t => t.timestamp), result = _a_trades.Where(t => t.timestamp > _last_polling_trade).Select(t => { return(new SCompleteOrderItem { timestamp = t.timestamp, sideType = t.sideType, price = t.price, quantity = t.quantity }); }) .ToList() }; if (_s_trade.result.Count() > 0) { _last_polling_trade = _s_trade.sequentialId; await mergeCompleteOrder(_s_trade); } } else if (_message.stream == "orderbook") { var _a_orderbooks = JsonConvert.DeserializeObject <List <UAOrderBook> >(_message.payload ?? ""); var _timestamp = _a_orderbooks.Max(o => o.timestamp); var _asks = _a_orderbooks[0].asks; var _bids = _a_orderbooks[0].bids; var _s_orderbooks = new SOrderBooks { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _a_orderbooks.Max(t => t.timestamp), result = new SOrderBook { timestamp = _timestamp, askSumQty = _asks.Sum(o => o.quantity), bidSumQty = _bids.Sum(o => o.quantity), asks = _asks, bids = _bids } }; await mergeOrderbook(_s_orderbooks); } else if (_message.stream == "ticker") { var _a_ticker_data = JsonConvert.DeserializeObject <List <UAOrderBook> >(_message.payload ?? ""); await publishTicker(new STickers { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _message.sequentialId, timestamp = _a_ticker_data.Max(o => o.timestamp), totalAskSize = _a_ticker_data.Sum(o => o.askSumQty), totalBidSize = _a_ticker_data.Sum(o => o.bidSumQty), result = _a_ticker_data.Select(o => { var _ask = o.asks.OrderBy(a => a.price).First(); var _bid = o.bids.OrderBy(a => a.price).Last(); return(new STickerItem { askPrice = _ask.price, askSize = _ask.quantity, bidPrice = _bid.price, bidSize = _bid.quantity }); }) .ToList() }); } } else if (_message.command == "SS") { await snapshotOrderbook(_message.symbol); } #if DEBUG else { BTLogger.SNG.WriteO(this, _message.payload); } #endif if (cancelToken.IsCancellationRequested == true) { break; } } catch (TaskCanceledException) { } catch (Exception ex) { BTLogger.SNG.WriteX(this, ex.ToString()); } } }, cancelToken ); await Task.WhenAll(_processing); BTLogger.SNG.WriteO(this, $"processing service stop..."); }
public async ValueTask Start(CancellationToken cancelToken) { BMLogger.SNG.WriteO(this, $"processing service start..."); var _processing = Task.Run(async() => { var _last_polling_trade = 0L; while (true) { try { await Task.Delay(0); var _message = (QMessage)null; if (ReceiveQ.TryDequeue(out _message) == false) { var _cancelled = cancelToken.WaitHandle.WaitOne(0); if (_cancelled == true) { break; } await Task.Delay(10); continue; } if (_message.command == "WS") { if (_message.stream == "order") { var _w_orders = JsonConvert.DeserializeObject <List <BMyOrderItem> >(_message.payload ?? ""); var _s_order = new SMyOrders { exchange = _message.exchange, stream = _message.stream, symbol = _message.symbol, action = _message.action, sequentialId = _w_orders.Max(t => t.timestamp), result = _w_orders.Select(o => { return(new SMyOrderItem { orderId = o.orderId ?? "", symbol = o.symbol ?? "", sideType = o.sideType, timestamp = o.timestamp, makerType = MakerType.Maker, orderStatus = o.orderStatus, orderType = o.orderType, quantity = o.quantity, price = o.price, amount = o.amount, filled = o.filled, remaining = o.remaining, workingIndicator = o.workingIndicator, avgPx = o.avgPx.HasValue ? o.avgPx.Value : 0, fee = o.fee, cost = o.cost, count = o.count }); }) .ToList <ISMyOrderItem>() }; await mergeMyOrder(_s_order); } else if (_message.stream == "trade") { var _w_trades = JsonConvert.DeserializeObject <List <BCompleteOrderItem> >(_message.payload ?? ""); var _s_trade = new SCompleteOrders { exchange = _message.exchange, stream = _message.stream, symbol = _message.symbol, action = _message.action, sequentialId = _w_trades.Max(t => t.timestamp), result = _w_trades.Select(t => { return(new SCompleteOrderItem { timestamp = t.timestamp, sideType = t.sideType, price = t.price, quantity = t.quantity }); }) .ToList() }; if (_s_trade.result.Count() > 0) { _last_polling_trade = _s_trade.sequentialId; await mergeCompleteOrder(_s_trade); } } else if (_message.stream == "orderbook") { var _w_orderbooks = JsonConvert.DeserializeObject <List <BOrderBookItem> >(_message.payload ?? ""); var _timestamp = CUnixTime.NowMilli; var _asks = _w_orderbooks.Where(o => o.sideType == SideType.Ask); var _bids = _w_orderbooks.Where(o => o.sideType == SideType.Bid); var _s_orderbooks = new SOrderBooks { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _timestamp, result = new SOrderBook { timestamp = _timestamp, askSumQty = _asks.Sum(o => o.quantity), bidSumQty = _bids.Sum(o => o.quantity), asks = _asks.Select(o => { return(new SOrderBookItem { quantity = o.quantity, price = o.price, amount = o.quantity * o.price, id = o.id, count = 1 }); }).ToList(), bids = _bids.Select(o => { return(new SOrderBookItem { quantity = o.quantity, price = o.price, amount = o.quantity * o.price, id = o.id, count = 1 }); }).ToList() } }; await mergeOrderbook(_s_orderbooks); } } else if (_message.command == "AP") { if (_message.stream == "order") { var _w_orders = JsonConvert.DeserializeObject <List <BMyOrderItem> >(_message.payload ?? ""); var _s_order = new SMyOrders { exchange = _message.exchange, stream = _message.stream, symbol = _message.symbol, action = _message.action, sequentialId = _w_orders.Max(t => t.timestamp), result = _w_orders.Select(o => { return(new SMyOrderItem { orderId = o.orderId ?? "", symbol = o.symbol ?? "", sideType = o.sideType, timestamp = o.timestamp, makerType = o.makerType, orderStatus = o.orderStatus, orderType = o.orderType, quantity = o.quantity, price = o.price, amount = o.amount, filled = o.filled, remaining = o.remaining, workingIndicator = o.workingIndicator, avgPx = o.avgPx.HasValue ? o.avgPx.Value : 0, fee = o.fee, cost = o.cost, count = o.count }); }) .ToList <ISMyOrderItem>() }; await mergeMyOrder(_s_order); } else if (_message.stream == "trade") { var _a_trades = JsonConvert.DeserializeObject <List <BCompleteOrderItem> >(_message.payload ?? ""); var _s_trade = new SCompleteOrders { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _a_trades.Max(t => t.timestamp), result = _a_trades.Where(t => t.timestamp > _last_polling_trade).Select(t => { return(new SCompleteOrderItem { timestamp = t.timestamp, sideType = t.sideType, price = t.price, quantity = t.quantity }); }) .ToList() }; if (_s_trade.result.Count() > 0) { _last_polling_trade = _s_trade.sequentialId; await mergeCompleteOrder(_s_trade); } } else if (_message.stream == "orderbook") { var _a_orderbooks = JsonConvert.DeserializeObject <List <BOrderBookItem> >(_message.payload ?? ""); var _timestamp = CUnixTime.NowMilli; var _asks = _a_orderbooks.Where(o => o.sideType == SideType.Ask); var _bids = _a_orderbooks.Where(o => o.sideType == SideType.Bid); var _s_orderbooks = new SOrderBooks { exchange = _message.exchange, symbol = _message.symbol, stream = _message.stream, action = _message.action, sequentialId = _timestamp, result = new SOrderBook { timestamp = _timestamp, askSumQty = _asks.Sum(o => o.quantity), bidSumQty = _bids.Sum(o => o.quantity), asks = _asks.Select(o => { return(new SOrderBookItem { quantity = o.quantity, price = o.price, amount = o.quantity * o.price, id = o.id, count = 1 }); }).ToList(), bids = _bids.Select(o => { return(new SOrderBookItem { quantity = o.quantity, price = o.price, amount = o.quantity * o.price, id = o.id, count = 1 }); }).ToList() } }; await mergeOrderbook(_s_orderbooks); } } else if (_message.command == "SS") { await snapshotOrderbook(_message.exchange); } #if DEBUG else { BMLogger.SNG.WriteO(this, _message.payload); } #endif if (cancelToken.IsCancellationRequested == true) { break; } } catch (TaskCanceledException) { } catch (Exception ex) { BMLogger.SNG.WriteX(this, ex.ToString()); } } }, cancelToken ); await Task.WhenAll(_processing); BMLogger.SNG.WriteO(this, $"processing service stop..."); }
public async ValueTask Start(CancellationTokenSource cancelTokenSource) { DRLogger.SNG.WriteO(this, $"processing service start..."); var _processing = Task.Run(async() => { var _last_polling_trade = 0L; var _orderbook_size = 25; while (true) { try { await Task.Delay(0); var _message = (QMessage)null; if (ReceiveQ.TryDequeue(out _message) == false) { var _cancelled = cancelTokenSource.Token.WaitHandle.WaitOne(0); if (_cancelled == true) { break; } await Task.Delay(10); continue; } if (_message.command == "WS") { if (_message.stream == "trade") { var _w_trades = JsonConvert.DeserializeObject <List <DCompleteOrderItem> >(_message.payload ?? ""); var _s_trades = new SCompleteOrders { exchange = _message.exchange, // deribit stream = _message.stream, // trade symbol = _message.symbol, // BTC-PERPETUAL action = _message.action, // pushing sequentialId = _w_trades.Max(t => t.timestamp), result = _w_trades.Select(t => { return(new SCompleteOrderItem { timestamp = t.timestamp, sideType = t.sideType, price = t.price, quantity = t.quantity }); }) .ToList() }; if (_s_trades.result.Count() > 0) { _last_polling_trade = _s_trades.sequentialId; await mergeTrades(_s_trades); } } else if (_message.stream == "orderbook") { var _w_orderbooks = JsonConvert.DeserializeObject <DWsOrderBook>(_message.payload ?? ""); if (_w_orderbooks.asks.Count() > 0 || _w_orderbooks.bids.Count() > 0) { var _timestamp = _w_orderbooks.timestamp; var _s_orderbooks = new SOrderBooks { exchange = _message.exchange, // deribit symbol = _message.symbol, // BTC-PERPETUAL stream = _message.stream, // orderbook action = _w_orderbooks.type, // snapshot, change sequentialId = _timestamp, result = new SOrderBook { timestamp = _timestamp, askSumQty = 0, bidSumQty = 0, asks = new List <SOrderBookItem>(), bids = new List <SOrderBookItem>() } }; foreach (var _a in _w_orderbooks.asks.OrderBy(a => a[1]).Take(_orderbook_size)) { _s_orderbooks.result.asks.Add(new SOrderBookItem { action = _a[0].ToString(), quantity = Convert.ToDecimal(_a[2]), price = Convert.ToDecimal(_a[1]), amount = 0, id = 0, count = 1 }); } foreach (var _b in _w_orderbooks.bids.OrderByDescending(b => b[1]).Take(_orderbook_size)) { _s_orderbooks.result.bids.Add(new SOrderBookItem { action = _b[0].ToString(), quantity = Convert.ToDecimal(_b[2]), price = Convert.ToDecimal(_b[1]), amount = 0, id = 0, count = 1 }); } await mergeOrderbooks(_s_orderbooks); } } } else if (_message.command == "AP") { if (_message.stream == "trade") { var _a_trades = JsonConvert.DeserializeObject <DRResults <DCompleteOrders> >(_message.payload ?? ""); if (_a_trades.result.trades.Count > 0) { var _s_trades = new SCompleteOrders { exchange = _message.exchange, // deribit symbol = _message.symbol, // BTC-PERPETUAL stream = _message.stream, // trade action = _message.action, // polling sequentialId = _a_trades.result.trades.Max(t => t.timestamp), result = _a_trades.result.trades.Where(t => t.timestamp > _last_polling_trade).Select(t => { return(new SCompleteOrderItem { timestamp = t.timestamp, sideType = t.sideType, price = t.price, quantity = t.quantity }); }) .ToList() }; if (_s_trades.result.Count() > 0) { _last_polling_trade = _s_trades.sequentialId; await mergeTrades(_s_trades); } } } else if (_message.stream == "orderbook") { var _a_orderbooks = JsonConvert.DeserializeObject <DRResults <DOrderBook> >(_message.payload ?? ""); if (_a_orderbooks.result.asks.Count > 0 || _a_orderbooks.result.bids.Count > 0) { var _timestamp = _a_orderbooks.result.timestamp; var _s_orderbooks = new SOrderBooks { exchange = _message.exchange, // deribit symbol = _message.symbol, // BTC-PERPETUAL stream = _message.stream, // orderbook action = _message.action, // polling sequentialId = _timestamp, result = new SOrderBook { timestamp = _timestamp, askSumQty = 0, bidSumQty = 0, asks = _a_orderbooks.result.asks.Select(o => { return(new SOrderBookItem { quantity = o.quantity, price = o.price, amount = 0, id = 0, count = 1 }); }) .ToList(), bids = _a_orderbooks.result.bids.Select(o => { return(new SOrderBookItem { quantity = o.quantity, price = o.price, amount = 0, id = 0, count = 1 }); }) .ToList() } }; await mergeOrderbooks(_s_orderbooks); } } } else if (_message.command == "SS") { await snapshotOrderbook(_message.exchange); } #if DEBUG else { DRLogger.SNG.WriteO(this, _message.payload); } #endif if (cancelTokenSource.Token.IsCancellationRequested == true) { break; } } catch (TaskCanceledException) { } catch (Exception ex) { DRLogger.SNG.WriteX(this, ex.ToString()); } } }, cancelTokenSource.Token ); await Task.WhenAll(_processing); DRLogger.SNG.WriteO(this, $"processing service stop..."); }