Esempio n. 1
0
    def test_stock_price_earnings_ratio(self):
        """
        Tests correct price-earnings calculation for both `common` and
        `preferred` stock types.
        """

        # Make a mock object for testing.
        sALE = Stock('ALE', 'common', 23, nan, 60)
        # Add some mock Trades.
        sALE.buy(500, 25)
        sALE.sell(300, 15)
        self.assertEqual(len(sALE._trades), 2)
        # Make a mock object for testing.
        sGIN = Stock('GIN', 'preferred', 8, 0.02, 100)
        # Add some mock Trades.
        sGIN.buy(320, 95)
        sGIN.sell(180, 110)
        self.assertEqual(len(sGIN._trades), 2)

        # `ALE` stock should use the last_dividend as dividend
        self.assertEqual(sALE.price_earnings_ratio(),
                         ((500*25+300*15)/(500+300)) / 23.)

        # But `GIN` stock should the fixed_dividend * par_value as dividend
        self.assertEqual(sGIN.price_earnings_ratio(),
                         ((320*95+180*110)/(320+180)) / (0.02 * 100))
Esempio n. 2
0
    def test_stock_dividend_yield_preferred(self):
        """
        Tests correct dividend yield calculation for `preferred` stock types.
        """

        # Make a mock object for testing.
        sGIN = Stock('GIN', 'preferred', 8, 0.02, 100)

        # A stock without trades has a default ticker price equal to its par
        # value. In this case, `preferred` stock types should have a price
        # earnings ratio equal to their par value.
        self.assertEqual(sGIN.dividend_yield(), 0.02)

        # Add some mock Trades.
        sGIN.buy(320, 95)
        sGIN.sell(180, 110)
        self.assertEqual(len(sGIN._trades), 2)

        # `preferred` stocks should not use the `common` calculation for
        # dividend yields...
        self.assertNotEqual(sGIN.dividend_yield(),
                            8 / ((320*95 + 180*110) / (320+180)))

        # ... instead, they should use the `preferred` calculation.
        self.assertEqual(sGIN.dividend_yield(),
                         (0.02 * 100) / ((320*95 + 180*110) / (320+180)))
Esempio n. 3
0
    def test_stock_price_no_recent(self):
        """
        Tests stock (ticker) price calculation for the case with no recent
        trades.
        """

        # Make a mock object for testing.
        sALE = Stock('ALE', 'common', 23, nan, 60)

        # A stock without trades has a ticker price equal to its par value.
        self.assertEqual(sALE.stock_price(), 60)

        # Add some mock Trades between -30 and -15 minutes relative to now.
        sALE.buy(500, 25,
                 datetime.datetime.now() - datetime.timedelta(minutes=16))
        sALE.sell(300, 15,
                  datetime.datetime.now() - datetime.timedelta(minutes=22))
        self.assertEqual(len(sALE._trades), 2)

        # Now add some mock Trades prior to 30 minutes in the past.
        sALE.buy(250, 33,
                 datetime.datetime.now() - datetime.timedelta(minutes=35))
        sALE.sell(125, 55,
                  datetime.datetime.now() - datetime.timedelta(minutes=39))
        self.assertEqual(len(sALE._trades), 4)

        # Since the latest trade happened at -16 minutes relative to now, the
        # time window in which to calculate the stock price is [-29, -14].
        self.assertEqual(sALE.stock_price(),
                         ((500*25 + 300*15) / (500+300)))
Esempio n. 4
0
    def test_stock_dividend_yield_common(self):
        """
        Tests correct dividend yield calculation for `common` stock types.
        """

        # Make a mock object for testing.
        sALE = Stock('ALE', 'common', 23, nan, 60)

        # A stock without trades has a default ticker price equal to its par
        # value.
        self.assertEqual(sALE.dividend_yield(), 23. / 60)

        # Add some mock Trades.
        sALE.buy(500, 25)
        sALE.sell(300, 15)
        self.assertEqual(len(sALE._trades), 2)

        # The dividend yield calculation should now use a ticker price
        # determined from the average trading price.
        self.assertEqual(sALE.dividend_yield(), 23. /
                         (((500*25)+(300*15))/(500+300)))
Esempio n. 5
0
    def test_stock_price(self):
        """
        Tests stock (ticker) price calculation.
        """

        # Make a mock object for testing.
        sALE = Stock('ALE', 'common', 23, nan, 60)

        # A stock without trades has a ticker price equal to its par value.
        self.assertEqual(sALE.stock_price(), 60)

        # Add some mock Trades.
        sALE.buy(500, 25)
        sALE.sell(300, 15)
        self.assertEqual(len(sALE._trades), 2)

        # Easy case for ticker price with two Trades.
        self.assertEqual(sALE.stock_price(), ((500*25)+(300*15))/(500+300))

        # Add some mock Trades in the distant past (such that they are excluded
        # from the average).
        sALE.buy(100, 87, datetime.datetime.now() -
                 datetime.timedelta(minutes=16))
        sALE.buy(23, 34, datetime.datetime.now() -
                 datetime.timedelta(minutes=15))
        self.assertEqual(len(sALE._trades), 4)

        # Stock price should be unchanged.
        self.assertEqual(sALE.stock_price(), ((500*25)+(300*15))/(500+300))
Esempio n. 6
0
    def test_stock_buy_sell(self):
        """
        Test buying and selling stocks.
        """

        # Make a mock object for testing.
        # NOTE there are better ways to do this!
        sALE = Stock('ALE', 'common', 23, nan, 60)

        # Trade price should not be a string.
        with self.assertRaises(AssertionError):
            sALE.buy(500, 55, '2017 06 05 13 42 00')
        # Trade price should not be negative.
        with self.assertRaises(AssertionError):
            sALE.buy(500, -23)
        # Trade price should not be a float.
        with self.assertRaises(AssertionError):
            sALE.buy(500, 123.0)
        # Trade price should not be a string.
        with self.assertRaises(AssertionError):
            sALE.sell(500, 55, '2017 06 05 13 42 00')
        # Trade price should not be negative.
        with self.assertRaises(AssertionError):
            sALE.sell(500, -23)
        # Trade price should not be a float.
        with self.assertRaises(AssertionError):
            sALE.sell(500, 123.0)

        # `Buy` records should have a `+1` number in the buy_sell tuple record.
        sALE.buy(500, 25)
        self.assertEqual(sALE._trades[-1].buy_sell, 1)
        # `Sell` records should have a `-1` number in the buy_sell tuple record.
        sALE.sell(300, 15)
        self.assertEqual(sALE._trades[-1].buy_sell, -1)

        # Trading cannot happen in the future.
        with self.assertRaises(AssertionError):
            sALE.buy(500, 25,
                     datetime.datetime.now() + datetime.timedelta(minutes=1))