public void When_Updating_Account_With_Sell_Transaction_With_More_Shares_Than_Position_Then_Exception_Is_Thrown()
        {
            // setup
            Security goog = new Security {
                Symbol = "goog"
            };
            var portfolio = TestDataGenerator.GenerateEmptyPortfolio();
            var mandingo  = portfolio.Accounts.Single(a => a.Name.Equals("mandingo", StringComparison.InvariantCultureIgnoreCase));

            mandingo.Positions.Add(new Position
            {
                Account  = mandingo,
                Shares   = 1M,
                Security = goog
            });
            var portfolioService = new PortfolioService(portfolio);
            var transaction      = new Transaction
            {
                Account  = mandingo,
                Date     = DateTime.UtcNow,
                Price    = 0M,
                Security = goog,
                Shares   = 10M,
                Type     = TransactionType.Sell
            };

            // verify
            try
            {
                portfolioService.UpdateWith(new List <Transaction> {
                    transaction
                });
            }
            catch (Exception ex)
            {
                Assert.That(ex.Message, Is.EqualTo("Tried to sell more shares than the account has."));
            }
        }
Esempio n. 2
0
        public void When_StringValueReporter_Given_Valid_Portfolio_Then_Report_Is_Written_To_String()
        {
            // setup
            var portfolio = TestDataGenerator.GenerateDefaultPortfolio();

            _quoterMock.Setup(m => m.GetQuotes(It.IsAny <IEnumerable <Security> >())).Returns(new Dictionary <Security, decimal>
            {
                { new Security {
                      Symbol = "goog"
                  }, 18.25M },
                { new Security {
                      Symbol = "msft"
                  }, 15M },
                { new Security {
                      Symbol = "aapl"
                  }, 9.36M },
            });

            // execute
            var reporter = new StringValueReporter(_quoterMock.Object);
            var result   = reporter.GetReport(portfolio);

            // validate
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Is.Not.Empty);

            const string expected = @"po' boy total = 5197.00
