public void EfficientFx_Calculate_Decending()
        {
            // Arrange
            var fx          = new EfficientFx();
            var stockPrices = new[]
            {
                sp(1, 94.35m),
                sp(2, 94.06m),
                sp(3, 93.51m),
                sp(4, 93.50m),  // Buy
                sp(5, 93.50m),  // Sell -- The maximum possible profit is zero.
                sp(6, 93.23m),
                sp(7, 93.06m),
                sp(8, 92.85m),
                sp(9, 92.31m),
                sp(10, 91.99m)
            };

            // Act
            var order = fx.Calculate(stockPrices);

            // Assert
            Assert.IsNotNull(order);
            Assert.AreEqual(sp(4, 93.50m), order.Buy);
            Assert.AreEqual(sp(5, 93.50m), order.Sell);
        }
        public void EfficientFx_Calculate_CallsGetSellPrices()
        {
            // Arrange
            var svc = Substitute.ForPartsOf <EfficientService>();
            var getSellPricesInput = string.Empty;

            svc.When(x => x.GetSellPrices(Arg.Any <StockPrice[]>()))
            .Do(info => getSellPricesInput = ToString(info.ArgAt <StockPrice[]>(0)));
            var fx          = new EfficientFx(svc);
            var stockPrices = new[]
            {
                sp(1, 1),
                sp(2, 5),
                sp(3, 3),
                sp(4, 4),
                sp(5, 7)
            };

            // Act
            fx.Calculate(stockPrices);

            // Assert
            svc.Received().GetSellPrices(Arg.Any <StockPrice[]>());
            Assert.AreEqual(
                "(1, 1)(2, 5)(3, 3)(4, 4)(5, 7)",
                getSellPricesInput);
        }
        public void EfficientFx_Calculate_SortsStockPrices()
        {
            // We can tell whether or not the StockPrices have been sorted by
            // observing what has been passed to the GetSellPrices method.

            // Arrange
            var svc = Substitute.ForPartsOf <EfficientService>();
            var getSellPricesInput = string.Empty;

            svc.When(x => x.GetSellPrices(Arg.Any <StockPrice[]>()))
            .Do(info => getSellPricesInput = ToString(info.ArgAt <StockPrice[]>(0)));
            var fx          = new EfficientFx(svc);
            var stockPrices = new[]
            {
                sp(4, 1),   // Prices don't matter here.
                sp(1, 1),
                sp(3, 1),
                sp(2, 1),
                sp(5, 1)
            };

            // Act
            fx.Calculate(stockPrices);

            // Assert
            Assert.AreEqual(
                "(1, 1)(2, 1)(3, 1)(4, 1)(5, 1)",
                getSellPricesInput);
        }
        public void EfficientFx_Calculate_Returns()
        {
            // Arrange
            var svc = Substitute.ForPartsOf <EfficientService>();
            var sb  = new StringBuilder();

            svc.When(x => x.ChooseBestOrder(Arg.Any <Order>(), Arg.Any <Order>()))
            .Do(info => {
                sb.Append(ToShortString(info.ArgAt <Order>(0)))
                .Append(ToShortString(info.ArgAt <Order>(1)))
                .Append(";");
            });
            var fx          = new EfficientFx(svc);
            var stockPrices = new[]
            {
                sp(1, 1),
                sp(2, 5),
                sp(3, 3),
                sp(4, 4),
                // An order can't be created from buying on the last date in
                // the list, so this one shouldn't be present.
                sp(5, 7)
            };

            // Act
            var result = fx.Calculate(stockPrices);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(sp(1, 1), result.Buy);
            Assert.AreEqual(sp(5, 7), result.Sell);
        }
        public void EfficientFx_Calculate_CallsPopSellPrices()
        {
            // Arrange
            var svc = Substitute.ForPartsOf <EfficientService>();
            var sb  = new StringBuilder();

            svc.When(x => x.PopSellPrices(Arg.Any <Stack <StockPrice> >(), Arg.Any <DateTime>()))
            .Do(info =>
                sb.Append(info.ArgAt <DateTime>(1).ToString("yyyy-MM-dd"))
                .Append(";")
                );
            var fx          = new EfficientFx(svc);
            var stockPrices = new[]
            {
                sp(1, 1),
                sp(2, 5),
                sp(3, 3),
                sp(4, 4),
                // An order can't be created from buying on the last date in
                // the list, so this one shouldn't be present.
                sp(5, 7)
            };

            // Act
            fx.Calculate(stockPrices);

            // Assert
            Assert.AreEqual(
                "2019-01-01;2019-01-02;2019-01-03;2019-01-04;",
                sb.ToString()
                );
        }
        public void EfficientFx_Calculate_ThrowsOnNullStockPrices()
        {
            // Arrange
            var fx = new EfficientFx();

            // Act
            fx.Calculate(null);
        }
        public void EfficientFx_Calculate_ThrowsWhenStockPricesCountLessThanTwo()
        {
            // Arrange
            var fx          = new EfficientFx();
            var stockPrices = new[]
            {
                sp(1, 1)
            };

            // Act
            fx.Calculate(stockPrices);
        }
        public void EfficientFx_Calculate_TwoPotentialBuyDates()
        {
            // Arrange
            var fx          = new EfficientFx();
            var stockPrices = new[]
            {
                sp(1, 91.00m),
                sp(2, 90.00m), // Don't buy. Too early.
                sp(3, 90.00m), // Buy
                sp(4, 92.00m),
                sp(5, 95.00m)  // Sell
            };

            // Act
            var order = fx.Calculate(stockPrices);

            // Assert
            Assert.IsNotNull(order);
            Assert.AreEqual(sp(3, 90.00m), order.Buy);
            Assert.AreEqual(sp(5, 95.00m), order.Sell);
        }
 public void EfficientFx_CtorSvc_ThrowsOnNullSvc()
 {
     // Act
     var fx = new EfficientFx(null);
 }