private OrderTransactionResponseBL TryFillOrderBook(IAccountServiceRpcClient accountService)
        {
#if PERF_FINEST
            long start = Now;
#endif

            OrderBL            buyOrder     = BuyBook.First;
            OrderBL            sellOrder    = SellBook.First;
            List <OrderBL>     orders       = new List <OrderBL>();
            List <Transaction> transactions = new List <Transaction>();
            // QUESTION: Execute the limit order at sell price benefits BUYER fat finger
            //           What to do if SELLER fat finger? Shouldn't that give the SELLER
            //           the higher BID price?
            decimal executionPrice = sellOrder.StrikePrice;
            int     fillQuantity   = Math.Min(buyOrder.OpenQuantity, sellOrder.OpenQuantity);
            Task <CanFillOrderResponse> buyerResponse = accountService
                                                        .CanFillOrderAsync(new CanFillOrderRequest {
                Order        = buyOrder.ToMessage(),
                FillQuantity = fillQuantity
            }).ResponseAsync;
            Task <CanFillOrderResponse> sellerResponse = accountService
                                                         .CanFillOrderAsync(new CanFillOrderRequest {
                Order        = sellOrder.ToMessage(),
                FillQuantity = fillQuantity
            }).ResponseAsync;
            Task.WaitAll(buyerResponse, sellerResponse);
            bool canExecute = true;
            if (!buyerResponse.Result.Value)
            {
                BuyBook.RemoveOrder(buyOrder);
                buyOrder.Cancel();
                orders.Add(buyOrder);
                canExecute = false;
                // TODO: Publish order has been cancelled
            }
            if (!sellerResponse.Result.Value)
            {
                SellBook.RemoveOrder(sellOrder);
                sellOrder.Cancel();
                orders.Add(sellOrder);
                canExecute = false;
                // TODO: Publish order has been cancelled
            }
            if (!canExecute)
            {
                return(new OrderTransactionResponseBL(new OrderTransactionBL(orders, transactions)));
            }

            buyOrder.OpenQuantity  -= fillQuantity;
            sellOrder.OpenQuantity -= fillQuantity;
            Transaction transaction = new Transaction(buyOrder, sellOrder, buyOrder.Ticker,
                                                      fillQuantity, executionPrice);
            transactions.Add(transaction);
            orders.Add(SellBook.First);
            if (SellBook.First.IsFilled)
            {
                OrderBL filledOrder = SellBook.First;
                SellBook.RemoveOrder(filledOrder);
                filledOrder.Complete();
            }
            orders.Add(BuyBook.First);
            if (BuyBook.First.IsFilled)
            {
                OrderBL filledOrder = BuyBook.First;
                BuyBook.RemoveOrder(filledOrder);
                filledOrder.Complete();
            }
#if PERF_FINEST
            Logger.Here().Information(String.Format("TryFillOrderBook executed in {0} milliseconds", ((Now - start) / TimeSpan.TicksPerMillisecond)));
#endif

            return(new OrderTransactionResponseBL(new OrderTransactionBL(orders, transactions)));
        }
        private OrderTransactionResponseBL FillMarketOrder(IAccountServiceRpcClient accountService,
                                                           OrderBL order, OrderBook book)
        {
#if PERF_FINEST
            long start = Now;
#endif
            CheckArgument(!order.Action.Equals(book.Type), "Error: Wrong book");

            bool               done         = false;
            List <OrderBL>     orders       = new List <OrderBL>();
            List <Transaction> transactions = new List <Transaction>();
            while (!done)
            {
                if (book.IsEmpty)
                {
                    throw new SystemException("Order book is empty");          // TODO: Handle order book is empty
                }
                OrderBL buyOrder       = order.IsBuyOrder ? order : book.First;
                OrderBL sellOrder      = order.IsSellOrder ? order : book.First;
                decimal executionPrice = order.IsBuyOrder ? sellOrder.StrikePrice : buyOrder.StrikePrice;
                int     fillQuantity   = Math.Min(buyOrder.OpenQuantity, sellOrder.OpenQuantity);
                // QUESTION: Many issues here, partial fill, etc
                Task <CanFillOrderResponse> buyerResponse = accountService
                                                            .CanFillOrderAsync(new CanFillOrderRequest {
                    Order        = buyOrder.ToMessage(),
                    FillQuantity = fillQuantity
                }).ResponseAsync;
                Task <CanFillOrderResponse> sellerResponse = accountService
                                                             .CanFillOrderAsync(new CanFillOrderRequest {
                    Order        = sellOrder.ToMessage(),
                    FillQuantity = fillQuantity
                }).ResponseAsync;
                Task.WaitAll(buyerResponse, sellerResponse);
                bool canExecute = true;
                if (!buyerResponse.Result.Value)
                {
                    if (!order.IsBuyOrder)
                    {
                        BuyBook.RemoveOrder(buyOrder);
                    }
                    buyOrder.Cancel();
                    orders.Add(buyOrder);
                    canExecute = false;
                    // TODO: Publish order has been cancelled
                }
                if (!sellerResponse.Result.Value)
                {
                    if (!order.IsSellOrder)
                    {
                        SellBook.RemoveOrder(sellOrder);
                    }
                    sellOrder.Cancel();
                    orders.Add(sellOrder);
                    canExecute = false;
                    // TODO: Publish order has been cancelled
                }
                if (!order.IsOpen)
                {
                    return(new OrderTransactionResponseBL(new OrderTransactionBL(orders, transactions)));
                }
                if (!canExecute)
                {
                    continue;
                }

                buyOrder.OpenQuantity  -= fillQuantity;
                sellOrder.OpenQuantity -= fillQuantity;
                Transaction transaction = new Transaction(buyOrder, sellOrder, buyOrder.Ticker,
                                                          fillQuantity, executionPrice);
                transactions.Add(transaction);
                orders.Add(book.First);
                if (book.First.IsFilled)
                {
                    OrderBL filledOrder = book.First;
                    book.RemoveOrder(filledOrder);
                    filledOrder.Complete();
                }
                if (order.IsFilled)
                {
                    order.Complete();
                    orders.Add(order);
                    done = true;
                }
            }
#if PERF_FINEST
            Logger.Here().Information(String.Format("Market order executed in {0} milliseconds", ((Now - start) / TimeSpan.TicksPerMillisecond)));
#endif

            return(new OrderTransactionResponseBL(new OrderTransactionBL(orders, transactions)));
        }