public async Task PlaceToMarketAsync() { var level = _levels.FirstOrDefault(l => l.Status == MarketLevelStatus.Empty); while (level != null) { var side = (level.Side == MarketSide.Long && level.Type == MarketLevelType.Direct) || (level.Side == MarketSide.Short && level.Type == MarketLevelType.Compensate) ? MarketSide.Long : MarketSide.Short; var price = level.Type == MarketLevelType.Direct ? level.Price : level.PriceCompensate; var scope = _levels.Where(l => l.Status == MarketLevelStatus.Placed && l.OrderSide != side); var crossLevel = side == MarketSide.Long ? scope.Where(l => l.Price <= price).OrderBy(l => l.Price).FirstOrDefault() : scope.Where(l => l.Price >= price).OrderByDescending(l => l.Price).FirstOrDefault(); if (crossLevel != null) { crossLevel.CurrentOrderId = string.Empty; crossLevel.Status = MarketLevelStatus.Empty; crossLevel.Type = crossLevel.Type == MarketLevelType.Direct ? MarketLevelType.Compensate : MarketLevelType.Direct; if (crossLevel.Status == MarketLevelStatus.Placed) { await _trader.CancelOrder(crossLevel.CurrentOrderId); _levelsByOrder.Remove(crossLevel.CurrentOrderId); } Console.WriteLine($"flip level. Price: {level.Price}, Side: {level.Side}, Type: {level.Type}, Id: {level.CurrentOrderId}"); level.CurrentOrderId = string.Empty; level.Status = MarketLevelStatus.Empty; level.Type = level.Type == MarketLevelType.Direct ? MarketLevelType.Compensate : MarketLevelType.Direct; Console.WriteLine($"flip level. Price: {level.Price}, Side: {level.Side}, Type: {level.Type}"); } else { var orderId = await _trader.PlaceOrderAsync( _symbol, price, level.OriginalSize, side); if (!string.IsNullOrEmpty(orderId)) { level.CurrentOrderId = orderId; level.Status = MarketLevelStatus.Placed; level.OrderSide = side; Console.WriteLine( $"Placed. Price: {level.Price}, Type: {level.Side}/{level.Type}, O-Price: {price}, O-Side: {side}, O-Id: {level.CurrentOrderId}"); _levelsByOrder[orderId] = level; } } level = _levels.FirstOrDefault(l => l.Status == MarketLevelStatus.Empty); } }
public async Task PlaceToMarketAsync() { await _semaphoreSlim.WaitAsync(); try { var level = _levels.FirstOrDefault(l => l.Status == MarketLevelStatus.Empty); while (level != null) { var side = level.ActualOrderSide; var price = level.ActualOrderPrice; var scope = _levels.Where(l => l.Status == MarketLevelStatus.Placed && l.OrderSide != side).ToList(); var crossLevel = side == MarketSide.Long ? scope.Where(l => l.PriceSell <= level.OriginalOrderPrice).OrderBy(l => l.PriceSell).FirstOrDefault() : scope.Where(l => l.PriceBuy >= level.OriginalOrderPrice).OrderByDescending(l => l.PriceBuy).FirstOrDefault(); if (crossLevel != null) { if (crossLevel.Status == MarketLevelStatus.Placed) { await CancelOrder(crossLevel.CurrentOrderId); } //crossLevel.RegisterTradeSize(crossLevel.ActualOrderSize * crossLevel.ActualOrderSideSign); crossLevel.Revert(); Console.WriteLine( $"flip level. Price: {crossLevel.PriceBuy}, Side: {crossLevel.Side}, Id: {level.CurrentOrderId}"); //level.RegisterTradeSize(crossLevel.ActualOrderSize * crossLevel.ActualOrderSideSign); level.Revert(); Console.WriteLine($"flip level. Price: {level.PriceBuy}, Side: {level.Side}"); } else { var orderId = await _trader.PlaceOrderAsync( _symbol, price, level.ActualOrderSize, side); if (!string.IsNullOrEmpty(orderId)) { level.CurrentOrderId = orderId; level.Status = MarketLevelStatus.Placed; level.OrderSide = side; Console.WriteLine( $"Placed. Price: {level.PriceBuy}, Side: {level.Side}, O-Price: {price}, O-Side: {side}, O-Id: {level.CurrentOrderId}"); _levelsByOrder[orderId] = level; } } level = _levels.FirstOrDefault(l => l.Status == MarketLevelStatus.Empty); } } finally { _semaphoreSlim.Release(); } }