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);
            }
        }
Пример #2
0
        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();
            }
        }