public void Ask_Heap_Latency() { const int size = 1024 * 1024; var arr1 = new Quote[128 * 1024]; Populate(arr1); var arr2 = new Quote[(1024 - 129) * 1024 - 1]; Populate(arr2); var arr3 = new Quote[1025]; Populate(arr3); var quote1 = new Quote(0.5m, 1, Guid.NewGuid().ToString(), 1, null, 1); var quote2 = new Quote(0.6m, 1, Guid.NewGuid().ToString(), 1, null, 1); var quote3 = new Quote(0.7m, 1, Guid.NewGuid().ToString(), 1, null, 1); var fullArray = new Quote[size + 3]; Array.Copy(arr1, 0, fullArray, 0, arr1.Length); Array.Copy(arr2, 0, fullArray, arr1.Length, arr2.Length); Array.Copy(arr3, 0, fullArray, arr1.Length + arr2.Length, arr3.Length); fullArray[fullArray.Length - 3] = quote1; fullArray[fullArray.Length - 2] = quote2; fullArray[fullArray.Length - 1] = quote3; fullArray = fullArray.OrderBy(x => x.QuotePrice).ToArray(); var heaps = new[] { CreateMinHeap(arr1, 0), CreateMinHeap(arr2, 1), CreateMinHeap(arr3, 2) }; var askHeap = new AskHeap(heaps); heaps[0].InsertVal(quote1); heaps[1].InsertVal(quote2); heaps[2].InsertVal(quote3); var position = new BuyPosition(fullArray.Sum(x => x.QuotePrice)); var sw = Stopwatch.StartNew(); Parallel.For(0, 1, i => { var cnt = 0; do { position.LastSize = 0; askHeap.FindSizeAndPrice(position); Assert.True(fullArray[cnt].QuotePrice.Equals(position.LastPrice)); } while (++cnt < fullArray.Length); position.LastSize = 0; askHeap.FindSizeAndPrice(position); Assert.True(position.LastSize.Equals(0)); }); sw.Stop(); Console.Out.WriteLine($"AskHeap Extract Time:{sw.Elapsed.TotalMilliseconds}"); }
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); }