public async Task <TradeResponse> TradeAsync(BuyPosition buy) { var response = new TradeResponse { TradeSummary = new List <string>(), Initial = $"{buy.Current}" }; var tasks = new List <Task <TradeInfo> >(); var keepLooping = true; var cnt = 0; var dollarVal = 0m; var tradeSize = 0m; var sw = Stopwatch.StartNew(); while (keepLooping) { buy.LastSize = 0; _askHeap.FindSizeAndPrice(buy); while (!buy.LastSize.Equals(0m)) { tasks.Add(GetBuyTask(buy)); buy.LastSize = 0; _askHeap.FindSizeAndPrice(buy); } if (tasks.Count > 0) { //We can change this using Interleaved Tasks logic to gain some perf! var finished = await Task.WhenAny(tasks).ConfigureAwait(false); tasks.Remove(finished); var info = await finished.ConfigureAwait(false); response.TradeSummary.Add(info.Summary(++cnt)); buy.AddValue(info.Remains); dollarVal += decimal.Round(info.DollarValue, 2); tradeSize += info.TradeSize; } else { keepLooping = false; } } sw.Stop(); response.Untraded = $"{decimal.Round(buy.Current, 2)}"; response.TotalValue = $"{decimal.Round(dollarVal, 2)} $"; response.TotalTraded = $"{tradeSize}"; response.MsTime = ((int)(sw.Elapsed.TotalMilliseconds * 1000)) / 1000.0m; return(response); }