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)
def test_factory_daily(self): trading_environment = factory.create_trading_environment() trade_source = factory.create_daily_trade_source([133], 200, trading_environment) prev = None for trade in trade_source: if prev: self.assertTrue(trade.dt > prev.dt) prev = trade
def run(self, source=None, start=None, end=None): """Run the algorithm. :Arguments: source : can be either: - pandas.Panel - pandas.DataFrame - zipline source - list of zipline sources If pandas.DataFrame is provided, it must have the following structure: * column names must consist of ints representing the different sids * index must be DatetimeIndex * array contents should be price info. :Returns: daily_stats : pandas.DataFrame Daily performance metrics such as returns, alpha etc. """ if source is None: assert(self.sources) else: self.set_sources(source, start, end) # Create transforms by wrapping them into StatefulTransforms self.transforms = [] for namestring, trans_descr in self.registered_transforms.iteritems(): sf = StatefulTransform( trans_descr['class'], *trans_descr['args'], **trans_descr['kwargs'] ) sf.namestring = namestring self.transforms.append(sf) environment = create_trading_environment( start=self.start_datetime, end=self.end_datetime, capital_base=self.capital_base ) # create transforms and zipline self.gen = self._create_generator(environment) # loop through simulated_trading, each iteration returns a # perf ndict perfs = list(self.gen) # convert perf ndict to pandas dataframe daily_stats = self._create_daily_stats(perfs) return daily_stats
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)
def test_factory_daily(self): trading_environment = factory.create_trading_environment() trade_source = factory.create_daily_trade_source( [133], 200, trading_environment ) prev = None for trade in trade_source: if prev: self.assertTrue(trade.dt > prev.dt) prev = trade
def test_generator_dates(self): """ Ensure the pipeline of generators are in sync, at least as far as their current dates. """ algo = TestAlgo(self) trading_environment = factory.create_trading_environment( start=datetime(2012, 1, 3, tzinfo=pytz.utc), end=datetime(2012, 7, 30, tzinfo=pytz.utc)) trade_source = factory.create_daily_trade_source([8229], 200, trading_environment) algo.set_sources([trade_source]) gen = algo.get_generator(trading_environment) self.assertTrue(list(gen)) self.assertTrue(algo.slippage.latest_date) self.assertTrue(algo.latest_date)
def test_generator_dates(self): """ Ensure the pipeline of generators are in sync, at least as far as their current dates. """ algo = TestAlgo(self) trading_environment = factory.create_trading_environment( start=datetime(2011, 7, 30, tzinfo=pytz.utc), end=datetime(2012, 7, 30, tzinfo=pytz.utc) ) trade_source = factory.create_daily_trade_source( [8229], 200, trading_environment ) algo.set_sources([trade_source]) gen = algo.get_generator(trading_environment) self.assertTrue(list(gen)) self.assertTrue(algo.slippage.latest_date) self.assertTrue(algo.latest_date)
def run(self, source, start=None, end=None): """Run the algorithm. :Arguments: source : can be either: - pandas.DataFrame - zipline source - list of zipline sources If pandas.DataFrame is provided, it must have the following structure: * column names must consist of ints representing the different sids * index must be DatetimeIndex * array contents should be price info. :Returns: daily_stats : pandas.DataFrame Daily performance metrics such as returns, alpha etc. """ if isinstance(source, (list, tuple)): assert start is not None and end is not None, \ """When providing a list of sources, \ start and end date have to be specified.""" elif isinstance(source, pd.DataFrame): # if DataFrame provided, wrap in DataFrameSource source = DataFrameSource(source) elif isinstance(source, pd.Panel): source = DataPanelSource(source) # If values not set, try to extract from source. if start is None: start = source.start if end is None: end = source.end if not isinstance(source, (list, tuple)): self.sources = [source] else: self.sources = source # Create transforms by wrapping them into StatefulTransforms self.transforms = [] for namestring, trans_descr in self.registered_transforms.iteritems(): sf = StatefulTransform( trans_descr['class'], *trans_descr['args'], **trans_descr['kwargs'] ) sf.namestring = namestring self.transforms.append(sf) environment = create_trading_environment( start=start, end=end, capital_base=self.capital_base ) # create transforms and zipline self.gen = self._create_generator(environment) # loop through simulated_trading, each iteration returns a # perf ndict perfs = list(self.gen) # convert perf ndict to pandas dataframe daily_stats = self._create_daily_stats(perfs) return daily_stats
def create_test_zipline(**config): """ :param config: A configuration object that is a dict with: - environment - a \ :py:class:`zipline.finance.trading.TradingEnvironment` - sid - an integer, which will be used as the security ID. - order_count - the number of orders the test algo will place, defaults to 100 - order_amount - the number of shares per order, defaults to 100 - trade_count - the number of trades to simulate, defaults to 101 to ensure all orders are processed. - algorithm - optional parameter providing an algorithm. defaults to :py:class:`zipline.test.algorithms.TestAlgorithm` - trade_source - optional parameter to specify trades, if present. If not present :py:class:`zipline.sources.SpecificEquityTrades` is the source, with daily frequency in trades. - slippage: optional parameter that configures the :py:class:`zipline.gens.tradingsimulation.TransactionSimulator`. Expects an object with a simulate mehod, such as :py:class:`zipline.gens.tradingsimulation.FixedSlippage`. :py:mod:`zipline.finance.trading` - transforms: optional parameter that provides a list of StatefulTransform objects. """ assert isinstance(config, dict) sid_list = config.get('sid_list') if not sid_list: sid = config.get('sid') sid_list = [sid] concurrent_trades = config.get('concurrent_trades', False) #-------------------- # Trading Environment #-------------------- if 'environment' in config: trading_environment = config['environment'] else: trading_environment = factory.create_trading_environment() if 'order_count' in config: order_count = config['order_count'] else: order_count = 100 if 'order_amount' in config: order_amount = config['order_amount'] else: order_amount = 100 if 'trade_count' in config: trade_count = config['trade_count'] else: # to ensure all orders are filled, we provide one more # trade than order trade_count = 101 #------------------- # Create the Algo #------------------- if 'algorithm' in config: test_algo = config['algorithm'] else: test_algo = TestAlgorithm( sid, order_amount, order_count ) #------------------- # Trade Source #------------------- if 'trade_source' in config: trade_source = config['trade_source'] else: trade_source = factory.create_daily_trade_source( sid_list, trade_count, trading_environment, concurrent=concurrent_trades ) test_algo.set_sources([trade_source]) #------------------- # Transforms #------------------- transforms = config.get('transforms', None) if transforms is not None: test_algo.set_transforms(transforms) #------------------- # Slippage # ------------------ slippage = config.get('slippage', None) if slippage is not None: test_algo.set_slippage(slippage) # ------------------ # generator/simulator sim = test_algo.get_generator(trading_environment) return sim
def run(self, source, start=None, end=None): """Run the algorithm. :Arguments: source : can be either: - pandas.DataFrame - zipline source - list of zipline sources If pandas.DataFrame is provided, it must have the following structure: * column names must consist of ints representing the different sids * index must be DatetimeIndex * array contents should be price info. :Returns: daily_stats : pandas.DataFrame Daily performance metrics such as returns, alpha etc. """ if isinstance(source, (list, tuple)): assert start is not None and end is not None, \ """When providing a list of sources, \ start and end date have to be specified.""" elif isinstance(source, pd.DataFrame): assert isinstance(source.index, pd.tseries.index.DatetimeIndex) # if DataFrame provided, wrap in DataFrameSource source = DataFrameSource(source) # If values not set, try to extract from source. if start is None: start = source.start if end is None: end = source.end if not isinstance(source, (list, tuple)): self.sources = [source] else: self.sources = source # Create transforms by wrapping them into StatefulTransforms self.transforms = [] for namestring, trans_descr in self.registered_transforms.iteritems(): sf = StatefulTransform(trans_descr['class'], *trans_descr['args'], **trans_descr['kwargs']) sf.namestring = namestring self.transforms.append(sf) environment = create_trading_environment(start=start, end=end) # create transforms and zipline self.gen = self._create_generator(environment) # loop through simulated_trading, each iteration returns a # perf ndict perfs = list(self.gen) # convert perf ndict to pandas dataframe daily_stats = self._create_daily_stats(perfs) return daily_stats
def transaction_sim(self, **params): """ This is a utility method that asserts expected results for conversion of orders to transactions given a trade history""" trade_count = params['trade_count'] trade_interval = params['trade_interval'] trade_delay = params.get('trade_delay') order_count = params['order_count'] order_amount = params['order_amount'] order_interval = params['order_interval'] expected_txn_count = params['expected_txn_count'] expected_txn_volume = params['expected_txn_volume'] # optional parameters # --------------------- # if present, alternate between long and short sales alternate = params.get('alternate') # if present, expect transaction amounts to match orders exactly. complete_fill = params.get('complete_fill') sid = 1 trading_environment = factory.create_trading_environment() trade_sim = TransactionSimulator() price = [10.1] * trade_count volume = [100] * trade_count start_date = trading_environment.first_open generated_trades = factory.create_trade_history( sid, price, volume, trade_interval, trading_environment ) if alternate: alternator = -1 else: alternator = 1 order_date = start_date for i in xrange(order_count): order = ndict({ 'sid': sid, 'amount': order_amount * alternator ** i, 'dt': order_date }) trade_sim.place_order(order) order_date = order_date + order_interval # move after market orders to just after market next # market open. if order_date.hour >= 21: if order_date.minute >= 00: order_date = order_date + timedelta(days=1) order_date = order_date.replace(hour=14, minute=30) # there should now be one open order list stored under the sid oo = trade_sim.open_orders self.assertEqual(len(oo), 1) self.assertTrue(sid in oo) order_list = oo[sid] self.assertEqual(order_count, len(order_list)) for i in xrange(order_count): order = order_list[i] self.assertEqual(order.sid, sid) self.assertEqual(order.amount, order_amount * alternator ** i) tracker = PerformanceTracker(trading_environment) # this approximates the loop inside TradingSimulationClient transactions = [] for trade in generated_trades: if trade_delay: trade.dt = trade.dt + trade_delay trade_sim.update(trade) if trade.TRANSACTION: transactions.append(trade.TRANSACTION) tracker.process_event(trade) if complete_fill: self.assertEqual(len(transactions), len(order_list)) total_volume = 0 for i in xrange(len(transactions)): txn = transactions[i] total_volume += txn.amount if complete_fill: order = order_list[i] self.assertEqual(order.amount, txn.amount) self.assertEqual(total_volume, expected_txn_volume) self.assertEqual(len(transactions), expected_txn_count) cumulative_pos = tracker.cumulative_performance.positions[sid] self.assertEqual(total_volume, cumulative_pos.amount) # the open orders should now be empty oo = trade_sim.open_orders self.assertTrue(sid in oo) order_list = oo[sid] self.assertEqual(0, len(order_list))
def transaction_sim(self, **params): """ This is a utility method that asserts expected results for conversion of orders to transactions given a trade history""" trade_count = params['trade_count'] trade_interval = params['trade_interval'] trade_delay = params.get('trade_delay') order_count = params['order_count'] order_amount = params['order_amount'] order_interval = params['order_interval'] expected_txn_count = params['expected_txn_count'] expected_txn_volume = params['expected_txn_volume'] # optional parameters # --------------------- # if present, alternate between long and short sales alternate = params.get('alternate') # if present, expect transaction amounts to match orders exactly. complete_fill = params.get('complete_fill') sid = 1 trading_environment = factory.create_trading_environment() trade_sim = TransactionSimulator() price = [10.1] * trade_count volume = [100] * trade_count start_date = trading_environment.first_open generated_trades = factory.create_trade_history( sid, price, volume, trade_interval, trading_environment) if alternate: alternator = -1 else: alternator = 1 order_date = start_date for i in xrange(order_count): order = ndict({ 'sid': sid, 'amount': order_amount * alternator**i, 'dt': order_date }) trade_sim.place_order(order) order_date = order_date + order_interval # move after market orders to just after market next # market open. if order_date.hour >= 21: if order_date.minute >= 00: order_date = order_date + timedelta(days=1) order_date = order_date.replace(hour=14, minute=30) # there should now be one open order list stored under the sid oo = trade_sim.open_orders self.assertEqual(len(oo), 1) self.assertTrue(sid in oo) order_list = oo[sid] self.assertEqual(order_count, len(order_list)) for i in xrange(order_count): order = order_list[i] self.assertEqual(order.sid, sid) self.assertEqual(order.amount, order_amount * alternator**i) tracker = PerformanceTracker(trading_environment) # this approximates the loop inside TradingSimulationClient transactions = [] for trade in generated_trades: if trade_delay: trade.dt = trade.dt + trade_delay trade_sim.update(trade) if trade.TRANSACTION: transactions.append(trade.TRANSACTION) tracker.process_event(trade) if complete_fill: self.assertEqual(len(transactions), len(order_list)) total_volume = 0 for i in xrange(len(transactions)): txn = transactions[i] total_volume += txn.amount if complete_fill: order = order_list[i] self.assertEqual(order.amount, txn.amount) self.assertEqual(total_volume, expected_txn_volume) self.assertEqual(len(transactions), expected_txn_count) cumulative_pos = tracker.cumulative_performance.positions[sid] self.assertEqual(total_volume, cumulative_pos.amount) # the open orders should now be empty oo = trade_sim.open_orders self.assertTrue(sid in oo) order_list = oo[sid] self.assertEqual(0, len(order_list))
def create_test_zipline(**config): """ :param config: A configuration object that is a dict with: - environment - a \ :py:class:`zipline.finance.trading.TradingEnvironment` - sid - an integer, which will be used as the security ID. - order_count - the number of orders the test algo will place, defaults to 100 - order_amount - the number of shares per order, defaults to 100 - trade_count - the number of trades to simulate, defaults to 101 to ensure all orders are processed. - algorithm - optional parameter providing an algorithm. defaults to :py:class:`zipline.test.algorithms.TestAlgorithm` - trade_source - optional parameter to specify trades, if present. If not present :py:class:`zipline.sources.SpecificEquityTrades` is the source, with daily frequency in trades. - slippage: optional parameter that configures the :py:class:`zipline.gens.tradingsimulation.TransactionSimulator`. Expects an object with a simulate mehod, such as :py:class:`zipline.gens.tradingsimulation.FixedSlippage`. :py:mod:`zipline.finance.trading` - transforms: optional parameter that provides a list of StatefulTransform objects. """ assert isinstance(config, dict) sid_list = config.get('sid_list') if not sid_list: sid = config.get('sid') sid_list = [sid] concurrent_trades = config.get('concurrent_trades', False) #-------------------- # Trading Environment #-------------------- if 'environment' in config: trading_environment = config['environment'] else: trading_environment = factory.create_trading_environment() if 'order_count' in config: order_count = config['order_count'] else: order_count = 100 if 'order_amount' in config: order_amount = config['order_amount'] else: order_amount = 100 if 'trade_count' in config: trade_count = config['trade_count'] else: # to ensure all orders are filled, we provide one more # trade than order trade_count = 101 #------------------- # Create the Algo #------------------- if 'algorithm' in config: test_algo = config['algorithm'] else: test_algo = TestAlgorithm(sid, order_amount, order_count) #------------------- # Trade Source #------------------- if 'trade_source' in config: trade_source = config['trade_source'] else: trade_source = factory.create_daily_trade_source( sid_list, trade_count, trading_environment, concurrent=concurrent_trades) test_algo.set_sources([trade_source]) #------------------- # Transforms #------------------- transforms = config.get('transforms', None) if transforms is not None: test_algo.set_transforms(transforms) #------------------- # Slippage # ------------------ slippage = config.get('slippage', None) if slippage is not None: test_algo.set_slippage(slippage) # ------------------ # generator/simulator sim = test_algo.get_generator(trading_environment) return sim