def test_algo_with_rl_violation(self):
        sim_params = factory.create_simulation_parameters(start=list(
            LEVERAGED_ETFS.keys())[0],
                                                          num_days=4)

        trade_history = factory.create_trade_history('BZQ',
                                                     [10.0, 10.0, 11.0, 11.0],
                                                     [100, 100, 100, 300],
                                                     timedelta(days=1),
                                                     sim_params)
        self.source = SpecificEquityTrades(event_list=trade_history)

        algo = RestrictedAlgoWithoutCheck(symbol='BZQ', sim_params=sim_params)
        with self.assertRaises(TradingControlViolation) as ctx:
            algo.run(self.source)

        self.check_algo_exception(algo, ctx, 0)

        # repeat with a symbol from a different lookup date

        trade_history = factory.create_trade_history('JFT',
                                                     [10.0, 10.0, 11.0, 11.0],
                                                     [100, 100, 100, 300],
                                                     timedelta(days=1),
                                                     sim_params)
        self.source = SpecificEquityTrades(event_list=trade_history)

        algo = RestrictedAlgoWithoutCheck(symbol='JFT', sim_params=sim_params)
        with self.assertRaises(TradingControlViolation) as ctx:
            algo.run(self.source)

        self.check_algo_exception(algo, ctx, 0)
Example #2
0
    def test_algo_with_rl_violation(self):
        sim_params = factory.create_simulation_parameters(
            start=list(LEVERAGED_ETFS.keys())[0], num_days=4)

        trade_history = factory.create_trade_history(
            'BZQ',
            [10.0, 10.0, 11.0, 11.0],
            [100, 100, 100, 300],
            timedelta(days=1),
            sim_params
        )
        self.source = SpecificEquityTrades(event_list=trade_history)

        algo = RestrictedAlgoWithoutCheck(symbol='BZQ', sim_params=sim_params)
        with self.assertRaises(TradingControlViolation) as ctx:
            algo.run(self.source)

        self.check_algo_exception(algo, ctx, 0)

        # repeat with a symbol from a different lookup date

        trade_history = factory.create_trade_history(
            'JFT',
            [10.0, 10.0, 11.0, 11.0],
            [100, 100, 100, 300],
            timedelta(days=1),
            sim_params
        )
        self.source = SpecificEquityTrades(event_list=trade_history)

        algo = RestrictedAlgoWithoutCheck(symbol='JFT', sim_params=sim_params)
        with self.assertRaises(TradingControlViolation) as ctx:
            algo.run(self.source)

        self.check_algo_exception(algo, ctx, 0)
Example #3
0
    def test_tracker(self):

        trade_count = 100
        sid = 133
        price = 10.1
        price_list = [price] * trade_count
        volume = [100] * trade_count
        trade_time_increment = datetime.timedelta(days=1)
        trade_history = factory.create_trade_history(sid, price_list, volume,
                                                     trade_time_increment,
                                                     self.trading_environment)

        sid2 = 134
        price2 = 12.12
        price2_list = [price2] * trade_count
        trade_history2 = factory.create_trade_history(sid2, price2_list,
                                                      volume,
                                                      trade_time_increment,
                                                      self.trading_environment)

        trade_history.extend(trade_history2)

        self.trading_environment.period_start = trade_history[0].dt
        self.trading_environment.period_end = trade_history[-1].dt
        self.trading_environment.capital_base = 1000.0
        self.trading_environment.frame_index = [
            'sid', 'volume', 'dt', 'price', 'changed'
        ]
        perf_tracker = perf.PerformanceTracker(self.trading_environment)

        for event in trade_history:
            #create a transaction for all but
            #first trade in each sid, to simulate None transaction
            if (event.dt != self.trading_environment.period_start):
                txn = ndict({
                    'sid': event.sid,
                    'amount': -25,
                    'dt': event.dt,
                    'price': 10.0,
                    'commission': 0.50
                })
            else:
                txn = None
            event['TRANSACTION'] = txn
            perf_tracker.process_event(event)

        #we skip two trades, to test case of None transaction
        txn_count = len(trade_history) - 2
        self.assertEqual(perf_tracker.txn_count, txn_count)

        cumulative_pos = perf_tracker.cumulative_performance.positions[sid]
        expected_size = txn_count / 2 * -25
        self.assertEqual(cumulative_pos.amount, expected_size)

        self.assertEqual(
            perf_tracker.period_end.replace(hour=0, minute=0, second=0),
            perf_tracker.cumulative_risk_metrics.end_date)
    def test_ending_before_pay_date(self):
        # post some trades in the market
        events = factory.create_trade_history(
            1, [10, 10, 10, 10, 10], [100, 100, 100, 100, 100], oneday, self.sim_params
        )

        pay_date = self.sim_params.first_open
        # find pay date that is much later.
        for i in xrange(30):
            pay_date = factory.get_next_trading_dt(pay_date, oneday)
        dividend = factory.create_dividend(1, 10.00, events[0].dt, events[1].dt, pay_date)

        buy_txn = create_txn(1, 10.0, 100, events[1].dt)
        events.insert(2, buy_txn)
        events.insert(1, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 5)
        cumulative_returns = [event["cumulative_perf"]["returns"] for event in results]
        self.assertEqual(cumulative_returns, [0, 0, 0, 0.0, 0.0])
        daily_returns = [event["daily_perf"]["returns"] for event in results]
        self.assertEqual(daily_returns, [0, 0, 0, 0, 0])
        cash_flows = [event["daily_perf"]["capital_used"] for event in results]
        self.assertEqual(cash_flows, [0, -1000, 0, 0, 0])
        cumulative_cash_flows = [event["cumulative_perf"]["capital_used"] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, -1000, -1000, -1000, -1000])
Example #5
0
    def test_returns(self):
        # Daily returns.
        returns = Returns(1)

        transformed = list(returns.transform(self.source))
        tnfm_vals = [message.tnfm_value for message in transformed]

        # No returns for the first event because we don't have a
        # previous close.
        expected = [0.0, 0.0, 0.1, 0.0]

        assert tnfm_vals == expected

        # Two-day returns.  An extra kink here is that the
        # factory will automatically skip a weekend for the
        # last event. Results shouldn't notice this blip.

        trade_history = factory.create_trade_history(
            133, [10.0, 15.0, 13.0, 12.0, 13.0], [100, 100, 100, 300, 100],
            timedelta(days=1), self.trading_environment)
        self.source = SpecificEquityTrades(event_list=trade_history)

        returns = StatefulTransform(Returns, 2)

        transformed = list(returns.transform(self.source))
        tnfm_vals = [message.tnfm_value for message in transformed]

        expected = [
            0.0, 0.0, (13.0 - 10.0) / 10.0, (12.0 - 15.0) / 15.0,
            (13.0 - 13.0) / 13.0
        ]

        assert tnfm_vals == expected
Example #6
0
    def test_buy_and_sell_before_ex(self):
        # post some trades in the market
        events = factory.create_trade_history(1, [10, 10, 10, 10, 10, 10],
                                              [100, 100, 100, 100, 100, 100],
                                              oneday, self.sim_params)

        dividend = factory.create_dividend(1, 10.00, events[3].dt,
                                           events[4].dt, events[5].dt)

        buy_txn = create_txn(events[1], 10.0, 100)
        events.insert(1, buy_txn)
        sell_txn = create_txn(events[3], 10.0, -100)
        events.insert(3, sell_txn)
        events.insert(1, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 6)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0, 0, 0, 0, 0, 0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0, 0, 0, 0, 0, 0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, -1000, 1000, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, -1000, 0, 0, 0, 0])
