Repository: quantopian/zipline
File: tests/test_perf_tracking.py (Python)

Code before:
            last_sale_date=dt, last_sale_price=10
        )

        # Test long-only methods
        pos_stats = pt.stats()
        self.assertEqual(100, pos_stats.long_value)
        self.assertEqual(100 + 300000, pos_stats.long_exposure)
        self.assertEqual(2, pos_stats.longs_count)

        # Test short-only methods
        self.assertEqual(-200, pos_stats.short_value)
        self.assertEqual(-200 - 400000, pos_stats.short_exposure)
        self.assertEqual(2, pos_stats.shorts_count)

        # Test gross and net values
        self.assertEqual(100 + 200, pos_stats.gross_value)
        self.assertEqual(100 - 200, pos_stats.net_value)

        # Test gross and net exposures
        self.assertEqual(100 + 200 + 300000 + 400000, pos_stats.gross_exposure)
        self.assertEqual(100 - 200 + 300000 - 400000, pos_stats.net_exposure)

    def test_cost_basis(self):
        dt = pd.Timestamp("2015-12-10 15:00", tz='UTC')

        long_equity_pos = perf.Position(
            self.EQUITY1,
            amount=10,
            last_sale_date=dt,
            cost_basis=10,
            last_sale_price=11,
        )

        short_equity_pos = perf.Position(
            self.EQUITY1,
            amount=-10,
            last_sale_date=dt,
            cost_basis=10,
            last_sale_price=11,
        )

        long_future_pos = perf.Position(
            self.FUTURE3,
            amount=10,
            last_sale_date=dt,
            cost_basis=10,
            last_sale_price=11,
        )

        short_future_pos = perf.Position(
            self.FUTURE3,

Review comment (bug):
This test may benefit from using `nose.parameterized` on the product of ('equity', 'future') and ('long', 'short').

(While poking around with the implementation of `adjust_commission_cost_basis` it would have been useful to have the cases fail independently.)

Code after:
            self.FUTURE4, amount=np.float64(-40.0),
            last_sale_date=dt, last_sale_price=10
        )

        # Test long-only methods
        pos_stats = pt.stats()
        self.assertEqual(100, pos_stats.long_value)
        self.assertEqual(100 + 300000, pos_stats.long_exposure)
        self.assertEqual(2, pos_stats.longs_count)

        # Test short-only methods
        self.assertEqual(-200, pos_stats.short_value)
        self.assertEqual(-200 - 400000, pos_stats.short_exposure)
        self.assertEqual(2, pos_stats.shorts_count)

        # Test gross and net values
        self.assertEqual(100 + 200, pos_stats.gross_value)
        self.assertEqual(100 - 200, pos_stats.net_value)

        # Test gross and net exposures
        self.assertEqual(100 + 200 + 300000 + 400000, pos_stats.gross_exposure)
        self.assertEqual(100 - 200 + 300000 - 400000, pos_stats.net_exposure)

    @parameterized.expand([('FutureLong', True, 1),
                           ('FutureShort', True, -1),
                           ('EquityLong', False, 1),
                           ('EquityShort', False, -1)])
    def test_cost_basis(self, _, is_future, sign):

        asset = self.FUTURE3 if is_future else self.EQUITY1
        dt = pd.Timestamp("2015-12-10 15:00", tz='UTC')

        position = perf.Position(
            asset,
            amount=sign*10,
            last_sale_date=dt,
            cost_basis=10,
            last_sale_price=11,
        )

        self.assertEqual(10, position.cost_basis)

        # If position is an equity position:
        # send a $5 commission to the equity position.  Spread out over 10
        # shares, that bumps the cost basis by $0.50.
        #
        # If position is a futures position:
        # send a $5k commission to the futures position.  since self.FUTURE3
        # has a contract size (multipler) of 1000, this should result in a
        # $10.5 updated cost basis. (5000 / 1000 = $5, spread out over 10
        # contracts, is $0.50 extra per contract).