public void InvalidDateIsIgnored()
        {
            LoggerStub          logger     = new LoggerStub();
            QuotePublisherStub  publisher  = new QuotePublisherStub();
            QuoteFeedController controller = new QuoteFeedController(publisher, logger);

            DateTime unspecified = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
            DateTime local       = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Local);

            controller.ProcessOrderbook(CreateOrder("btc", true, unspecified, new VolumePrice[] { new VolumePrice()
                                                                                                  {
                                                                                                      Volume = 1, Price = 100
                                                                                                  } })).Wait();
            controller.ProcessOrderbook(CreateOrder("btc", true, local, new VolumePrice[] { new VolumePrice()
                                                                                            {
                                                                                                Volume = 1, Price = 100
                                                                                            } })).Wait();
            controller.ProcessOrderbook(CreateOrder("btc", true, DateTime.MinValue, new VolumePrice[] { new VolumePrice()
                                                                                                        {
                                                                                                            Volume = 1, Price = 100
                                                                                                        } })).Wait();
            controller.ProcessOrderbook(CreateOrder("btc", true, DateTime.MaxValue, new VolumePrice[] { new VolumePrice()
                                                                                                        {
                                                                                                            Volume = 1, Price = 100
                                                                                                        } })).Wait();
            Assert.Equal(0, publisher.Published.Count);
        }
예제 #2
0
        public void MultipleOrdersShouldBeProcessedConsecutively()
        {
            LoggerStub logger = new LoggerStub();
            // Assume that publisher execution takes some time (random number of seconds)
            QuotePublisherStub publisher = new QuotePublisherStub(async(Quote q) => {
                int duration = new Random().Next(1, 3);
                await Task.Delay(TimeSpan.FromSeconds(duration));
            });
            QuoteFeedController controller = new QuoteFeedController(publisher, logger);

            // Produce multiple orders and wait for publishing
            List <Task> tasks = new List <Task>(TASKS_COUNT);

            for (int i = 0; i < TASKS_COUNT; i++)
            {
                var task = controller.ProcessOrderbook(CreateOrder("btc", true, Utils.ParseUtc("2017-01-01 10:10:12Z"),
                                                                   new[] { new VolumePrice()
                                                                           {
                                                                               Volume = 1, Price = i
                                                                           } }));
                tasks.Add(task);
            }

            Task.WaitAll(tasks.ToArray());

            // There should be the same number of events as the number of incoming orders.
            // If orders were processed in different order, there would be less events
            // as the price is constantly increasing.
            Assert.Equal(TASKS_COUNT, publisher.Published.Count);
        }
        public void NullIsIgnored()
        {
            LoggerStub          logger     = new LoggerStub();
            QuotePublisherStub  publisher  = new QuotePublisherStub();
            QuoteFeedController controller = new QuoteFeedController(publisher, logger);

            controller.ProcessOrderbook(null).Wait();
            Assert.Equal(0, publisher.Published.Count);
        }
예제 #4
0
        public void QuoteIsUpdatedWhenDateIsEqualAndBestPrice()
        {
            LoggerStub          logger     = new LoggerStub();
            QuotePublisherStub  publisher  = new QuotePublisherStub();
            QuoteFeedController controller = new QuoteFeedController(publisher, logger);

            // BTCUSD / BUY, 1st order
            controller.ProcessOrderbook(CreateOrder("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:10Z"), new[] {
                new VolumePrice()
                {
                    Volume = 1, Price = 999
                }, new VolumePrice()
                {
                    Volume = 1, Price = 1000
                }
            })).Wait();

            Assert.Equal(1, publisher.Published.Count);
            publisher.Published.Last().Equals(CreateQuote("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:10Z"), 1000.0));

            // BTCUSD / BUY, 2nd order
            controller.ProcessOrderbook(CreateOrder("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:10Z"), new[] {
                new VolumePrice()
                {
                    Volume = 1, Price = 1001
                }
            })).Wait();

            Assert.Equal(2, publisher.Published.Count);
            publisher.Published.Last().Equals(CreateQuote("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:10Z"), 1001.0));

            // BTCRUB / SELL, 1st order
            controller.ProcessOrderbook(CreateOrder("btcrub", false, Utils.ParseUtc("2017-01-02 10:10:10Z"), new[] {
                new VolumePrice()
                {
                    Volume = 1, Price = 50
                }, new VolumePrice()
                {
                    Volume = 1, Price = 60
                }
            })).Wait();

            Assert.Equal(3, publisher.Published.Count);
            publisher.Published.Last().Equals(CreateQuote("btcrub", false, Utils.ParseUtc("2017-01-02 10:10:10Z"), 50));

            // BTCRUB / SELL, 2nd order
            controller.ProcessOrderbook(CreateOrder("btcrub", false, Utils.ParseUtc("2017-01-02 10:10:10Z"), new[] {
                new VolumePrice()
                {
                    Volume = 1, Price = 40
                }
            })).Wait();

            Assert.Equal(4, publisher.Published.Count);
            publisher.Published.Last().Equals(CreateQuote("btcrub", false, Utils.ParseUtc("2017-01-02 10:10:10Z"), 40));
        }
        public void EmptyPricesIsIgnored()
        {
            LoggerStub          logger     = new LoggerStub();
            QuotePublisherStub  publisher  = new QuotePublisherStub();
            QuoteFeedController controller = new QuoteFeedController(publisher, logger);

            controller.ProcessOrderbook(CreateOrder("btc", true, Utils.ParseUtc("2017-01-01 10:10:12Z"), null)).Wait();
            controller.ProcessOrderbook(CreateOrder("btc", true, Utils.ParseUtc("2017-01-01 10:10:12Z"), new VolumePrice[] { })).Wait();
            Assert.Equal(0, publisher.Published.Count);
        }
        public void GeneratedQuotesHaveUtcKind()
        {
            LoggerStub          logger     = new LoggerStub();
            QuotePublisherStub  publisher  = new QuotePublisherStub();
            QuoteFeedController controller = new QuoteFeedController(publisher, logger);

            // BTCUSD / BUY, 1st order
            controller.ProcessOrderbook(CreateOrder("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:10Z"), new[] {
                new VolumePrice()
                {
                    Volume = 1, Price = 999
                }, new VolumePrice()
                {
                    Volume = 1, Price = 1000
                }
            })).Wait();

            Assert.Equal(1, publisher.Published.Count);
            publisher.Published.Last().Equals(CreateQuote("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:10Z"), 1000.0));

            // BTCUSD / BUY, 2nd order
            controller.ProcessOrderbook(CreateOrder("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:11Z"), new[] {
                new VolumePrice()
                {
                    Volume = 1, Price = 1001
                }, new VolumePrice()
                {
                    Volume = 1, Price = 999
                }
            })).Wait();

            Assert.Equal(2, publisher.Published.Count);
            publisher.Published.Last().Equals(CreateQuote("btcusd", true, Utils.ParseUtc("2017-01-01 10:10:11Z"), 1001.0));

            /// Check Kind
            foreach (var quote in publisher.Published)
            {
                Assert.Equal(0, quote.Timestamp.Kind.CompareTo(DateTimeKind.Utc));
            }
        }