public void HandlerUsesAccuracyDictionary() { DateTime dt = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc); const string asset1 = "btcusd"; const string asset2 = "eurusd"; var env = new EnvironmentStub(new List <AssetPair>() { new AssetPair() { Id = asset1, Accuracy = 5 }, new AssetPair() { Id = asset2, Accuracy = 3 } }); var def = new DefaultHandler(null); var handler = new MidHandler(env, def); Queue <QuoteExt> queue = new Queue <QuoteExt>(); handler.Handle(new QuoteExt() { AssetPair = asset1, IsBuy = false, Price = 1.12345, Timestamp = dt, PriceType = PriceType.Ask }, queue).Wait(); handler.Handle(new QuoteExt() { AssetPair = asset1, IsBuy = true, Price = 2.54321, Timestamp = dt.AddSeconds(1), PriceType = PriceType.Bid }, queue).Wait(); handler.Handle(new QuoteExt() { AssetPair = asset2, IsBuy = false, Price = 1.1111, Timestamp = dt, PriceType = PriceType.Ask }, queue).Wait(); handler.Handle(new QuoteExt() { AssetPair = asset2, IsBuy = true, Price = 2.2222, Timestamp = dt.AddSeconds(1), PriceType = PriceType.Bid }, queue).Wait(); Assert.Equal(6, queue.Count); // Check output queue var mid = queue.ToList().Where(q => q.PriceType == PriceType.Mid).ToList(); Assert.Equal(2, mid.Count); mid[0].IsEqual(new QuoteExt() { AssetPair = asset1, Price = 1.83333, Timestamp = dt, PriceType = PriceType.Mid }); mid[1].IsEqual(new QuoteExt() { AssetPair = asset2, Price = 1.667, Timestamp = dt, PriceType = PriceType.Mid }); }
public void NoExceptionExpectedOnMultithread() { var logger = new LoggerStub(); var candlesRepo = new CandleHistoryRepositoryStub(); var env = new EnvironmentStub(new List <AssetPair>() { new AssetPair() { Id = "btcusd", Accuracy = 5 } }); var controller = new CandleGenerationController(candlesRepo, logger, "test component", env); // Cancel after 1 sec CancellationTokenSource tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(2)); CancellationToken token = tokenSource.Token; int consumeCalledTimes = 0; int tickCalledTimes = 0; // Call Consume and Tick methods at the same time repeatedly and check that there was no exception. Task producing = Task.Run(async() => { while (!token.IsCancellationRequested) { await controller.HandleQuote(new Quote() { AssetPair = "btcusd", IsBuy = true, Price = 100, Timestamp = DateTime.UtcNow }); await Task.Delay(50); Interlocked.Increment(ref consumeCalledTimes); } }, token); Task timer = Task.Run(() => { while (!token.IsCancellationRequested) { controller.Tick(); Interlocked.Increment(ref tickCalledTimes); } }, token); Task.WaitAll(producing, timer); Assert.True(consumeCalledTimes > 0); Assert.True(tickCalledTimes > 0); Assert.True(candlesRepo.Stored.Count > 0); }
public void HandlerChecksTimestamp() { DateTime dt = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc); const string asset = "btcusd"; var env = new EnvironmentStub(new List <AssetPair>() { new AssetPair() { Id = asset, Accuracy = 5 } }); var def = new DefaultHandler(null); var handler = new MidHandler(env, def); Queue <QuoteExt> queue = new Queue <QuoteExt>(); handler.Handle(new QuoteExt() { AssetPair = asset, IsBuy = false, Price = 1, Timestamp = dt, PriceType = PriceType.Ask }, queue).Wait(); Assert.Equal(1, queue.Count); queue.Clear(); handler.Handle(new QuoteExt() { AssetPair = asset, IsBuy = true, Price = 2, Timestamp = dt.AddSeconds(1), PriceType = PriceType.Bid }, queue).Wait(); Assert.Equal(2, queue.Count); // Check output queue queue.ToArray()[0].IsEqual(new QuoteExt() { AssetPair = asset, Price = 1.5, Timestamp = dt, PriceType = PriceType.Mid }); queue.Clear(); // Old time quote should not affect computing. Though a new Mid quote is still generated. handler.Handle(new QuoteExt() { AssetPair = asset, IsBuy = false, Price = 3, Timestamp = dt.AddSeconds(-1), PriceType = PriceType.Ask }, queue).Wait(); Assert.Equal(2, queue.Count); queue.ToArray()[0].IsEqual(new QuoteExt() { AssetPair = asset, Price = 1.5, Timestamp = dt, PriceType = PriceType.Mid }); }