public static decimal CalculateSpread(OrderExecutionOrderBook message, decimal volume)
        {
            decimal SpreadWeight(IReadOnlyList <VolumePrice> orderbook)
            {
                var weight       = 0M;
                var currentLevel = 0;
                var qtyLeft      = Math.Abs(volume);

                while (qtyLeft > 0 && currentLevel < message.OrderBook.Asks.Count)
                {
                    var currentLevelVolume = currentLevel != orderbook.Count - 1
                        ? orderbook[currentLevel].Volume
                        : decimal.MaxValue;

                    weight += (qtyLeft - currentLevelVolume > 0 ? currentLevelVolume : qtyLeft)
                              * orderbook[currentLevel].Price;
                    qtyLeft -= currentLevelVolume;
                    currentLevel++;
                }

                return(weight);
            }

            var askSpreadWeight = SpreadWeight(message.OrderBook.Asks);
            var bidSpreadWeight = SpreadWeight(message.OrderBook.Bids);

            return(askSpreadWeight - bidSpreadWeight);
        }
        public static OrderExecutionOrderBook ToDomain(this OrderExecutionOrderBookContract contract)
        {
            var orderBook = new OrderExecutionOrderBook
            {
                OrderId         = contract.OrderId,
                ExternalOrderId = contract.ExternalOrderId,
                OrderBook       = new ExternalOrderBook
                {
                    ExchangeName = contract.OrderBook.ExchangeName,
                    AssetPairId  = contract.OrderBook.AssetPairId,
                    Timestamp    = contract.OrderBook.Timestamp,
                    Asks         = contract.OrderBook.Asks.Select(x => new VolumePrice {
                        Volume = x.Volume, Price = x.Price
                    }).ToList(),
                    Bids = contract.OrderBook.Bids.Select(x => new VolumePrice {
                        Volume = x.Volume, Price = x.Price
                    }).ToList(),
                },
            };

            orderBook.Spread = SpreadCalculator.CalculateSpread(orderBook, contract.Volume);

            return(orderBook);
        }
 public decimal Spread_Calculation_Success(OrderExecutionOrderBook orderExecutionOrderBook, decimal volume)
 {
     return(SpreadCalculator.CalculateSpread(orderExecutionOrderBook, volume));
 }