From 5e276d0e72f2ca560480138e69f595628ab2390c Mon Sep 17 00:00:00 2001 From: Andrew Liang Date: Wed, 14 Sep 2016 11:29:52 -0400 Subject: [PATCH] TEST: Modify tests for extra BarData parameter Introducing a WithCreateBarData fixture which allows for the creation of a BarData using only the `simulation_dt_func` and `restrictions` params. Assumes that each suite uses the same `data_portal`, `data_frequency` and `trading_calendar` --- tests/finance/test_slippage.py | 783 +++++++++++++++++---------------- tests/test_api_shim.py | 13 +- tests/test_blotter.py | 24 +- tests/test_finance.py | 10 +- tests/test_history.py | 86 ++-- tests/test_tradesimulation.py | 2 + zipline/testing/fixtures.py | 16 + 7 files changed, 502 insertions(+), 432 deletions(-) diff --git a/tests/finance/test_slippage.py b/tests/finance/test_slippage.py index 2c6ae008..17846b94 100644 --- a/tests/finance/test_slippage.py +++ b/tests/finance/test_slippage.py @@ -27,20 +27,25 @@ from pandas.tslib import normalize_date from zipline.finance.slippage import VolumeShareSlippage -from zipline.protocol import DATASOURCE_TYPE +from zipline.protocol import DATASOURCE_TYPE, BarData from zipline.finance.blotter import Order - +from zipline.finance.restrictions import NoopRestrictions from zipline.data.data_portal import DataPortal -from zipline.protocol import BarData from zipline.testing import tmp_bcolz_equity_minute_bar_reader from zipline.testing.fixtures import ( + WithCreateBarData, WithDataPortal, WithSimParams, + WithTradingEnvironment, ZiplineTestCase, ) +from zipline.utils.classproperty import classproperty -class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): +class SlippageTestCase(WithCreateBarData, + WithSimParams, + WithDataPortal, + ZiplineTestCase): START_DATE = pd.Timestamp('2006-01-05 14:31', tz='utc') END_DATE = pd.Timestamp('2006-01-05 14:36', tz='utc') SIM_PARAMS_CAPITAL_BASE = 1.0e5 @@ -56,6 +61,10 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): freq='1min' ) + @classproperty + def CREATE_BARDATA_DATA_FREQUENCY(cls): + return cls.sim_params.data_frequency + @classmethod def make_equity_minute_bar_data(cls): yield 133, pd.DataFrame( @@ -74,97 +83,6 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): super(SlippageTestCase, cls).init_class_fixtures() cls.ASSET133 = cls.env.asset_finder.retrieve_asset(133) - def test_volume_share_slippage(self): - assets = ( - (133, pd.DataFrame( - { - 'open': [3.00], - 'high': [3.15], - 'low': [2.85], - 'close': [3.00], - 'volume': [200], - }, - index=[self.minutes[0]], - )), - ) - days = pd.date_range( - start=normalize_date(self.minutes[0]), - end=normalize_date(self.minutes[-1]) - ) - with tmp_bcolz_equity_minute_bar_reader(self.trading_calendar, days, assets) \ - as reader: - data_portal = DataPortal( - self.env.asset_finder, self.trading_calendar, - first_trading_day=reader.first_trading_day, - equity_minute_reader=reader, - ) - - slippage_model = VolumeShareSlippage() - - open_orders = [ - Order( - dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - amount=100, - filled=0, - sid=self.ASSET133 - ) - ] - - bar_data = BarData(data_portal, - lambda: self.minutes[0], - 'minute', - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 1) - _, txn = orders_txns[0] - - expected_txn = { - 'price': float(3.0001875), - 'dt': datetime.datetime( - 2006, 1, 5, 14, 31, tzinfo=pytz.utc), - 'amount': int(5), - 'sid': int(133), - 'commission': None, - 'type': DATASOURCE_TYPE.TRANSACTION, - 'order_id': open_orders[0].id - } - - self.assertIsNotNone(txn) - - # TODO: Make expected_txn an Transaction object and ensure there - # is a __eq__ for that class. - self.assertEquals(expected_txn, txn.__dict__) - - open_orders = [ - Order( - dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - amount=100, - filled=0, - sid=self.ASSET133 - ) - ] - - # Set bar_data to be a minute ahead of last trade. - # Volume share slippage should not execute when there is no trade. - bar_data = BarData(data_portal, - lambda: self.minutes[1], - 'minute', - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - def test_orders_limit(self): slippage_model = VolumeShareSlippage() slippage_model.data_portal = self.data_portal @@ -179,10 +97,9 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): 'limit': 3.5}) ] - bar_data = BarData(self.data_portal, - lambda: self.minutes[3], - self.sim_params.data_frequency, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[3], + ) orders_txns = list(slippage_model.simulate( bar_data, @@ -202,10 +119,9 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): 'limit': 3.5}) ] - bar_data = BarData(self.data_portal, - lambda: self.minutes[3], - self.sim_params.data_frequency, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[3], + ) orders_txns = list(slippage_model.simulate( bar_data, @@ -225,10 +141,9 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): 'limit': 3.6}) ] - bar_data = BarData(self.data_portal, - lambda: self.minutes[3], - self.sim_params.data_frequency, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[3], + ) orders_txns = list(slippage_model.simulate( bar_data, @@ -265,10 +180,9 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): 'limit': 3.5}) ] - bar_data = BarData(self.data_portal, - lambda: self.minutes[0], - self.sim_params.data_frequency, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[0], + ) orders_txns = list(slippage_model.simulate( bar_data, @@ -288,10 +202,9 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): 'limit': 3.5}) ] - bar_data = BarData(self.data_portal, - lambda: self.minutes[0], - self.sim_params.data_frequency, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[0], + ) orders_txns = list(slippage_model.simulate( bar_data, @@ -311,10 +224,9 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): 'limit': 3.4}) ] - bar_data = BarData(self.data_portal, - lambda: self.minutes[1], - self.sim_params.data_frequency, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[1], + ) orders_txns = list(slippage_model.simulate( bar_data, @@ -338,6 +250,376 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): for key, value in expected_txn.items(): self.assertEquals(value, txn[key]) + def test_orders_stop_limit(self): + slippage_model = VolumeShareSlippage() + slippage_model.data_portal = self.data_portal + + # long, does not trade + open_orders = [ + Order(**{ + 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + 'amount': 100, + 'filled': 0, + 'sid': self.ASSET133, + 'stop': 4.0, + 'limit': 3.0}) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[2], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[3], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + # long, does not trade - impacted price worse than limit price + open_orders = [ + Order(**{ + 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + 'amount': 100, + 'filled': 0, + 'sid': self.ASSET133, + 'stop': 4.0, + 'limit': 3.5}) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[2], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[3], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + # long, does trade + open_orders = [ + Order(**{ + 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + 'amount': 100, + 'filled': 0, + 'sid': self.ASSET133, + 'stop': 4.0, + 'limit': 3.6}) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[2], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[3], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 1) + _, txn = orders_txns[0] + + expected_txn = { + 'price': float(3.50021875), + 'dt': datetime.datetime( + 2006, 1, 5, 14, 34, tzinfo=pytz.utc), + 'amount': int(50), + 'sid': int(133) + } + + for key, value in expected_txn.items(): + self.assertEquals(value, txn[key]) + + # short, does not trade + + open_orders = [ + Order(**{ + 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + 'amount': -100, + 'filled': 0, + 'sid': self.ASSET133, + 'stop': 3.0, + 'limit': 4.0}) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[0], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[1], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + # short, does not trade - impacted price worse than limit price + open_orders = [ + Order(**{ + 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + 'amount': -100, + 'filled': 0, + 'sid': self.ASSET133, + 'stop': 3.0, + 'limit': 3.5}) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[0], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[1], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + # short, does trade + open_orders = [ + Order(**{ + 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + 'amount': -100, + 'filled': 0, + 'sid': self.ASSET133, + 'stop': 3.0, + 'limit': 3.4}) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[0], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[1], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 1) + _, txn = orders_txns[0] + + expected_txn = { + 'price': float(3.49978125), + 'dt': datetime.datetime( + 2006, 1, 5, 14, 32, tzinfo=pytz.utc), + 'amount': int(-50), + 'sid': int(133) + } + + for key, value in expected_txn.items(): + self.assertEquals(value, txn[key]) + + +class VolumeShareSlippageTestCase(WithCreateBarData, + WithSimParams, + WithDataPortal, + ZiplineTestCase): + + START_DATE = pd.Timestamp('2006-01-05 14:31', tz='utc') + END_DATE = pd.Timestamp('2006-01-05 14:36', tz='utc') + SIM_PARAMS_CAPITAL_BASE = 1.0e5 + SIM_PARAMS_DATA_FREQUENCY = 'minute' + SIM_PARAMS_EMISSION_RATE = 'daily' + + ASSET_FINDER_EQUITY_SIDS = (133,) + ASSET_FINDER_EQUITY_START_DATE = pd.Timestamp('2006-01-05', tz='utc') + ASSET_FINDER_EQUITY_END_DATE = pd.Timestamp('2006-01-07', tz='utc') + minutes = pd.DatetimeIndex( + start=START_DATE, + end=END_DATE - pd.Timedelta('1 minute'), + freq='1min' + ) + + @classproperty + def CREATE_BARDATA_DATA_FREQUENCY(cls): + return cls.sim_params.data_frequency + + @classmethod + def make_equity_minute_bar_data(cls): + yield 133, pd.DataFrame( + { + 'open': [3.00], + 'high': [3.15], + 'low': [2.85], + 'close': [3.00], + 'volume': [200], + }, + index=[cls.minutes[0]], + ) + + @classmethod + def init_class_fixtures(cls): + super(VolumeShareSlippageTestCase, cls).init_class_fixtures() + cls.ASSET133 = cls.env.asset_finder.retrieve_asset(133) + + def test_volume_share_slippage(self): + + slippage_model = VolumeShareSlippage() + + open_orders = [ + Order( + dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + amount=100, + filled=0, + sid=self.ASSET133 + ) + ] + + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[0], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 1) + _, txn = orders_txns[0] + + expected_txn = { + 'price': float(3.0001875), + 'dt': datetime.datetime( + 2006, 1, 5, 14, 31, tzinfo=pytz.utc), + 'amount': int(5), + 'sid': int(133), + 'commission': None, + 'type': DATASOURCE_TYPE.TRANSACTION, + 'order_id': open_orders[0].id + } + + self.assertIsNotNone(txn) + + # TODO: Make expected_txn an Transaction object and ensure there + # is a __eq__ for that class. + self.assertEquals(expected_txn, txn.__dict__) + + open_orders = [ + Order( + dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), + amount=100, + filled=0, + sid=self.ASSET133 + ) + ] + + # Set bar_data to be a minute ahead of last trade. + # Volume share slippage should not execute when there is no trade. + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.minutes[1], + ) + + orders_txns = list(slippage_model.simulate( + bar_data, + self.ASSET133, + open_orders, + )) + + self.assertEquals(len(orders_txns), 0) + + +class OrdersStopTestCase(WithSimParams, + WithTradingEnvironment, + ZiplineTestCase): + + START_DATE = pd.Timestamp('2006-01-05 14:31', tz='utc') + END_DATE = pd.Timestamp('2006-01-05 14:36', tz='utc') + SIM_PARAMS_CAPITAL_BASE = 1.0e5 + SIM_PARAMS_DATA_FREQUENCY = 'minute' + SIM_PARAMS_EMISSION_RATE = 'daily' + ASSET_FINDER_EQUITY_SIDS = (133,) + minutes = pd.DatetimeIndex( + start=START_DATE, + end=END_DATE - pd.Timedelta('1 minute'), + freq='1min' + ) + + @classmethod + def init_class_fixtures(cls): + super(OrdersStopTestCase, cls).init_class_fixtures() + cls.ASSET133 = cls.env.asset_finder.retrieve_asset(133) + STOP_ORDER_CASES = { # Stop orders can be long/short and have their price greater or # less than the stop. @@ -501,10 +783,14 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): try: dt = pd.Timestamp('2006-01-05 14:31', tz='UTC') - bar_data = BarData(data_portal, - lambda: dt, - 'minute', - self.trading_calendar) + bar_data = BarData( + data_portal, + lambda: dt, + self.sim_params.data_frequency, + self.trading_calendar, + NoopRestrictions(), + ) + _, txn = next(slippage_model.simulate( bar_data, self.ASSET133, @@ -520,254 +806,3 @@ class SlippageTestCase(WithSimParams, WithDataPortal, ZiplineTestCase): for key, value in expected['transaction'].items(): self.assertEquals(value, txn[key]) - - def test_orders_stop_limit(self): - slippage_model = VolumeShareSlippage() - slippage_model.data_portal = self.data_portal - - # long, does not trade - open_orders = [ - Order(**{ - 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - 'amount': 100, - 'filled': 0, - 'sid': self.ASSET133, - 'stop': 4.0, - 'limit': 3.0}) - ] - - bar_data = BarData(self.data_portal, - lambda: self.minutes[2], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - bar_data = BarData(self.data_portal, - lambda: self.minutes[3], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - # long, does not trade - impacted price worse than limit price - open_orders = [ - Order(**{ - 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - 'amount': 100, - 'filled': 0, - 'sid': self.ASSET133, - 'stop': 4.0, - 'limit': 3.5}) - ] - - bar_data = BarData(self.data_portal, - lambda: self.minutes[2], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - bar_data = BarData(self.data_portal, - lambda: self.minutes[3], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - # long, does trade - open_orders = [ - Order(**{ - 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - 'amount': 100, - 'filled': 0, - 'sid': self.ASSET133, - 'stop': 4.0, - 'limit': 3.6}) - ] - - bar_data = BarData(self.data_portal, - lambda: self.minutes[2], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - bar_data = BarData(self.data_portal, - lambda: self.minutes[3], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 1) - _, txn = orders_txns[0] - - expected_txn = { - 'price': float(3.50021875), - 'dt': datetime.datetime( - 2006, 1, 5, 14, 34, tzinfo=pytz.utc), - 'amount': int(50), - 'sid': int(133) - } - - for key, value in expected_txn.items(): - self.assertEquals(value, txn[key]) - - # short, does not trade - - open_orders = [ - Order(**{ - 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - 'amount': -100, - 'filled': 0, - 'sid': self.ASSET133, - 'stop': 3.0, - 'limit': 4.0}) - ] - - bar_data = BarData(self.data_portal, - lambda: self.minutes[0], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - bar_data = BarData(self.data_portal, - lambda: self.minutes[1], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - # short, does not trade - impacted price worse than limit price - open_orders = [ - Order(**{ - 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - 'amount': -100, - 'filled': 0, - 'sid': self.ASSET133, - 'stop': 3.0, - 'limit': 3.5}) - ] - - bar_data = BarData(self.data_portal, - lambda: self.minutes[0], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - bar_data = BarData(self.data_portal, - lambda: self.minutes[1], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - # short, does trade - open_orders = [ - Order(**{ - 'dt': datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc), - 'amount': -100, - 'filled': 0, - 'sid': self.ASSET133, - 'stop': 3.0, - 'limit': 3.4}) - ] - - bar_data = BarData(self.data_portal, - lambda: self.minutes[0], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 0) - - bar_data = BarData(self.data_portal, - lambda: self.minutes[1], - self.sim_params.data_frequency, - self.trading_calendar) - - orders_txns = list(slippage_model.simulate( - bar_data, - self.ASSET133, - open_orders, - )) - - self.assertEquals(len(orders_txns), 1) - _, txn = orders_txns[0] - - expected_txn = { - 'price': float(3.49978125), - 'dt': datetime.datetime( - 2006, 1, 5, 14, 32, tzinfo=pytz.utc), - 'amount': int(-50), - 'sid': int(133) - } - - for key, value in expected_txn.items(): - self.assertEquals(value, txn[key]) diff --git a/tests/test_api_shim.py b/tests/test_api_shim.py index 3aa64b8d..f79416d2 100644 --- a/tests/test_api_shim.py +++ b/tests/test_api_shim.py @@ -7,7 +7,6 @@ from pandas.core.common import PerformanceWarning from zipline import TradingAlgorithm from zipline.finance.trading import SimulationParameters -from zipline.protocol import BarData from zipline.testing import ( MockDailyBarReader, create_daily_df_for_asset, @@ -15,6 +14,7 @@ from zipline.testing import ( str_to_seconds, ) from zipline.testing.fixtures import ( + WithCreateBarData, WithDataPortal, WithSimParams, ZiplineTestCase, @@ -114,7 +114,11 @@ def handle_data(context, data): """ -class TestAPIShim(WithDataPortal, WithSimParams, ZiplineTestCase): +class TestAPIShim(WithCreateBarData, + WithDataPortal, + WithSimParams, + ZiplineTestCase, + ): START_DATE = pd.Timestamp("2016-01-05", tz='UTC') END_DATE = pd.Timestamp("2016-01-28", tz='UTC') SIM_PARAMS_DATA_FREQUENCY = 'minute' @@ -186,11 +190,8 @@ class TestAPIShim(WithDataPortal, WithSimParams, ZiplineTestCase): test_end_minute = self.trading_calendar.minutes_for_session( self.sim_params.sessions[0] )[-1] - bar_data = BarData( - self.data_portal, + bar_data = self.create_bardata( lambda: test_end_minute, - "minute", - self.trading_calendar ) ohlcvp_fields = [ "open", diff --git a/tests/test_blotter.py b/tests/test_blotter.py index 89c251db..fa5d0cf3 100644 --- a/tests/test_blotter.py +++ b/tests/test_blotter.py @@ -31,8 +31,9 @@ from zipline.finance.slippage import ( DEFAULT_VOLUME_SLIPPAGE_BAR_LIMIT, FixedSlippage, ) -from zipline.protocol import BarData +from zipline.utils.classproperty import classproperty from zipline.testing.fixtures import ( + WithCreateBarData, WithDataPortal, WithLogger, WithSimParams, @@ -40,7 +41,8 @@ from zipline.testing.fixtures import ( ) -class BlotterTestCase(WithLogger, +class BlotterTestCase(WithCreateBarData, + WithLogger, WithDataPortal, WithSimParams, ZiplineTestCase): @@ -71,6 +73,10 @@ class BlotterTestCase(WithLogger, index=cls.sim_params.sessions, ) + @classproperty + def CREATE_BARDATA_DATA_FREQUENCY(cls): + return cls.sim_params.data_frequency + @parameterized.expand([(MarketOrder(), None, None), (LimitOrder(10), 10, None), (StopOrder(10), None, 10), @@ -219,11 +225,8 @@ class BlotterTestCase(WithLogger, filled_id = blotter.order(asset_24, 100, MarketOrder()) filled_order = None blotter.current_dt = self.sim_params.sessions[-1] - bar_data = BarData( - self.data_portal, - lambda: self.sim_params.sessions[-1], - self.sim_params.data_frequency, - self.trading_calendar + bar_data = self.create_bardata( + simulation_dt_func=lambda: self.sim_params.sessions[-1], ) txns, _, closed_orders = blotter.get_transactions(bar_data) for txn in txns: @@ -295,11 +298,8 @@ class BlotterTestCase(WithLogger, filled_order = None blotter.current_dt = dt - bar_data = BarData( - self.data_portal, - lambda: dt, - self.sim_params.data_frequency, - self.trading_calendar + bar_data = self.create_bardata( + simulation_dt_func=lambda: dt, ) txns, _, _ = blotter.get_transactions(bar_data) for txn in txns: diff --git a/tests/test_finance.py b/tests/test_finance.py index 4b374a35..b8729933 100644 --- a/tests/test_finance.py +++ b/tests/test_finance.py @@ -37,6 +37,7 @@ from zipline.data.minute_bars import BcolzMinuteBarReader from zipline.data.data_portal import DataPortal from zipline.data.us_equity_pricing import BcolzDailyBarWriter from zipline.finance.slippage import FixedSlippage +from zipline.finance.restrictions import NoopRestrictions from zipline.protocol import BarData from zipline.testing import ( tmp_trading_env, @@ -317,10 +318,11 @@ class FinanceTestCase(WithLogger, order_date = order_date.replace(hour=14, minute=30) else: bar_data = BarData( - data_portal, - lambda: tick, - sim_params.data_frequency, - self.trading_calendar + data_portal=data_portal, + simulation_dt_func=lambda: tick, + data_frequency=sim_params.data_frequency, + trading_calendar=self.trading_calendar, + restrictions=NoopRestrictions(), ) txns, _, closed_orders = blotter.get_transactions(bar_data) for txn in txns: diff --git a/tests/test_history.py b/tests/test_history.py index a68b7216..2859bb8b 100644 --- a/tests/test_history.py +++ b/tests/test_history.py @@ -21,20 +21,21 @@ import pandas as pd from six import iteritems from zipline import TradingAlgorithm -from zipline._protocol import handle_non_market_minutes +from zipline._protocol import handle_non_market_minutes, BarData from zipline.assets import Asset from zipline.errors import ( HistoryInInitialize, HistoryWindowStartsBeforeData, ) from zipline.finance.trading import SimulationParameters -from zipline.protocol import BarData +from zipline.finance.restrictions import NoopRestrictions from zipline.testing import ( create_minute_df_for_asset, str_to_seconds, MockDailyBarReader, ) from zipline.testing.fixtures import ( + WithCreateBarData, WithDataPortal, ZiplineTestCase, alias, @@ -46,7 +47,7 @@ OHLCP = OHLC + ['price'] ALL_FIELDS = OHLCP + ['volume'] -class WithHistory(WithDataPortal): +class WithHistory(WithCreateBarData, WithDataPortal): TRADING_START_DT = TRADING_ENV_MIN_DATE = START_DATE = pd.Timestamp( '2014-01-03', tz='UTC', @@ -251,8 +252,9 @@ class WithHistory(WithDataPortal): fields = fields if fields is not None else ALL_FIELDS assets = assets if assets is not None else [self.ASSET2, self.ASSET3] - bar_data = BarData(self.data_portal, lambda: dt, mode, - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: dt, + ) check_internal_consistency( bar_data, assets, fields, 10, freq ) @@ -704,8 +706,9 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): )[0:60] for idx, minute in enumerate(minutes): - bar_data = BarData(self.data_portal, lambda: minute, 'minute', - self.trading_calendar) + bar_data = self.create_bardata( + lambda: minute, + ) check_internal_consistency( bar_data, [self.ASSET2, self.ASSET3], ALL_FIELDS, 10, '1m' ) @@ -766,13 +769,12 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): ) )[1] - midnight_bar_data = \ - BarData(self.data_portal, lambda: midnight, 'minute', - self.trading_calendar) - - yesterday_bar_data = \ - BarData(self.data_portal, lambda: last_minute, 'minute', - self.trading_calendar) + midnight_bar_data = self.create_bardata( + lambda: midnight, + ) + yesterday_bar_data = self.create_bardata( + lambda: last_minute + ) with handle_non_market_minutes(midnight_bar_data): for field in ALL_FIELDS: @@ -789,8 +791,9 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): )[0:60] for idx, minute in enumerate(minutes): - bar_data = BarData(self.data_portal, lambda: minute, 'minute', - self.trading_calendar) + bar_data = self.create_bardata( + lambda: minute + ) check_internal_consistency( bar_data, self.SHORT_ASSET, ALL_FIELDS, 30, '1m' ) @@ -799,8 +802,13 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): data_portal = self.make_data_portal() # choose a window that contains the last minute of the asset - bar_data = BarData(data_portal, lambda: minutes[15], 'minute', - self.trading_calendar) + bar_data = BarData( + data_portal=data_portal, + simulation_dt_func=lambda: minutes[15], + data_frequency='minute', + restrictions=NoopRestrictions(), + trading_calendar=self.trading_calendar, + ) # close high low open price volume # 2015-01-06 20:47:00+00:00 768 770 767 769 768 76800 @@ -1012,8 +1020,9 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): def test_passing_iterable_to_history_regular_hours(self): # regular hours current_dt = pd.Timestamp("2015-01-06 9:45", tz='US/Eastern') - bar_data = BarData(self.data_portal, lambda: current_dt, "minute", - self.trading_calendar) + bar_data = self.create_bardata( + lambda: current_dt, + ) bar_data.history(pd.Index([self.ASSET1, self.ASSET2]), "high", 5, "1m") @@ -1021,8 +1030,9 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): def test_passing_iterable_to_history_bts(self): # before market hours current_dt = pd.Timestamp("2015-01-07 8:45", tz='US/Eastern') - bar_data = BarData(self.data_portal, lambda: current_dt, "minute", - self.trading_calendar) + bar_data = self.create_bardata( + lambda: current_dt, + ) with handle_non_market_minutes(bar_data): bar_data.history(pd.Index([self.ASSET1, self.ASSET2]), @@ -1031,8 +1041,9 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): def test_overnight_adjustments(self): # Should incorporate adjustments on midnight 01/06 current_dt = pd.Timestamp('2015-01-06 8:45', tz='US/Eastern') - bar_data = BarData(self.data_portal, lambda: current_dt, 'minute', - self.trading_calendar) + bar_data = self.create_bardata( + lambda: current_dt, + ) adj_expected = { 'open': np.arange(8381, 8391) / 4.0, @@ -1341,6 +1352,8 @@ class MinuteEquityHistoryTestCase(WithHistory, ZiplineTestCase): class DailyEquityHistoryTestCase(WithHistory, ZiplineTestCase): + CREATE_BARDATA_DATA_FREQUENCY = 'daily' + @classmethod def make_equity_daily_bar_data(cls): yield 1, cls.create_df_for_asset( @@ -1403,8 +1416,9 @@ class DailyEquityHistoryTestCase(WithHistory, ZiplineTestCase): ) for idx, day in enumerate(days): - bar_data = BarData(self.data_portal, lambda: day, 'daily', - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: day, + ) check_internal_consistency( bar_data, [self.ASSET2, self.ASSET3], ALL_FIELDS, 10, '1d' ) @@ -1445,10 +1459,9 @@ class DailyEquityHistoryTestCase(WithHistory, ZiplineTestCase): # asset1 ends on 2016-01-30 # asset2 ends on 2015-12-13 - bar_data = BarData(self.data_portal, - lambda: pd.Timestamp('2016-01-06', tz='UTC'), - 'daily', - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: pd.Timestamp('2016-01-06', tz='UTC'), + ) for field in OHLCP: window = bar_data.history( @@ -1486,8 +1499,9 @@ class DailyEquityHistoryTestCase(WithHistory, ZiplineTestCase): # days has 1/7, 1/8 for idx, day in enumerate(days): - bar_data = BarData(self.data_portal, lambda: day, 'daily', - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: day, + ) check_internal_consistency( bar_data, self.SHORT_ASSET, ALL_FIELDS, 2, '1d' ) @@ -1639,10 +1653,10 @@ class DailyEquityHistoryTestCase(WithHistory, ZiplineTestCase): # asset1 ends on 2016-01-30 # asset2 ends on 2016-01-04 - bar_data = BarData(self.data_portal, - lambda: pd.Timestamp('2016-01-06 16:00', tz='UTC'), - 'daily', - self.trading_calendar) + bar_data = self.create_bardata( + simulation_dt_func=lambda: + pd.Timestamp('2016-01-06 16:00', tz='UTC'), + ) for field in OHLCP: window = bar_data.history( diff --git a/tests/test_tradesimulation.py b/tests/test_tradesimulation.py index d3bb8b33..c6027004 100644 --- a/tests/test_tradesimulation.py +++ b/tests/test_tradesimulation.py @@ -24,6 +24,7 @@ from zipline import TradingAlgorithm from zipline.gens.sim_engine import BEFORE_TRADING_START_BAR from zipline.finance.performance import PerformanceTracker +from zipline.finance.restrictions import NoopRestrictions from zipline.gens.tradesimulation import AlgorithmSimulator from zipline.sources.benchmark_source import BenchmarkSource from zipline.test_algorithms import NoopAlgorithm @@ -135,6 +136,7 @@ def initialize(context): self.data_portal, BeforeTradingStartsOnlyClock(dt), algo._create_benchmark_source(), + NoopRestrictions(), None ) diff --git a/zipline/testing/fixtures.py b/zipline/testing/fixtures.py index f0e2aaa5..8290b5a4 100644 --- a/zipline/testing/fixtures.py +++ b/zipline/testing/fixtures.py @@ -36,8 +36,10 @@ from ..utils.classproperty import classproperty from ..utils.final import FinalMeta, final from .core import tmp_asset_finder, make_simple_equity_info from zipline.assets import Equity, Future +from zipline.finance.restrictions import NoopRestrictions from zipline.pipeline import SimplePipelineEngine from zipline.pipeline.loaders.testing import make_seeded_random_loader +from zipline.protocol import BarData from zipline.utils.calendars import ( get_calendar, register_calendar) @@ -1319,3 +1321,17 @@ class WithResponses(object): self.responses = self.enter_instance_context( responses.RequestsMock(), ) + + +class WithCreateBarData(WithDataPortal): + + CREATE_BARDATA_DATA_FREQUENCY = 'minute' + + def create_bardata(self, simulation_dt_func, restrictions=None): + return BarData( + self.data_portal, + simulation_dt_func, + self.CREATE_BARDATA_DATA_FREQUENCY, + self.trading_calendar, + restrictions or NoopRestrictions() + )