Example #7
0
    def test_short_position_pays_dividend(self):
        # post some trades in the market
        events = factory.create_trade_history(1, [10, 10, 10, 10, 10],
                                              [100, 100, 100, 100, 100],
                                              oneday, self.sim_params)

        dividend = factory.create_dividend(
            1,
            10.00,
            # declare at open of test
            events[0].dt,
            # ex_date same as trade 2
            events[2].dt,
            events[3].dt)

        txn = create_txn(events[1], 10.0, -100)
        events.insert(1, txn)
        events.insert(0, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.0, -0.1, -0.1])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.0, -0.1, 0.0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, 1000, 0, -1000, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, 1000, 1000, 0, 0])
    def test_algo_with_rl_violation_cumulative(self):
        """
        Add a new restriction, run a test long after both
        knowledge dates, make sure stock from original restriction
        set is still disallowed.
        """
        sim_params = factory.create_simulation_parameters(
            start=list(
                LEVERAGED_ETFS.keys())[0] + timedelta(days=7), num_days=4)

        with security_list_copy():
            add_security_data(['AAPL'], [])
            trade_history = factory.create_trade_history(
                'BZQ',
                [10.0, 10.0, 11.0, 11.0],
                [100, 100, 100, 300],
                timedelta(days=1),
                sim_params,
                env=self.env,
            )
            self.source = SpecificEquityTrades(event_list=trade_history,
                                               env=self.env)
            algo = RestrictedAlgoWithoutCheck(
                symbol='BZQ', sim_params=sim_params, env=self.env)
            with self.assertRaises(TradingControlViolation) as ctx:
                algo.run(self.source)

            self.check_algo_exception(algo, ctx, 0)
    def test_no_position_receives_no_dividend(self):
        #post some trades in the market
        events = factory.create_trade_history(1, [10, 10, 10, 10, 10],
                                              [100, 100, 100, 100, 100],
                                              oneday, self.sim_params)

        dividend = factory.create_dividend(1, 10.00, events[0].dt,
                                           events[1].dt, events[2].dt)

        events.insert(1, dividend)
        perf_tracker = perf.PerformanceTracker(self.sim_params)
        transformed_events = list(
            perf_tracker.transform(((event.dt, [event]) for event in events)))

        #flatten the list of events
        results = []
        for te in transformed_events:
            for event in te[1]:
                for message in event.perf_messages:
                    results.append(message)

        perf_messages, risk = perf_tracker.handle_simulation_end()
        results.append(perf_messages[0])

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.0, 0.0, 0.0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.0, 0.0, 0.0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, 0, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, 0, 0, 0, 0])
Example #10
0
    def test_cost_basis_calc_close_pos(self):
        history_args = (
            1,
            [10, 9, 11, 8, 9, 12, 13, 14],
            [200, -100, -100, 100, -300, 100, 500, 400],
            onesec,
            self.sim_params
        )
        cost_bases = [10, 10, 0, 8, 9, 9, 13, 13.5]

        trades = factory.create_trade_history(*history_args)
        transactions = factory.create_txn_history(*history_args)

        pp = perf.PerformancePeriod(1000.0)

        for txn, cb in zip(transactions, cost_bases):
            pp.execute_transaction(txn)
            self.assertEqual(pp.positions[1].cost_basis, cb)

        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        self.assertEqual(pp.positions[1].cost_basis, cost_bases[-1])
Example #11
0
    def test_commission_zero_position(self):
        """
        Ensure no div-by-zero errors.
        """
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100],
            oneday,
            self.sim_params
        )

        # Buy and sell the same sid so that we have a zero position by the
        # time of events[3].
        txns = [
            create_txn(events[0], 20, 1),
            create_txn(events[1], 20, -1),
        ]

        # Add a cash adjustment at the time of event[3].
        cash_adj_dt = events[3].dt
        cash_adjustment = factory.create_commission(1, 300.0, cash_adj_dt)

        events.append(cash_adjustment)

        results = calculate_results(self, events, txns=txns)
        # Validate that we lost 300 dollars from our cash pool.
        self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                         9700)
Example #12
0
    def test_no_position_receives_no_dividend(self):
        # post some trades in the market
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100],
            oneday,
            self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            events[0].dt,
            events[1].dt,
            events[2].dt
        )

        results = calculate_results(
            self,
            events,
            dividend_events=[dividend],
        )

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.0, 0.0, 0.0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.0, 0.0, 0.0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, 0, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, 0, 0, 0, 0])
    def test_short_position_pays_dividend(self):
        # post some trades in the market
        events = factory.create_trade_history(
            1, [10, 10, 10, 10, 10], [100, 100, 100, 100, 100], oneday, self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            # declare at open of test
            events[0].dt,
            # ex_date same as trade 2
            events[2].dt,
            events[3].dt,
        )

        txn = create_txn(1, 10.0, -100, events[1].dt)
        events.insert(1, txn)
        events.insert(0, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 5)
        cumulative_returns = [event["cumulative_perf"]["returns"] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.0, -0.1, -0.1])
        daily_returns = [event["daily_perf"]["returns"] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.0, -0.1, 0.0])
        cash_flows = [event["daily_perf"]["capital_used"] for event in results]
        self.assertEqual(cash_flows, [0, 1000, 0, -1000, 0])
        cumulative_cash_flows = [event["cumulative_perf"]["capital_used"] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, 1000, 1000, 0, 0])
    def test_algo_with_rl_violation_cumulative(self):
        """
        Add a new restriction, run a test long after both
        knowledge dates, make sure stock from original restriction
        set is still disallowed.
        """
        sim_params = factory.create_simulation_parameters(
            start=list(LEVERAGED_ETFS.keys())[0] + timedelta(days=7),
            num_days=4)

        with security_list_copy():
            add_security_data(['AAPL'], [])
            trade_history = factory.create_trade_history(
                'BZQ',
                [10.0, 10.0, 11.0, 11.0],
                [100, 100, 100, 300],
                timedelta(days=1),
                sim_params,
                env=self.env,
            )
            self.source = SpecificEquityTrades(event_list=trade_history,
                                               env=self.env)
            algo = RestrictedAlgoWithoutCheck(symbol='BZQ',
                                              sim_params=sim_params,
                                              env=self.env)
            with self.assertRaises(TradingControlViolation) as ctx:
                algo.run(self.source)

            self.check_algo_exception(algo, ctx, 0)
Example #15
0
    def test_set_max_order_count(self):

        # Override the default setUp to use six-hour intervals instead of full
        # days so we can exercise trading-session rollover logic.
        trade_history = factory.create_trade_history(
            self.sid,
            [10.0, 10.0, 11.0, 11.0],
            [100, 100, 100, 300],
            timedelta(hours=6),
            self.sim_params
        )
        self.source = SpecificEquityTrades(event_list=trade_history)

        def handle_data(algo, data):
            for i in range(5):
                algo.order(self.sid, 1)
                algo.order_count += 1

        algo = SetMaxOrderCountAlgorithm(3)
        self.check_algo_fails(algo, handle_data, 3)

        # Second call to handle_data is the same day as the first, so the last
        # order of the second call should fail.
        algo = SetMaxOrderCountAlgorithm(9)
        self.check_algo_fails(algo, handle_data, 9)

        # Only ten orders are placed per day, so this should pass even though
        # in total more than 20 orders are placed.
        algo = SetMaxOrderCountAlgorithm(10)
        self.check_algo_succeeds(algo, handle_data, order_count=20)
Example #16
0
    def test_no_position_receives_no_dividend(self):
        # post some trades in the market
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100],
            oneday,
            self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            events[0].dt,
            events[1].dt,
            events[2].dt
        )

        events.insert(1, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.0, 0.0, 0.0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.0, 0.0, 0.0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, 0, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, 0, 0, 0, 0])
