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(); }