public void Start() { var data = _writer.GetRowsAsync <OrderBookNoSql>().ToListAsync().GetAwaiter().GetResult(); lock (_gate) { foreach (var book in data.GroupBy(e => e.PartitionKey)) { var(brokerId, symbol) = OrderBookNoSql.GetBrokerIdAndSymbol(book.Key); var manager = new OrderBookManager(brokerId, symbol, _logger); var price = manager.SetState(book); if (!_data.TryGetValue(brokerId, out var symbolManagers)) { symbolManagers = new Dictionary <string, OrderBookManager>(); _data[brokerId] = symbolManagers; } symbolManagers[symbol] = manager; _logger.LogInformation("Book manager is inited. BrokerId: {brokerId}; Symbol:{symbol}; Count: {count}. Price: {ask} / {bid}", brokerId, symbol, book.Count(), price.Ask, price.Bid); } _isInit = true; } }
public static double CalculateAveragePrice( OrderBookNoSql orderBook, ISpotInstrument instrument, IAsset fromAsset, IAsset toAsset, IAsset volumeAsset, double volume) { if (instrument.BaseAsset == fromAsset.Symbol && volumeAsset.Symbol == fromAsset.Symbol) { return((double)CalculateAveragePriceStraight(orderBook.BuyLevels.OrderByDescending(e => e.Price), (decimal)volume, instrument.Accuracy)); } if (instrument.BaseAsset == fromAsset.Symbol && volumeAsset.Symbol == toAsset.Symbol) { return((double)CalculateAveragePriceNotStraight(orderBook.BuyLevels.OrderByDescending(e => e.Price), (decimal)volume, instrument.Accuracy)); } if (instrument.BaseAsset == toAsset.Symbol && volumeAsset.Symbol == toAsset.Symbol) { return((double)CalculateAveragePriceStraight(orderBook.SellLevels.OrderBy(e => e.Price), (decimal)volume, instrument.Accuracy)); } if (instrument.BaseAsset == toAsset.Symbol && volumeAsset.Symbol == fromAsset.Symbol) { return((double)CalculateAveragePriceNotStraight(orderBook.SellLevels.OrderBy(e => e.Price), (decimal)volume, instrument.Accuracy)); } throw new Exception("CalculateAveragePrice cant calculate price and volume"); }
/// <summary> /// Register order and notify about best price update /// </summary> public BidAsk RegisterOrderUpdate(List <OrderBookOrder> updates, Dictionary <string, OrderBookNoSql> updateList, Dictionary <string, OrderBookNoSql> deleteList) { var priceUpdated = false; foreach (var order in updates.Where(e => e.IsActive)) { var orderLevel = ConvertOrder(order); if (!_data.TryGetValue(order.OrderId, out var entity)) { entity = OrderBookNoSql.Create(order.BrokerId, order.Symbol, orderLevel, order.Side); _data[order.OrderId] = entity; } entity.Level = orderLevel; updateList[entity.Level.OrderId] = entity; if (order.Side == OrderSide.Sell && (_ask == null || _ask?.Price > order.Price)) { _ask = entity.Level; priceUpdated = true; } if (order.Side == OrderSide.Buy && (_ask == null || _bid?.Price < order.Price)) { _bid = entity.Level; priceUpdated = true; } } foreach (var order in updates.Where(e => !e.IsActive)) { var orderId = order.OrderId; var orderLevel = ConvertOrder(order); if (!_data.TryGetValue(order.OrderId, out var entity)) { entity = OrderBookNoSql.Create(order.BrokerId, order.Symbol, orderLevel, order.Side); } _data.Remove(orderId); deleteList[orderId] = entity; if (_ask?.OrderId == orderId) { _ask = null; priceUpdated = true; } if (_bid?.OrderId == orderId) { _bid = null; priceUpdated = true; } } if (priceUpdated && _ask == null) { _ask = _data.Values.Where(e => e.Side == OrderSide.Sell).OrderBy(e => e.Level.Price).FirstOrDefault()?.Level; } if (priceUpdated && _bid == null) { _bid = _data.Values.Where(e => e.Side == OrderSide.Buy).OrderByDescending(e => e.Level.Price).FirstOrDefault()?.Level; } if (_ask != null && _bid != null && _ask.Price <= _bid.Price) { _logger.LogError("NEGATIVE SPREAD {symbol}; Ask: {ask}; Bid: {bid}", Symbol, _ask.Price, _bid.Price); priceUpdated = false; } if (priceUpdated) { var updateTs = updates.Max(e => e.Timestamp); var bidAsk = new BidAsk { Id = Symbol, LiquidityProvider = BrokerId, Ask = _ask != null?Convert.ToDouble(_ask.Price) : 0, Bid = _bid != null?Convert.ToDouble(_bid.Price) : 0, DateTime = updateTs }; return(bidAsk); } return(null); }
public List <OrderBookLevelNoSql> GetOrderBook(string brokerId, string symbol) { var orderBook = _reader.Get(OrderBookNoSql.GeneratePartitionKey(brokerId, symbol)); return(orderBook.Select(e => e.Level).ToList()); }