Example #17
0
    def test_commission_zero_position(self):
        """
        Ensure no div-by-zero errors.
        """
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            cash_adj_dt = self.sim_params.first_open \
                + datetime.timedelta(hours=3)
            cash_adjustment = factory.create_commission(1, 300.0,
                                                        cash_adj_dt)

            # Insert a purchase order.
            events.insert(0, create_txn(events[0], 20, 1))

            # Sell that order.
            events.insert(1, create_txn(events[1], 20, -1))

            events.insert(2, cash_adjustment)
            results = calculate_results(self, events)
            # Validate that we lost 300 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9700)
Example #18
0
    def test_commission_zero_position(self):
        """
        Ensure no div-by-zero errors.
        """
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            cash_adj_dt = self.sim_params.first_open \
                + datetime.timedelta(hours=3)
            cash_adjustment = factory.create_commission(1, 300.0,
                                                        cash_adj_dt)

            # Insert a purchase order.
            events.insert(0, create_txn(events[0], 20, 1))

            # Sell that order.
            events.insert(1, create_txn(events[1], 20, -1))

            events.insert(2, cash_adjustment)
            results = calculate_results(self, events)
            # Validate that we lost 300 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9700)
Example #19
0
    def test_moving_stddev(self):
        trade_history = factory.create_trade_history(
            133,
            [10.0, 15.0, 13.0, 12.0],
            [100, 100, 100, 100],
            timedelta(days=1),
            self.sim_params
        )

        stddev = MovingStandardDev(
            market_aware=True,
            window_length=3,
        )

        self.source = SpecificEquityTrades(event_list=trade_history)

        transformed = list(stddev.transform(self.source))

        vals = [message[stddev.get_hash()] for message in transformed]

        expected = [
            None,
            np.std([10.0, 15.0], ddof=1),
            np.std([10.0, 15.0, 13.0], ddof=1),
            np.std([15.0, 13.0, 12.0], ddof=1),
        ]

        # np has odd rounding behavior, cf.
        # http://docs.scipy.org/doc/np/reference/generated/np.std.html
        for v1, v2 in zip(vals, expected):

            if v1 is None:
                self.assertIsNone(v2)
                continue
            self.assertEquals(round(v1, 5), round(v2, 5))
Example #20
0
    def test_cost_basis_calc_close_pos(self):
        history_args = (
            1,
            [10, 9, 11, 8, 9, 12, 13, 14],
            [200, -100, -100, 100, -300, 100, 500, 400],
            onesec,
            self.sim_params
        )
        cost_bases = [10, 10, 0, 8, 9, 9, 13, 13.5]

        trades = factory.create_trade_history(*history_args)
        transactions = factory.create_txn_history(*history_args)

        pp = perf.PerformancePeriod(1000.0)

        for txn, cb in zip(transactions, cost_bases):
            pp.execute_transaction(txn)
            self.assertEqual(pp.positions[1].cost_basis, cb)

        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        self.assertEqual(pp.positions[1].cost_basis, cost_bases[-1])
Example #21
0
    def test_commission_event(self):
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            cash_adj_dt = self.sim_params.first_open \
                + datetime.timedelta(hours=3)
            cash_adjustment = factory.create_commission(1, 300.0,
                                                        cash_adj_dt)

            # Insert a purchase order.
            events.insert(0, create_txn(events[0], 20, 1))

            events.insert(1, cash_adjustment)
            results = calculate_results(self, events)
            # Validate that we lost 320 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9680)
            # Validate that the cost basis of our position changed.
            self.assertEqual(results[-1]['daily_perf']['positions']
                             [0]['cost_basis'], 320.0)
Example #22
0
    def test_ending_before_pay_date(self):
        # post some trades in the market
        events = factory.create_trade_history(1, [10, 10, 10, 10, 10],
                                              [100, 100, 100, 100, 100],
                                              oneday, self.sim_params)

        pay_date = self.sim_params.first_open
        # find pay date that is much later.
        for i in xrange(30):
            pay_date = factory.get_next_trading_dt(pay_date, oneday)
        dividend = factory.create_dividend(1, 10.00, events[0].dt,
                                           events[1].dt, pay_date)

        buy_txn = create_txn(events[1], 10.0, 100)
        events.insert(2, buy_txn)
        events.insert(1, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0, 0, 0, 0.0, 0.0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0, 0, 0, 0, 0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, -1000, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows,
                         [0, -1000, -1000, -1000, -1000])
Example #23
0
    def test_moving_stddev(self):
        trade_history = factory.create_trade_history(
            133,
            [10.0, 15.0, 13.0, 12.0],
            [100, 100, 100, 100],
            timedelta(hours=1),
            self.trading_environment
        )

        stddev = MovingStandardDev(
            market_aware=False,
            delta=timedelta(minutes=150),
        )
        self.source = SpecificEquityTrades(event_list=trade_history)

        transformed = list(stddev.transform(self.source))

        vals = [message.tnfm_value for message in transformed]

        expected = [
            None,
            np.std([10.0, 15.0], ddof=1),
            np.std([10.0, 15.0, 13.0], ddof=1),
            np.std([15.0, 13.0, 12.0], ddof=1),
        ]

        # np has odd rounding behavior, cf.
        # http://docs.scipy.org/doc/np/reference/generated/np.std.html
        for v1, v2 in zip(vals, expected):

            if v1 is None:
                assert v2 is None
                continue
            assert round(v1, 5) == round(v2, 5)
Example #24
0
    def test_moving_stddev(self):
        trade_history = factory.create_trade_history(133,
                                                     [10.0, 15.0, 13.0, 12.0],
                                                     [100, 100, 100, 100],
                                                     timedelta(hours=1),
                                                     self.trading_environment)

        stddev = MovingStandardDev(
            market_aware=False,
            delta=timedelta(minutes=150),
        )
        self.source = SpecificEquityTrades(event_list=trade_history)

        transformed = list(stddev.transform(self.source))

        vals = [message.tnfm_value for message in transformed]

        expected = [
            None,
            np.std([10.0, 15.0], ddof=1),
            np.std([10.0, 15.0, 13.0], ddof=1),
            np.std([15.0, 13.0, 12.0], ddof=1),
        ]

        # np has odd rounding behavior, cf.
        # http://docs.scipy.org/doc/np/reference/generated/np.std.html
        for v1, v2 in zip(vals, expected):

            if v1 is None:
                assert v2 is None
                continue
            assert round(v1, 5) == round(v2, 5)
Example #25
0
    def test_commission_event(self):
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            cash_adj_dt = self.sim_params.period_start \
                + datetime.timedelta(hours=3)
            cash_adjustment = factory.create_commission(1, 300.0,
                                                        cash_adj_dt)

            # Insert a purchase order.
            events.insert(0, create_txn(events[0], 20, 1))

            events.insert(1, cash_adjustment)
            results = calculate_results(self, events)
            # Validate that we lost 320 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9680)
            # Validate that the cost basis of our position changed.
            self.assertEqual(results[-1]['daily_perf']['positions']
                             [0]['cost_basis'], 320.0)
