def test_volshare_slippage(self): # verify order -> transaction -> portfolio position. # -------------- test_algo = TradingAlgorithm( script=""" from zipline.api import * def initialize(context): model = slippage.VolumeShareSlippage( volume_limit=.3, price_impact=0.05 ) set_slippage(model) set_commission(commission.PerShare(0.02)) context.count = 2 context.incr = 0 def handle_data(context, data): if context.incr < context.count: # order small lots to be sure the # order will fill in a single transaction order(0, 5000) record(price=data[0].price) record(volume=data[0].volume) record(incr=context.incr) context.incr += 1 """, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 100 # 67 will be used inside assert_single_position # to confirm we have as many transactions as expected. # The algo places 2 trades of 5000 shares each. The trade # events have volume ranging from 100 to 950. The volume cap # of 0.3 limits the trade volume to a range of 30 - 316 shares. # The spreadsheet linked below calculates the total position # size over each bar, and predicts 67 txns will be required # to fill the two orders. The number of bars and transactions # differ because some bars result in multiple txns. See # spreadsheet for details: # https://www.dropbox.com/s/ulrk2qt0nrtrigb/Volume%20Share%20Worksheet.xlsx self.zipline_test_config['expected_transactions'] = 67 zipline = simfactory.create_test_zipline( **self.zipline_test_config) output, _ = assert_single_position(self, zipline) # confirm the slippage and commission on a sample # transaction per_share_commish = 0.02 perf = output[1] transaction = perf['daily_perf']['transactions'][0] commish = transaction['amount'] * per_share_commish self.assertEqual(commish, transaction['commission']) self.assertEqual(2.029, transaction['price'])
def test_datasource_exception(self): self.zipline_test_config["trade_source"] = ExceptionSource() zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(ZeroDivisionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, "integer division or modulo by zero")
def test_datasource_exception(self): self.zipline_test_config['trade_source'] = ExceptionSource() zipline = simfactory.create_test_zipline( **self.zipline_test_config ) with self.assertRaises(ZeroDivisionError): output, _ = drain_zipline(self, zipline)
def test_datasource_exception(self): self.zipline_test_config['trade_source'] = ExceptionSource() zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(ZeroDivisionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, 'integer division or modulo by zero')
def test_tranform_exception(self): exc_tnfm = StatefulTransform(ExceptionTransform) self.zipline_test_config["transforms"] = [exc_tnfm] zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(AssertionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, "An assertion message")
def test_tranform_exception(self): exc_tnfm = StatefulTransform(ExceptionTransform) self.zipline_test_config['transforms'] = [exc_tnfm] zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(AssertionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, 'An assertion message')
def test_fixed_slippage(self): # verify order -> transaction -> portfolio position. # -------------- test_algo = TradingAlgorithm( script=""" from zipline.api import (slippage, commission, set_slippage, set_commission, order, record) def initialize(context): model = slippage.FixedSlippage(spread=0.10) set_slippage(model) set_commission(commission.PerTrade(100.00)) context.count = 1 context.incr = 0 def handle_data(context, data): if context.incr < context.count: order(0, -1000) record(price=data[0].price) context.incr += 1""", sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 200 # this matches the value in the algotext initialize # method, and will be used inside assert_single_position # to confirm we have as many transactions as orders we # placed. self.zipline_test_config['order_count'] = 1 # self.zipline_test_config['transforms'] = \ # test_algo.transform_visitor.transforms.values() zipline = simfactory.create_test_zipline( **self.zipline_test_config) output, _ = assert_single_position(self, zipline) # confirm the slippage and commission on a sample # transaction recorded_price = output[1]['daily_perf']['recorded_vars']['price'] transaction = output[1]['daily_perf']['transactions'][0] self.assertEqual(100.0, transaction['commission']) expected_spread = 0.05 expected_commish = 0.10 expected_price = recorded_price - expected_spread - expected_commish self.assertEqual(expected_price, transaction['price'])
def test_full_zipline(self): # provide enough trades to ensure all orders are filled. self.zipline_test_config['order_count'] = 100 # making a small order amount, so that each order is filled # in a single transaction, and txn_count == order_count. self.zipline_test_config['order_amount'] = 25 # No transactions can be filled on the first trade, so # we have one extra trade to ensure all orders are filled. self.zipline_test_config['trade_count'] = 101 full_zipline = simfactory.create_test_zipline( **self.zipline_test_config) assert_single_position(self, full_zipline)
def test_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config["algorithm"] = ExceptionAlgorithm( "handle_data", self.zipline_test_config["sid"], sim_params=factory.create_simulation_parameters() ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(Exception) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, "Algo exception in handle_data")
def test_order_methods(self): """Only test that order methods can be called without error. Correct filling of orders is tested in zipline. """ test_algo = TradingAlgorithm(script=call_all_order_methods, sim_params=self.sim_params) set_algo_instance(test_algo) self.zipline_test_config["algorithm"] = test_algo self.zipline_test_config["trade_count"] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline)
def test_zerodivision_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config["algorithm"] = DivByZeroAlgorithm( self.zipline_test_config["sid"], sim_params=factory.create_simulation_parameters() ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(ZeroDivisionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, "integer division or modulo by zero")
def _algo_record_float_magic_should_pass(self, var_type): test_algo = TradingAlgorithm(script=record_float_magic % var_type, sim_params=self.sim_params) set_algo_instance(test_algo) self.zipline_test_config["algorithm"] = test_algo self.zipline_test_config["trade_count"] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline) self.assertEqual(len(output), 252) incr = [] for o in output[:200]: incr.append(o["daily_perf"]["recorded_vars"]["data"]) np.testing.assert_array_equal(incr, [np.nan] * 200)
def test_algo_record_vars(self): test_algo = TradingAlgorithm(script=record_variables, sim_params=self.sim_params) set_algo_instance(test_algo) self.zipline_test_config["algorithm"] = test_algo self.zipline_test_config["trade_count"] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline) self.assertEqual(len(output), 252) incr = [] for o in output[:200]: incr.append(o["daily_perf"]["recorded_vars"]["incr"]) np.testing.assert_array_equal(incr, range(1, 201))
def test_zerodivision_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ DivByZeroAlgorithm( self.zipline_test_config['sid'], sim_params=factory.create_simulation_parameters(), env=self.env ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(ZeroDivisionError): output, _ = drain_zipline(self, zipline)
def test_portfolio_in_init(self): """ Test that accessing portfolio in init doesn't break. """ test_algo = TradingAlgorithm( script=access_portfolio_in_init, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 1 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline)
def test_zerodivision_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ DivByZeroAlgorithm( self.zipline_test_config['sid'] ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(ZeroDivisionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, 'integer division or modulo by zero')
def test_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ ExceptionAlgorithm( 'handle_data', self.zipline_test_config['sid'] ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(Exception) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, 'Algo exception in handle_data')
def test_zerodivision_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ DivByZeroAlgorithm( self.zipline_test_config['sid'], sim_params=factory.create_simulation_parameters() ) zipline = simfactory.create_test_zipline( **self.zipline_test_config ) with self.assertRaises(ZeroDivisionError): output, _ = drain_zipline(self, zipline)
def test_order_methods(self): """Only test that order methods can be called without error. Correct filling of orders is tested in zipline. """ test_algo = TradingAlgorithm( script=call_all_order_methods, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline)
def test_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ ExceptionAlgorithm( 'handle_data', self.zipline_test_config['sid'], sim_params=factory.create_simulation_parameters(), env=self.env ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(Exception) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(str(ctx.exception), 'Algo exception in handle_data')
def test_set_portfolio(self): """ Are we protected against overwriting an algo's portfolio? """ # Simulation # ---------- self.zipline_test_config["algorithm"] = SetPortfolioAlgorithm( self.zipline_test_config["sid"], sim_params=factory.create_simulation_parameters() ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(AttributeError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, "can't set attribute")
def test_account_in_init(self): """ Test that accessing account in init doesn't break. """ test_algo = TradingAlgorithm( script=access_account_in_init, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 1 zipline = simfactory.create_test_zipline( **self.zipline_test_config) output, _ = drain_zipline(self, zipline)
def _algo_record_float_magic_should_pass(self, var_type): test_algo = TradingAlgorithm( script=record_float_magic % var_type, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline) self.assertEqual(len(output), 252) incr = [] for o in output[:200]: incr.append(o['daily_perf']['recorded_vars']['data']) np.testing.assert_array_equal(incr, [np.nan] * 200)
def test_zerodivision_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ DivByZeroAlgorithm( self.zipline_test_config['sid'] ) zipline = simfactory.create_test_zipline( **self.zipline_test_config ) with self.assertRaises(ZeroDivisionError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, 'integer division or modulo by zero')
def test_set_portfolio(self): """ Are we protected against overwriting an algo's portfolio? """ # Simulation # ---------- self.zipline_test_config['algorithm'] = \ SetPortfolioAlgorithm( self.zipline_test_config['sid'], sim_params=factory.create_simulation_parameters(), env=self.env ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(AttributeError): output, _ = drain_zipline(self, zipline)
def test_set_portfolio(self): """ Are we protected against overwriting an algo's portfolio? """ # Simulation # ---------- self.zipline_test_config['algorithm'] = \ SetPortfolioAlgorithm( self.zipline_test_config['sid'] ) zipline = simfactory.create_test_zipline(**self.zipline_test_config) with self.assertRaises(AttributeError) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, "can't set attribute")
def test_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ ExceptionAlgorithm( 'handle_data', self.zipline_test_config['sid'] ) zipline = simfactory.create_test_zipline( **self.zipline_test_config ) with self.assertRaises(Exception) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(ctx.exception.message, 'Algo exception in handle_data')
def test_algo_record_vars(self): test_algo = TradingAlgorithm( script=record_variables, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = drain_zipline(self, zipline) self.assertEqual(len(output), 252) incr = [] for o in output[:200]: incr.append(o['daily_perf']['recorded_vars']['incr']) np.testing.assert_array_equal(incr, range(1, 201))
def test_exception_in_handle_data(self): # Simulation # ---------- self.zipline_test_config['algorithm'] = \ ExceptionAlgorithm( 'handle_data', self.zipline_test_config['sid'], sim_params=factory.create_simulation_parameters(), env=self.env ) zipline = simfactory.create_test_zipline( **self.zipline_test_config ) with self.assertRaises(Exception) as ctx: output, _ = drain_zipline(self, zipline) self.assertEqual(str(ctx.exception), 'Algo exception in handle_data')
def test_set_portfolio(self): """ Are we protected against overwriting an algo's portfolio? """ # Simulation # ---------- self.zipline_test_config['algorithm'] = \ SetPortfolioAlgorithm( self.zipline_test_config['sid'], sim_params=factory.create_simulation_parameters() ) zipline = simfactory.create_test_zipline( **self.zipline_test_config ) with self.assertRaises(AttributeError): output, _ = drain_zipline(self, zipline)
def test_full_zipline(self): #provide enough trades to ensure all orders are filled. self.zipline_test_config['order_count'] = 100 self.zipline_test_config['trade_count'] = 200 zipline = simfactory.create_test_zipline(**self.zipline_test_config) assert_single_position(self, zipline)