mandingo total = 3697.00
goog: 100 x 18.25 = 1825.00
aapl: 200 x 9.36 = 1872.00
took total = 1500
msft: 100 x 15 = 1500
";

            Assert.That(result, Is.EqualTo(expected));
        }
        public void When_Updating_Account_With_Transaction_That_Already_Happened_Then_New_Transaction_Is_Ignored()
        {
            var      portfolio = TestDataGenerator.GenerateDefaultPortfolio();
            var      mandingo  = portfolio.Accounts.Single(a => a.Name.Equals("mandingo", StringComparison.InvariantCultureIgnoreCase));
            Security yvr       = new Security {
                Symbol = "yvr"
            };

            var transactions = new List <Transaction>();

            transactions.AddRange(mandingo.Transactions);
            transactions.Add(new Transaction
            {
                Account  = mandingo,
                Date     = DateTime.UtcNow,
                Price    = 10M,
                Security = yvr,
                Shares   = 50M,
                Type     = TransactionType.Buy
            });

            var portfolioService = new PortfolioService(portfolio);

            portfolioService.UpdateWith(transactions);

            Assert.That(mandingo.Transactions.Count, Is.EqualTo(3));
            var googPosition = mandingo.Positions.Single(p => p.Security.Symbol.Equals("goog", StringComparison.InvariantCultureIgnoreCase));

            Assert.That(googPosition.Shares, Is.EqualTo(100M));
            var aaplPosition = mandingo.Positions.Single(p => p.Security.Symbol.Equals("aapl", StringComparison.InvariantCultureIgnoreCase));

            Assert.That(aaplPosition.Shares, Is.EqualTo(200M));
            var yvrPosition = mandingo.Positions.Single(p => p.Security.Symbol.Equals("yvr", StringComparison.InvariantCultureIgnoreCase));

            Assert.That(yvrPosition.Shares, Is.EqualTo(50M));
        }
        public void When_Updating_Account_Then_Update_Is_Atomic()
        {
            var      portfolio = TestDataGenerator.GenerateDefaultPortfolio();
            var      mandingo  = portfolio.Accounts.Single(a => a.Name.Equals("mandingo", StringComparison.InvariantCultureIgnoreCase));
            Security yvr       = new Security {
                Symbol = "yvr"
            };
            Security goog = new Security {
                Symbol = "goog"
            };

            var transactions = new List <Transaction>(2)
            {
                new Transaction
                {
                    Account  = mandingo,
                    Date     = DateTime.UtcNow,
                    Price    = 10M,
                    Security = yvr,
                    Shares   = 100M,
                    Type     = TransactionType.Buy
                },
                new Transaction
                {
                    Account  = mandingo,
                    Date     = DateTime.UtcNow,
                    Price    = 10M,
                    Security = goog,
                    Shares   = 10M,
                    Type     = TransactionType.Sell
                },
                new Transaction
                {
                    Account  = mandingo,
                    Date     = DateTime.UtcNow,
                    Price    = 10M,
                    Security = new Security {
                        Symbol = "not_owned"
                    },
                    Shares = 100M,
                    Type   = TransactionType.Sell
                }
            };

            var portfolioService = new PortfolioService(portfolio);

            Assert.Throws <Exception>(() => portfolioService.UpdateWith(transactions));

            Assert.That(mandingo.Positions.Count, Is.EqualTo(2));
            var googPosition = mandingo.Positions.Single(p => p.Security.Symbol.Equals(goog.Symbol, StringComparison.InvariantCultureIgnoreCase));

            Assert.That(googPosition.Shares, Is.EqualTo(100M));
            var aaplPosition = mandingo.Positions.Single(p => p.Security.Symbol.Equals("aapl", StringComparison.InvariantCultureIgnoreCase));

            Assert.That(aaplPosition.Shares, Is.EqualTo(200M));

            var took         = portfolio.Accounts.Single(a => a.Name.Equals("took", StringComparison.InvariantCultureIgnoreCase));
            var msftPosition = took.Positions.Single(p => p.Security.Symbol.Equals("msft", StringComparison.InvariantCultureIgnoreCase));

            Assert.That(msftPosition.Shares, Is.EqualTo(100M));
        }
        public void When_Updating_Empty_Portfolio_With_Transactions_Then_Portfolio_Is_Updated_To_Correct_State()
        {
            // setup
            var      portfolio        = TestDataGenerator.GenerateEmptyPortfolio();
            var      portfolioService = new PortfolioService(portfolio);
            var      mandingo         = portfolio.Accounts.Single(a => a.Name.Equals("mandingo", StringComparison.InvariantCultureIgnoreCase));
            var      took             = portfolio.Accounts.Single(a => a.Name.Equals("took", StringComparison.InvariantCultureIgnoreCase));
            Security goog             = new Security {
                Symbol = "goog"
            };
            Security msft = new Security {
                Symbol = "msft"
            };
            var transactionDate = DateTime.UtcNow;

            var transactions = new List <Transaction>();

            transactions.Add(new Transaction
            {
                Account  = mandingo,
                Date     = transactionDate,
                Price    = 15.25M,
                Security = goog,
                Shares   = 100M,
                Type     = TransactionType.Buy
            });
            transactions.Add(new Transaction()
            {
                Account  = took,
                Date     = transactionDate.AddMinutes(14),
                Price    = 21.54M,
                Security = msft,
                Shares   = 50M,
                Type     = TransactionType.Sell
            });
            transactions.Add(new Transaction()
            {
                Account  = took,
                Date     = transactionDate,
                Price    = 21.34M,
                Security = msft,
                Shares   = 200M,
                Type     = TransactionType.Buy
            });

            // execute
            portfolioService.UpdateWith(transactions);

            // verify
            Assert.That(mandingo.Transactions.Count, Is.EqualTo(1));
            Assert.That(mandingo.Positions.Count, Is.EqualTo(1));
            var position = mandingo.Positions.Single();

            Assert.That(position.Security.Symbol, Is.EqualTo(goog.Symbol));
            Assert.That(position.Account, Is.EqualTo(mandingo));
            Assert.That(position.Shares, Is.EqualTo(100M));

            Assert.That(took.Transactions.Count, Is.EqualTo(2));
            Assert.That(took.Positions.Count, Is.EqualTo(1));
            position = took.Positions.Single();
            Assert.That(position.Security.Symbol, Is.EqualTo(msft.Symbol));
            Assert.That(position.Account, Is.EqualTo(took));
            Assert.That(position.Shares, Is.EqualTo(150M));
        }