Example #26
0
    def test_returns(self):
        # Daily returns.
        returns = Returns(1)

        transformed = list(returns.transform(self.source))
        tnfm_vals = [message[returns.get_hash()] for message in transformed]

        # No returns for the first event because we don't have a
        # previous close.
        expected = [0.0, 0.0, 0.1, 0.0]

        self.assertEquals(tnfm_vals, expected)

        # Two-day returns.  An extra kink here is that the
        # factory will automatically skip a weekend for the
        # last event. Results shouldn't notice this blip.

        trade_history = factory.create_trade_history(
            133, [10.0, 15.0, 13.0, 12.0, 13.0], [100, 100, 100, 300, 100], timedelta(days=1), self.trading_environment
        )
        self.source = SpecificEquityTrades(event_list=trade_history)

        returns = StatefulTransform(Returns, 2)

        transformed = list(returns.transform(self.source))
        tnfm_vals = [message[returns.get_hash()] for message in transformed]

        expected = [0.0, 0.0, (13.0 - 10.0) / 10.0, (12.0 - 15.0) / 15.0, (13.0 - 13.0) / 13.0]

        self.assertEquals(tnfm_vals, expected)
    def test_long_position_receives_dividend(self):
        # post some trades in the market
        events = factory.create_trade_history(
            1, [10, 10, 10, 10, 10], [100, 100, 100, 100, 100], oneday, self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            # declared date, when the algorithm finds out about
            # the dividend
            events[1].dt,
            # ex_date, when the algorithm is credited with the
            # dividend
            events[1].dt,
            # pay date, when the algorithm receives the dividend.
            events[2].dt,
        )

        txn = create_txn(1, 10.0, 100, events[0].dt)
        events.insert(0, txn)
        events.insert(1, dividend)
        results = calculate_results(self, events)

        self.assertEqual(len(results), 5)
        cumulative_returns = [event["cumulative_perf"]["returns"] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.1, 0.1, 0.1])
        daily_returns = [event["daily_perf"]["returns"] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.10, 0.0, 0.0])
        cash_flows = [event["daily_perf"]["capital_used"] for event in results]
        self.assertEqual(cash_flows, [-1000, 0, 1000, 0, 0])
        cumulative_cash_flows = [event["cumulative_perf"]["capital_used"] for event in results]
        self.assertEqual(cumulative_cash_flows, [-1000, -1000, 0, 0, 0])
        cash_pos = [event["cumulative_perf"]["ending_cash"] for event in results]
        self.assertEqual(cash_pos, [9000, 9000, 10000, 10000, 10000])
Example #28
0
    def setUp(self):
        self.sim_params = factory.create_simulation_parameters()
        setup_logger(self)

        trade_history = factory.create_trade_history(
            133, [10.0, 10.0, 11.0, 11.0], [100, 100, 100, 300], timedelta(days=1), self.sim_params
        )
        self.source = SpecificEquityTrades(event_list=trade_history)
Example #29
0
    def setUp(self):
        self.sim_params = factory.create_simulation_parameters(num_days=4)
        trade_history = factory.create_trade_history(
            133, [10.0, 10.0, 11.0, 11.0], [100, 100, 100, 300], timedelta(days=1), self.sim_params
        )

        self.source = SpecificEquityTrades(event_list=trade_history)
        self.df_source, self.df = factory.create_test_df_source(self.sim_params)
Example #30
0
    def setUp(self):
        self.sim_params = factory.create_simulation_parameters(num_days=4)
        self.sid = 133
        self.trade_history = factory.create_trade_history(
            self.sid, [10.0, 10.0, 11.0, 11.0], [100, 100, 100, 300],
            timedelta(days=1), self.sim_params)

        self.source = SpecificEquityTrades(event_list=self.trade_history)
Example #31
0
    def setUp(self):
        self.trading_environment = factory.create_trading_environment()
        setup_logger(self)

        trade_history = factory.create_trade_history(
            133, [10.0, 10.0, 11.0, 11.0], [100, 100, 100, 300], timedelta(days=1), self.trading_environment
        )
        self.source = SpecificEquityTrades(event_list=trade_history)
Example #32
0
    def test_split_long_position(self):
        events = factory.create_trade_history(1, [20, 20], [100, 100], oneday,
                                              self.sim_params)

        # set up a long position in sid 1
        # 100 shares at $20 apiece = $2000 position
        txns = [create_txn(events[0], 20, 100)]

        # set up a split with ratio 3 occurring at the start of the second
        # day.
        splits = [
            factory.create_split(
                1,
                3,
                events[1].dt,
            ),
        ]

        results = calculate_results(self, events, txns=txns, splits=splits)

        # should have 33 shares (at $60 apiece) and $20 in cash
        self.assertEqual(2, len(results))

        latest_positions = results[1]['daily_perf']['positions']
        self.assertEqual(1, len(latest_positions))

        # check the last position to make sure it's been updated
        position = latest_positions[0]

        self.assertEqual(1, position['sid'])
        self.assertEqual(33, position['amount'])
        self.assertEqual(60, position['cost_basis'])
        self.assertEqual(60, position['last_sale_price'])

        # since we started with $10000, and we spent $2000 on the
        # position, but then got $20 back, we should have $8020
        # (or close to it) in cash.

        # we won't get exactly 8020 because sometimes a split is
        # denoted as a ratio like 0.3333, and we lose some digits
        # of precision.  thus, make sure we're pretty close.
        daily_perf = results[1]['daily_perf']

        self.assertTrue(
            zp_math.tolerant_equals(8020, daily_perf['ending_cash'], 1))

        for i, result in enumerate(results):
            for perf_kind in ('daily_perf', 'cumulative_perf'):
                perf_result = result[perf_kind]
                # prices aren't changing, so pnl and returns should be 0.0
                self.assertEqual(
                    0.0, perf_result['pnl'],
                    "day %s %s pnl %s instead of 0.0" %
                    (i, perf_kind, perf_result['pnl']))
                self.assertEqual(
                    0.0, perf_result['returns'],
                    "day %s %s returns %s instead of 0.0" %
                    (i, perf_kind, perf_result['returns']))
Example #33
0
    def test_split_long_position(self):
        with trading.TradingEnvironment() as env:
            events = factory.create_trade_history(
                1,
                [20, 20],
                [100, 100],
                oneday,
                self.sim_params
            )

            # set up a long position in sid 1
            # 100 shares at $20 apiece = $2000 position
            events.insert(0, create_txn(events[0], 20, 100))

            # set up a split with ratio 3
            events.append(factory.create_split(1, 3,
                          env.next_trading_day(events[1].dt)))

            results = calculate_results(self, events)

            # should have 33 shares (at $60 apiece) and $20 in cash
            self.assertEqual(2, len(results))

            latest_positions = results[1]['daily_perf']['positions']
            self.assertEqual(1, len(latest_positions))

            # check the last position to make sure it's been updated
            position = latest_positions[0]

            self.assertEqual(1, position['sid'])
            self.assertEqual(33, position['amount'])
            self.assertEqual(60, position['cost_basis'])
            self.assertEqual(60, position['last_sale_price'])

            # since we started with $10000, and we spent $2000 on the
            # position, but then got $20 back, we should have $8020
            # (or close to it) in cash.

            # we won't get exactly 8020 because sometimes a split is
            # denoted as a ratio like 0.3333, and we lose some digits
            # of precision.  thus, make sure we're pretty close.
            daily_perf = results[1]['daily_perf']

            self.assertTrue(
                zp_math.tolerant_equals(8020,
                                        daily_perf['ending_cash'], 1))

            for i, result in enumerate(results):
                for perf_kind in ('daily_perf', 'cumulative_perf'):
                    perf_result = result[perf_kind]
                    # prices aren't changing, so pnl and returns should be 0.0
                    self.assertEqual(0.0, perf_result['pnl'],
                                     "day %s %s pnl %s instead of 0.0" %
                                     (i, perf_kind, perf_result['pnl']))
                    self.assertEqual(0.0, perf_result['returns'],
                                     "day %s %s returns %s instead of 0.0" %
                                     (i, perf_kind, perf_result['returns']))
