public void sell(string symbolName, int quantity)
        {
            if (quantity < 1)
            {
                throw new System.ServiceModel.FaultException <ArgumentException>(new ArgumentException("Quantity must be greater than zero.", "quantity"));
            }

            TraderContext db = DbContext;
            Symbol        s  = db.Symbols.Where(x => x.name == symbolName).FirstOrDefault();

            if (s == null)
            {
                throw new System.ServiceModel.FaultException <ArgumentException>(new ArgumentException("Symbol not found.", "symbol"));
            }
            Quote lastPrice = db.FindLastQuoteFor(s);

            if (lastPrice == null)
            {
                // if we have no prices, the operation cannot complete
                return;
            }
            Portfolio portfolio = db.Portfolios.FirstOrDefault();
            Position  pos       = portfolio.Positions.Where(x => x.Symbol == s && x.status == positionStatus.Open).FirstOrDefault();

            if (pos == null || pos.quantity < quantity)
            {
                // the user does not own enough shares to complete the requested sell transaction
                throw new System.ServiceModel.FaultException <InsufficientQuantityFault>(new InsufficientQuantityFault(quantity, pos.quantity));
            }
            // figure out which shares to sell to get the best price
            List <Trade> byProfit       = pos.Trades.Where(t => t.type == tradeTypes.Buy).OrderByDescending(o => (lastPrice.price - o.price)).ToList <Trade>();
            List <Trade> toSell         = new List <Trade>();
            string       transaction_id = Guid.NewGuid().ToString();

            foreach (Trade t in byProfit)
            {
                int   remaining = quantity - toSell.Sum(x => x.quantity);
                Trade next      = t.sell(Math.Min(t.quantity, remaining));
                next.price         = lastPrice.price;
                next.TransactionId = transaction_id;
                toSell.Add(next);
                if (toSell.Sum(x => x.quantity) == quantity)
                {
                    break;
                }
            }
            pos.Trades.AddRange(toSell);
            // update subtotals in the postition to reflect the new transaction
            pos.Recalculate();
            // add the proceeds of the sale to our available cash
            portfolio.Cash += toSell.Sum(x => (x.price * x.quantity) - x.PaidCommission);
            db.SaveChanges();
            db.Dispose();
        }