/// <summary> /// /// </summary> /// <param name="cmy"></param> /// <returns></returns> private async ValueTask <bool> mergeMyOrder(SMyOrders cmy) { var _result = false; SMyOrders _qmy; { if (__qMyOrders.TryGetValue(cmy.symbol, out _qmy) == true) { if (cmy.action == "insert" || cmy.action == "update" || cmy.action == "delete") { updateMyOrder(_qmy, ref cmy); _result = true; } else if (cmy.action == "partial" || cmy.action == "polling") { modifyMyOrder(_qmy, ref cmy); } _qmy.result.RemoveAll(o => o.quantity == o.filled); } else if (cmy.action == "partial" || cmy.action == "polling") { __qMyOrders[cmy.symbol] = cmy; _result = true; } if (_result == true) { await publishMyCompleteOrder(cmy); } } return(_result); }
private async ValueTask publishMyCompleteOrder(SMyOrders stk) { await Task.Delay(0); var _json_data = JsonConvert.SerializeObject(stk); __complete.Write(this, BMConfig.DealerName, _json_data); }
/// <summary> /// /// </summary> /// <param name="qmy"></param> /// <param name="cmy"></param> /// <returns></returns> private void updateMyOrder(SMyOrders qmy, ref SMyOrders cmy) { foreach (var _co in cmy.result) { var _qa = qmy.result.Where(o => o.orderId == _co.orderId).SingleOrDefault(); if (_qa == null) { if (_co.orderStatus == OrderStatus.Open) { qmy.result.Add(_co); } } else { _qa.timestamp = _co.timestamp; _co.orderStatus = _co.orderStatus == OrderStatus.Unknown ? _qa.orderStatus : _co.orderStatus; _co.sideType = _co.sideType == SideType.Unknown ? _qa.sideType : _co.sideType; _co.orderType = _co.orderType == OrderType.Unknown ? _qa.orderType : _co.orderType; _co.makerType = _co.makerType == MakerType.Unknown ? _qa.makerType : _co.makerType; if (_co.orderStatus == OrderStatus.Partially || _co.orderStatus == OrderStatus.Closed) { _qa.remaining = _co.remaining; _qa.filled = _co.filled; _qa.avgPx = _co.avgPx; } else if (_co.orderStatus == OrderStatus.Canceled) { _qa.remaining = _co.remaining; _qa.filled = _qa.quantity - _qa.remaining; } else { if (_co.quantity != 0 && _co.quantity != _qa.quantity) { _qa.quantity = _co.quantity; _qa.amount = _qa.price * _qa.quantity; } if (_co.price != 0 && _co.price != _qa.price) { _qa.price = _co.price; _qa.amount = _qa.price * _qa.quantity; } if (_co.remaining != 0 && _co.remaining != _qa.remaining) { _qa.remaining = _co.remaining; _qa.filled = _qa.quantity - _qa.remaining; } } } } }
/// <summary> /// /// </summary> /// <param name="qmy"></param> /// <param name="cmy"></param> /// <returns></returns> private void modifyMyOrder(SMyOrders qmy, ref SMyOrders cmy) { foreach (var _co in cmy.result) { var _qa = qmy.result.Where(o => o.orderId == _co.orderId).SingleOrDefault(); if (_qa == null) { qmy.result.Add(_co); } } foreach (var _qo in qmy.result) { var _ca = cmy.result.Where(o => o.orderId == _qo.orderId).SingleOrDefault(); if (_ca == null) { _qo.filled = _qo.quantity; } } }
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..."); }