Example #34
0
    def test_long_position(self):
        """
            verify that the performance period calculates properly for a
            single buy transaction
        """
        # post some trades in the market
        trades = factory.create_trade_history(1, [10, 10, 10, 11],
                                              [100, 100, 100, 100], onesec,
                                              self.sim_params)

        txn = create_txn(trades[1], 10.0, 100)
        pp = perf.PerformancePeriod(1000.0)

        pp.execute_transaction(txn)

        # This verifies that the last sale price is being correctly
        # set in the positions. If this is not the case then returns can
        # incorrectly show as sharply dipping if a transaction arrives
        # before a trade. This is caused by returns being based on holding
        # stocks with a last sale price of 0.
        self.assertEqual(pp.positions[1].last_sale_price, 10.0)

        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        self.assertEqual(
            pp.period_cash_flow, -1 * txn.price * txn.amount,
            "capital used should be equal to the opposite of the transaction \
            cost of sole txn in test")

        self.assertEqual(len(pp.positions), 1, "should be just one position")

        self.assertEqual(pp.positions[1].sid, txn.sid,
                         "position should be in security with id 1")

        self.assertEqual(
            pp.positions[1].amount, txn.amount,
            "should have a position of {sharecount} shares".format(
                sharecount=txn.amount))

        self.assertEqual(pp.positions[1].cost_basis, txn.price,
                         "should have a cost basis of 10")

        self.assertEqual(
            pp.positions[1].last_sale_price, trades[-1]['price'],
            "last sale should be same as last trade. \
            expected {exp} actual {act}".format(
                exp=trades[-1]['price'], act=pp.positions[1].last_sale_price))

        self.assertEqual(
            pp.ending_value, 1100,
            "ending value should be price of last trade times number of \
            shares in position")

        self.assertEqual(pp.pnl, 100, "gain of 1 on 100 shares should be 100")
Example #35
0
    def setUp(self):
        self.trading_environment = factory.create_trading_environment()
        setup_logger(self)

        trade_history = factory.create_trade_history(133,
                                                     [10.0, 10.0, 11.0, 11.0],
                                                     [100, 100, 100, 300],
                                                     timedelta(days=1),
                                                     self.trading_environment)
        self.source = SpecificEquityTrades(event_list=trade_history)
Example #36
0
 def setUp(self):
     self.sim_params = factory.create_simulation_parameters()
     trade_history = factory.create_trade_history(133,
                                                  [10.0, 10.0, 11.0, 11.0],
                                                  [100, 100, 100, 300],
                                                  timedelta(days=1),
                                                  self.sim_params)
     self.source = SpecificEquityTrades(event_list=trade_history)
     self.df_source, self.df = \
         factory.create_test_df_source(self.sim_params)
Example #37
0
    def setUp(self):
        self.sim_params = factory.create_simulation_parameters()
        setup_logger(self)

        trade_history = factory.create_trade_history(133,
                                                     [10.0, 10.0, 11.0, 11.0],
                                                     [100, 100, 100, 300],
                                                     timedelta(days=1),
                                                     self.sim_params)
        self.source = trade_history
Example #38
0
    def test_covering_short(self):
        """verify performance where short is bought and covered, and shares \
trade after cover"""

        trades = factory.create_trade_history(
            1, [10, 10, 10, 11, 9, 8, 7, 8, 9, 10],
            [100, 100, 100, 100, 100, 100, 100, 100, 100, 100], onesec,
            self.sim_params)

        short_txn = create_txn(
            trades[1],
            10.0,
            -100,
        )

        cover_txn = create_txn(trades[6], 7.0, 100)
        pp = perf.PerformancePeriod(1000.0)

        pp.execute_transaction(short_txn)
        pp.execute_transaction(cover_txn)

        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        short_txn_cost = short_txn.price * short_txn.amount
        cover_txn_cost = cover_txn.price * cover_txn.amount

        self.assertEqual(
            pp.period_cash_flow, -1 * short_txn_cost - cover_txn_cost,
            "capital used should be equal to the net transaction costs")

        self.assertEqual(len(pp.positions), 1, "should be just one position")

        self.assertEqual(
            pp.positions[1].sid, short_txn.sid,
            "position should be in security from the transaction")

        self.assertEqual(pp.positions[1].amount, 0,
                         "should have a position of -100 shares")

        self.assertEqual(pp.positions[1].cost_basis, 0,
                         "a covered position should have a cost basis of 0")

        self.assertEqual(pp.positions[1].last_sale_price, trades[-1].price,
                         "last sale should be price of last trade")

        self.assertEqual(
            pp.ending_value, 0,
            "ending value should be price of last trade times number of \
shares in position")

        self.assertEqual(pp.pnl, 300, "gain of 1 on 100 shares should be 300")
Example #39
0
    def test_ending_before_pay_date(self):
        #post some trades in the market
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100],
            oneday,
            self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            events[0].dt,
            events[1].dt,
            events[-1].dt + 10 * oneday
        )

        buy_txn = create_txn(1, 10.0, 100, events[1].dt)
        events.insert(2, buy_txn)
        events.insert(1, dividend)
        perf_tracker = perf.PerformanceTracker(self.sim_params)

        all_events = (msg[1] for msg in heapq.merge(
            ((event.dt, event) for event in events),
            ((event.dt, event) for event in self.benchmark_events)))

        transformed_events = list(perf_tracker.transform(
            itertools.groupby(all_events, attrgetter('dt'))))

        #flatten the list of events
        results = []
        for te in transformed_events:
            for event in te[1]:
                for message in event.perf_messages:
                    results.append(message)

        perf_messages, risk = perf_tracker.handle_simulation_end()
        results.append(perf_messages[0])

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0, 0, 0, 0.0, 0.0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0, 0, 0, 0, 0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, -1000, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(
            cumulative_cash_flows,
            [0, -1000, -1000, -1000, -1000]
        )
Example #40
0
    def test_long_position_receives_dividend(self):
        #post some trades in the market
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100],
            oneday,
            self.trading_environment
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            events[0].dt,
            events[1].dt,
            events[2].dt
        )

        events.insert(1, dividend)
        txn = factory.create_txn(1, 10.0, 100, self.dt+oneday)
        events[2].TRANSACTION = txn
        perf_tracker = perf.PerformanceTracker(self.trading_environment)
        transformed_events = list(perf_tracker.transform(
            ((event.dt, [event]) for event in events))
        )

        #flatten the list of events
        results = []
        for te in transformed_events:
            for event in te[1]:
                for message in event.perf_messages:
                    results.append(message)

        perf_messages, risk = perf_tracker.handle_simulation_end()
        results.append(perf_messages[0])

        self.assertEqual(results[0]['daily_perf']['period_open'], events[0].dt)
        self.assertEqual(
            results[-1]['daily_perf']['period_open'],
            events[-1].dt
        )

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.1, 0.1, 0.1])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.10, 0.0, 0.0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, -1000, 1000, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, -1000, 0, 0, 0])
Example #41
0
    def test_long_position_receives_dividend(self):
        #post some trades in the market
        events = factory.create_trade_history(1, [10, 10, 10, 10, 10],
                                              [100, 100, 100, 100, 100],
                                              oneday, self.sim_params)

        dividend = factory.create_dividend(
            1,
            10.00,
            # declared date, when the algorithm finds out about
            # the dividend
            events[1].dt,
            # ex_date, when the algorithm is credited with the
            # dividend
            events[1].dt,
            # pay date, when the algorithm receives the dividend.
            events[2].dt)

        txn = factory.create_txn(1, 10.0, 100, events[0].dt)
        events[0].TRANSACTION = txn
        events.insert(1, dividend)
        perf_tracker = perf.PerformanceTracker(self.sim_params)
        transformed_events = list(
            perf_tracker.transform(((event.dt, [event]) for event in events)))

        #flatten the list of events
        results = []
        for te in transformed_events:
            for event in te[1]:
                for message in event.perf_messages:
                    results.append(message)

        perf_messages, risk = perf_tracker.handle_simulation_end()
        results.append(perf_messages[0])

        self.assertEqual(results[0]['daily_perf']['period_open'], events[0].dt)
        self.assertEqual(results[-1]['daily_perf']['period_open'],
                         events[-1].dt)

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0.0, 0.0, 0.1, 0.1, 0.1])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0.0, 0.0, 0.10, 0.0, 0.0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [-1000, 0, 1000, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [-1000, -1000, 0, 0, 0])
        cash_pos = \
            [event['cumulative_perf']['ending_cash'] for event in results]
        self.assertEqual(cash_pos, [9000, 9000, 10000, 10000, 10000])
Example #42
0
    def test_buy_and_sell_before_ex(self):
        #post some trades in the market
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100, 100],
            oneday,
            self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            events[3].dt,
            events[4].dt,
            events[5].dt
        )

        buy_txn = create_txn(1, 10.0, 100, events[1].dt)
        events.insert(2, buy_txn)
        sell_txn = create_txn(1, 10.0, -100, events[3].dt)
        events.insert(4, sell_txn)
        events.insert(1, dividend)
        perf_tracker = perf.PerformanceTracker(self.sim_params)

        all_events = heapq.merge(
            ((event.dt, event) for event in events),
            ((event.dt, event) for event in self.benchmark_events))

        transformed_events = list(perf_tracker.transform(
            (event[0], [event[1]]) for event in all_events))

        #flatten the list of events
        results = []
        for te in transformed_events:
            for event in te[1]:
                for message in event.perf_messages:
                    results.append(message)

        perf_messages, risk = perf_tracker.handle_simulation_end()
        results.append(perf_messages[0])

        self.assertEqual(len(results), 6)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0, 0, 0, 0, 0, 0])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0, 0, 0, 0, 0, 0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [0, -1000, 1000, 0, 0, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [0, -1000, 0, 0, 0, 0])
Example #43
0
    def test_long_position_receives_stock_dividend(self):
        with trading.TradingEnvironment():
            # post some trades in the market
            events = []
            for sid in (1, 2):
                events.extend(
                    factory.create_trade_history(
                        sid,
                        [10, 10, 10, 10, 10],
                        [100, 100, 100, 100, 100],
                        oneday,
                        self.sim_params)
                )

            dividend = factory.create_stock_dividend(
                1,
                payment_sid=2,
                ratio=2,
                # declared date, when the algorithm finds out about
                # the dividend
                declared_date=events[0].dt,
                # ex_date, the date before which the algorithm must hold stock
                # to receive the dividend
                ex_date=events[1].dt,
                # pay date, when the algorithm receives the dividend.
                pay_date=events[2].dt
            )

            txns = [create_txn(events[0], 10.0, 100)]

            results = calculate_results(
                self,
                events,
                dividend_events=[dividend],
                txns=txns,
            )

            self.assertEqual(len(results), 5)
            cumulative_returns = \
                [event['cumulative_perf']['returns'] for event in results]
            self.assertEqual(cumulative_returns, [0.0, 0.0, 0.2, 0.2, 0.2])
            daily_returns = [event['daily_perf']['returns']
                             for event in results]
            self.assertEqual(daily_returns, [0.0, 0.0, 0.2, 0.0, 0.0])
            cash_flows = [event['daily_perf']['capital_used']
                          for event in results]
            self.assertEqual(cash_flows, [-1000, 0, 0, 0, 0])
            cumulative_cash_flows = \
                [event['cumulative_perf']['capital_used'] for event in results]
            self.assertEqual(cumulative_cash_flows, [-1000] * 5)
            cash_pos = \
                [event['cumulative_perf']['ending_cash'] for event in results]
            self.assertEqual(cash_pos, [9000] * 5)
Example #44
0
    def setUp(self):
        self.sim_params = factory.create_simulation_parameters(num_days=4)
        self.sidint = 133
        self.trade_history = factory.create_trade_history(
            self.sidint,
            [10.0, 10.0, 11.0, 11.0],
            [100, 100, 100, 300],
            timedelta(days=1),
            self.sim_params
        )

        self.source = SpecificEquityTrades(event_list=self.trade_history)
    def test_long_position(self):
        """
            verify that the performance period calculates properly for a
            single buy transaction
        """
        # post some trades in the market
        trades = factory.create_trade_history(1, [10, 10, 10, 11], [100, 100, 100, 100], onesec, self.sim_params)

        txn = create_txn(1, 10.0, 100, self.dt + onesec)
        pp = perf.PerformancePeriod(1000.0)

        pp.execute_transaction(txn)
        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        self.assertEqual(
            pp.period_cash_flow,
            -1 * txn.price * txn.amount,
            "capital used should be equal to the opposite of the transaction \
            cost of sole txn in test",
        )

        self.assertEqual(len(pp.positions), 1, "should be just one position")

        self.assertEqual(pp.positions[1].sid, txn.sid, "position should be in security with id 1")

        self.assertEqual(
            pp.positions[1].amount,
            txn.amount,
            "should have a position of {sharecount} shares".format(sharecount=txn.amount),
        )

        self.assertEqual(pp.positions[1].cost_basis, txn.price, "should have a cost basis of 10")

        self.assertEqual(
            pp.positions[1].last_sale_price,
            trades[-1]["price"],
            "last sale should be same as last trade. \
            expected {exp} actual {act}".format(
                exp=trades[-1]["price"], act=pp.positions[1].last_sale_price
            ),
        )

        self.assertEqual(
            pp.ending_value,
            1100,
            "ending value should be price of last trade times number of \
            shares in position",
        )

        self.assertEqual(pp.pnl, 100, "gain of 1 on 100 shares should be 100")
    def test_covering_short(self):
        """verify performance where short is bought and covered, and shares \
trade after cover"""

        trades = factory.create_trade_history(
            1,
            [10, 10, 10, 11, 9, 8, 7, 8, 9, 10],
            [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
            onesec,
            self.sim_params,
        )

        short_txn = create_txn(1, 10.0, -100, self.dt + onesec)

        cover_txn = create_txn(1, 7.0, 100, self.dt + onesec * 6)
        pp = perf.PerformancePeriod(1000.0)

        pp.execute_transaction(short_txn)
        pp.execute_transaction(cover_txn)

        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        short_txn_cost = short_txn.price * short_txn.amount
        cover_txn_cost = cover_txn.price * cover_txn.amount

        self.assertEqual(
            pp.period_cash_flow,
            -1 * short_txn_cost - cover_txn_cost,
            "capital used should be equal to the net transaction costs",
        )

        self.assertEqual(len(pp.positions), 1, "should be just one position")

        self.assertEqual(pp.positions[1].sid, short_txn.sid, "position should be in security from the transaction")

        self.assertEqual(pp.positions[1].amount, 0, "should have a position of -100 shares")

        self.assertEqual(pp.positions[1].cost_basis, 0, "a covered position should have a cost basis of 0")

        self.assertEqual(pp.positions[1].last_sale_price, trades[-1].price, "last sale should be price of last trade")

        self.assertEqual(
            pp.ending_value,
            0,
            "ending value should be price of last trade times number of \
shares in position",
        )

        self.assertEqual(pp.pnl, 300, "gain of 1 on 100 shares should be 300")
Example #47
0
    def test_algo_without_rl_violation(self):
        sim_params = factory.create_simulation_parameters(start=list(
            LEVERAGED_ETFS.keys())[0],
                                                          num_days=4)

        trade_history = factory.create_trade_history('AAPL',
                                                     [10.0, 10.0, 11.0, 11.0],
                                                     [100, 100, 100, 300],
                                                     timedelta(days=1),
                                                     sim_params)
        self.source = SpecificEquityTrades(event_list=trade_history)
        algo = RestrictedAlgoWithoutCheck(symbol='AAPL', sim_params=sim_params)
        algo.run(self.source)
Example #48
0
    def setUp(self):
        days = 251
        self.sim_params = factory.create_simulation_parameters(num_days=days)
        setup_logger(self)

        trade_history = factory.create_trade_history(
            133, [10.0] * days, [100] * days, timedelta(days=1), self.sim_params
        )

        self.source = SpecificEquityTrades(event_list=trade_history)
        self.df_source, self.df = factory.create_test_df_source(self.sim_params)

        self.zipline_test_config = {"sid": 0}
Example #49
0
    def test_long_position_receives_stock_dividend(self):
        with trading.TradingEnvironment():
            # post some trades in the market
            events = []
            for sid in (1, 2):
                events.extend(
                    factory.create_trade_history(sid, [10, 10, 10, 10, 10],
                                                 [100, 100, 100, 100, 100],
                                                 oneday, self.sim_params))

            dividend = factory.create_stock_dividend(
                1,
                payment_sid=2,
                ratio=2,
                # declared date, when the algorithm finds out about
                # the dividend
                declared_date=events[0].dt,
                # ex_date, the date before which the algorithm must hold stock
                # to receive the dividend
                ex_date=events[1].dt,
                # pay date, when the algorithm receives the dividend.
                pay_date=events[2].dt)

            txns = [create_txn(events[0], 10.0, 100)]

            results = calculate_results(
                self,
                events,
                dividend_events=[dividend],
                txns=txns,
            )

            self.assertEqual(len(results), 5)
            cumulative_returns = \
                [event['cumulative_perf']['returns'] for event in results]
            self.assertEqual(cumulative_returns, [0.0, 0.0, 0.2, 0.2, 0.2])
            daily_returns = [
                event['daily_perf']['returns'] for event in results
            ]
            self.assertEqual(daily_returns, [0.0, 0.0, 0.2, 0.0, 0.0])
            cash_flows = [
                event['daily_perf']['capital_used'] for event in results
            ]
            self.assertEqual(cash_flows, [-1000, 0, 0, 0, 0])
            cumulative_cash_flows = \
                [event['cumulative_perf']['capital_used'] for event in results]
            self.assertEqual(cumulative_cash_flows, [-1000] * 5)
            cash_pos = \
                [event['cumulative_perf']['ending_cash'] for event in results]
            self.assertEqual(cash_pos, [9000] * 5)
Example #50
0
    def test_long_position(self):
        """
            verify that the performance period calculates properly for a
            single buy transaction
        """
        #post some trades in the market
        trades = factory.create_trade_history(1, [10, 10, 10, 11],
                                              [100, 100, 100, 100],
                                              self.onesec,
                                              self.trading_environment)

        txn = factory.create_txn(1, 10.0, 100, self.dt + self.onesec)
        pp = perf.PerformancePeriod({}, 0.0, 1000.0)

        pp.execute_transaction(txn)
        for trade in trades:
            pp.update_last_sale(trade)

        pp.calculate_performance()

        self.assertEqual(
            pp.period_capital_used, -1 * txn.price * txn.amount,
            "capital used should be equal to the opposite of the transaction \
            cost of sole txn in test")

        self.assertEqual(len(pp.positions), 1, "should be just one position")

        self.assertEqual(pp.positions[1].sid, txn.sid,
                         "position should be in security with id 1")

        self.assertEqual(
            pp.positions[1].amount, txn.amount,
            "should have a position of {sharecount} shares".format(
                sharecount=txn.amount))

        self.assertEqual(pp.positions[1].cost_basis, txn.price,
                         "should have a cost basis of 10")

        self.assertEqual(
            pp.positions[1].last_sale_price, trades[-1]['price'],
            "last sale should be same as last trade. \
            expected {exp} actual {act}".format(
                exp=trades[-1]['price'], act=pp.positions[1].last_sale_price))

        self.assertEqual(
            pp.ending_value, 1100,
            "ending value should be price of last trade times number of \
            shares in position")

        self.assertEqual(pp.pnl, 100, "gain of 1 on 100 shares should be 100")
Example #51
0
    def test_commission_event(self):
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            # Test commission models and validate result
            # Expected commission amounts:
            # PerShare commission:  1.00, 1.00, 1.50 = $3.50
            # PerTrade commission:  5.00, 5.00, 5.00 = $15.00
            # PerDollar commission: 1.50, 3.00, 4.50 = $9.00
            # Total commission = $3.50 + $15.00 + $9.00 = $27.50

            # Create 3 transactions:  50, 100, 150 shares traded @ $20
            transactions = [create_txn(events[0], 20, i)
                            for i in [50, 100, 150]]

            # Create commission models and validate that produce expected
            # commissions.
            models = [PerShare(cost=0.01, min_trade_cost=1.00),
                      PerTrade(cost=5.00),
                      PerDollar(cost=0.0015)]
            expected_results = [3.50, 15.0, 9.0]

            for model, expected in zip(models, expected_results):
                total_commission = 0
                for trade in transactions:
                    total_commission += model.calculate(trade)[1]
                self.assertEqual(total_commission, expected)

            # Verify that commission events are handled correctly by
            # PerformanceTracker.
            cash_adj_dt = events[0].dt
            cash_adjustment = factory.create_commission(1, 300.0, cash_adj_dt)
            events.append(cash_adjustment)

            # Insert a purchase order.
            txns = [create_txn(events[0], 20, 1)]
            results = calculate_results(self, events, txns=txns)

            # Validate that we lost 320 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9680)
            # Validate that the cost basis of our position changed.
            self.assertEqual(results[-1]['daily_perf']['positions']
                             [0]['cost_basis'], 320.0)
Example #52
0
    def test_algo_without_rl_violation(self):
        sim_params = factory.create_simulation_parameters(
            start=list(LEVERAGED_ETFS.keys())[0], num_days=4)

        trade_history = factory.create_trade_history(
            'AAPL',
            [10.0, 10.0, 11.0, 11.0],
            [100, 100, 100, 300],
            timedelta(days=1),
            sim_params
        )
        self.source = SpecificEquityTrades(event_list=trade_history)
        algo = RestrictedAlgoWithoutCheck(sid='AAPL', sim_params=sim_params)
        algo.run(self.source)
Example #53
0
    def test_iterate_over_rl(self):
        sim_params = factory.create_simulation_parameters(start=list(
            LEVERAGED_ETFS.keys())[0],
                                                          num_days=4)

        trade_history = factory.create_trade_history('BZQ',
                                                     [10.0, 10.0, 11.0, 11.0],
                                                     [100, 100, 100, 300],
                                                     timedelta(days=1),
                                                     sim_params)
        self.source = SpecificEquityTrades(event_list=trade_history)
        algo = IterateRLAlgo(symbol='BZQ', sim_params=sim_params)
        algo.run(self.source)
        self.assertTrue(algo.found)
Example #54
0
    def test_commission_event(self):
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            # Test commission models and validate result
            # Expected commission amounts:
            # PerShare commission:  1.00, 1.00, 1.50 = $3.50
            # PerTrade commission:  5.00, 5.00, 5.00 = $15.00
            # PerDollar commission: 1.50, 3.00, 4.50 = $9.00
            # Total commission = $3.50 + $15.00 + $9.00 = $27.50

            # Create 3 transactions:  50, 100, 150 shares traded @ $20
            transactions = [create_txn(events[0], 20, i)
                            for i in [50, 100, 150]]

            # Create commission models
            models = [PerShare(cost=0.01, min_trade_cost=1.00),
                      PerTrade(cost=5.00),
                      PerDollar(cost=0.0015)]

            # Aggregate commission amounts
            total_commission = 0
            for model in models:
                for trade in transactions:
                    total_commission += model.calculate(trade)[1]
            self.assertEqual(total_commission, 27.5)

            cash_adj_dt = self.sim_params.first_open \
                + datetime.timedelta(hours=3)
            cash_adjustment = factory.create_commission(1, 300.0,
                                                        cash_adj_dt)

            # Insert a purchase order.
            events.insert(0, create_txn(events[0], 20, 1))

            events.insert(1, cash_adjustment)
            results = calculate_results(self, events)
            # Validate that we lost 320 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9680)
            # Validate that the cost basis of our position changed.
            self.assertEqual(results[-1]['daily_perf']['positions']
                             [0]['cost_basis'], 320.0)
Example #55
0
    def test_commission_event(self):
        with trading.TradingEnvironment():
            events = factory.create_trade_history(1, [10, 10, 10, 10, 10],
                                                  [100, 100, 100, 100, 100],
                                                  oneday, self.sim_params)

            # Test commission models and validate result
            # Expected commission amounts:
            # PerShare commission:  1.00, 1.00, 1.50 = $3.50
            # PerTrade commission:  5.00, 5.00, 5.00 = $15.00
            # PerDollar commission: 1.50, 3.00, 4.50 = $9.00
            # Total commission = $3.50 + $15.00 + $9.00 = $27.50

            # Create 3 transactions:  50, 100, 150 shares traded @ $20
            transactions = [
                create_txn(events[0], 20, i) for i in [50, 100, 150]
            ]

            # Create commission models and validate that produce expected
            # commissions.
            models = [
                PerShare(cost=0.01, min_trade_cost=1.00),
                PerTrade(cost=5.00),
                PerDollar(cost=0.0015)
            ]
            expected_results = [3.50, 15.0, 9.0]

            for model, expected in zip(models, expected_results):
                total_commission = 0
                for trade in transactions:
                    total_commission += model.calculate(trade)[1]
                self.assertEqual(total_commission, expected)

            # Verify that commission events are handled correctly by
            # PerformanceTracker.
            cash_adj_dt = events[0].dt
            cash_adjustment = factory.create_commission(1, 300.0, cash_adj_dt)
            events.append(cash_adjustment)

            # Insert a purchase order.
            txns = [create_txn(events[0], 20, 1)]
            results = calculate_results(self, events, txns=txns)

            # Validate that we lost 320 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9680)
            # Validate that the cost basis of our position changed.
            self.assertEqual(
                results[-1]['daily_perf']['positions'][0]['cost_basis'], 320.0)
Example #56
0
    def test_commission_event(self):
        with trading.TradingEnvironment():
            events = factory.create_trade_history(
                1,
                [10, 10, 10, 10, 10],
                [100, 100, 100, 100, 100],
                oneday,
                self.sim_params
            )

            # Test commission models and validate result
            # Expected commission amounts:
            # PerShare commission:  1.00, 1.00, 1.50 = $3.50
            # PerTrade commission:  5.00, 5.00, 5.00 = $15.00
            # PerDollar commission: 1.50, 3.00, 4.50 = $9.00
            # Total commission = $3.50 + $15.00 + $9.00 = $27.50

            # Create 3 transactions:  50, 100, 150 shares traded @ $20
            transactions = [create_txn(events[0], 20, i)
                            for i in [50, 100, 150]]

            # Create commission models
            models = [PerShare(cost=0.01, min_trade_cost=1.00),
                      PerTrade(cost=5.00),
                      PerDollar(cost=0.0015)]

            # Aggregate commission amounts
            total_commission = 0
            for model in models:
                for trade in transactions:
                    total_commission += model.calculate(trade)[1]
            self.assertEqual(total_commission, 27.5)

            cash_adj_dt = self.sim_params.first_open \
                + datetime.timedelta(hours=3)
            cash_adjustment = factory.create_commission(1, 300.0,
                                                        cash_adj_dt)

            # Insert a purchase order.
            events.insert(0, create_txn(events[0], 20, 1))

            events.insert(1, cash_adjustment)
            results = calculate_results(self, events)
            # Validate that we lost 320 dollars from our cash pool.
            self.assertEqual(results[-1]['cumulative_perf']['ending_cash'],
                             9680)
            # Validate that the cost basis of our position changed.
            self.assertEqual(results[-1]['daily_perf']['positions']
                             [0]['cost_basis'], 320.0)
Example #57
0
    def test_selling_before_dividend_payment_still_gets_paid(self):
        #post some trades in the market
        events = factory.create_trade_history(
            1,
            [10, 10, 10, 10, 10],
            [100, 100, 100, 100, 100],
            oneday,
            self.sim_params
        )

        dividend = factory.create_dividend(
            1,
            10.00,
            events[0].dt,
            events[1].dt,
            events[3].dt
        )

        buy_txn = factory.create_txn(1, 10.0, 100, events[0].dt)
        events[0].TRANSACTION = buy_txn
        sell_txn = factory.create_txn(1, 10.0, -100, events[2].dt)
        events[2].TRANSACTION = sell_txn
        events.insert(1, dividend)
        perf_tracker = perf.PerformanceTracker(self.sim_params)
        transformed_events = list(perf_tracker.transform(
            ((event.dt, [event]) for event in events))
        )

        #flatten the list of events
        results = []
        for te in transformed_events:
            for event in te[1]:
                for message in event.perf_messages:
                    results.append(message)

        perf_messages, risk = perf_tracker.handle_simulation_end()
        results.append(perf_messages[0])

        self.assertEqual(len(results), 5)
        cumulative_returns = \
            [event['cumulative_perf']['returns'] for event in results]
        self.assertEqual(cumulative_returns, [0, 0, 0, 0.1, 0.1])
        daily_returns = [event['daily_perf']['returns'] for event in results]
        self.assertEqual(daily_returns, [0, 0, 0, 0.1, 0])
        cash_flows = [event['daily_perf']['capital_used'] for event in results]
        self.assertEqual(cash_flows, [-1000, 0, 1000, 1000, 0])
        cumulative_cash_flows = \
            [event['cumulative_perf']['capital_used'] for event in results]
        self.assertEqual(cumulative_cash_flows, [-1000, -1000, 0, 1000, 1000])
Example #58
0
    def test_algo_with_rl_violation_after_add(self):
        with security_list_copy():
            add_security_data(['AAPL'], [])
            sim_params = factory.create_simulation_parameters(
                start=self.trading_day_before_first_kd, num_days=4)
            trade_history = factory.create_trade_history(
                'AAPL', [10.0, 10.0, 11.0, 11.0], [100, 100, 100, 300],
                timedelta(days=1), sim_params)
            self.source = SpecificEquityTrades(event_list=trade_history)
            algo = RestrictedAlgoWithoutCheck(symbol='AAPL',
                                              sim_params=sim_params)
            with self.assertRaises(TradingControlViolation) as ctx:
                algo.run(self.source)

            self.check_algo_exception(algo, ctx, 2)