diff --git a/zipline/lines.py b/zipline/lines.py index 6d398cfe..3a7cd0b4 100644 --- a/zipline/lines.py +++ b/zipline/lines.py @@ -1,20 +1,20 @@ """ -Ziplines are composed of multiple components connected by asynchronous -messaging. All ziplines follow a general topology of parallel sources, -datetimestamp serialization, parallel transformations, and finally sinks. -Furthermore, many ziplines have common needs. For example, all trade -simulations require a +Ziplines are composed of multiple components connected by asynchronous +messaging. All ziplines follow a general topology of parallel sources, +datetimestamp serialization, parallel transformations, and finally sinks. +Furthermore, many ziplines have common needs. For example, all trade +simulations require a :py:class:`~zipline.finance.trading.TradeSimulationClient`. -To establish best practices and minimize code replication, the lines module +To establish best practices and minimize code replication, the lines module provides complete zipline topologies. You can extend any zipline without the need to extend the class. Simply instantiate any additional components -that you would like included in the zipline, and add them to the zipline -before invoking simulate. +that you would like included in the zipline, and add them to the zipline +before invoking simulate. + - Here is a diagram of the SimulatedTrading zipline: - + +----------------------+ +------------------------+ | Trade History | | (DataSource added | @@ -89,36 +89,36 @@ LOGGER = logging.getLogger('ZiplineLogger') class SimulatedTrading(object): """ Zipline with:: - + - _no_ data sources. - Trade simulation client, which is available to send callbacks on events and also accept orders to be simulated. - An order data source, which will receive orders from the trade - simulation client, and feed them into the event stream to be + simulation client, and feed them into the event stream to be serialized and order alongside all other data source events. - transaction simulation transformation, which receives the order events and estimates a theoretical execution price and volume. - + All components in this zipline are subject to heartbeat checks and a control monitor, which can kill the entire zipline in the event of exceptions in one of the components or an external request to end the simulation. """ - + def __init__(self, **config): """ :param config: a dict with the following required properties:: - + - algorithm: a class that follows the algorithm protocol. See - :py:meth:`zipline.finance.trading.TradingSimulationClient.add_algorithm` + :py:meth:`zipline.finance.trading.TradingSimulationClient.add_algorithm for details. - trading_environment: an instance of :py:class:`zipline.trading.TradingEnvironment` - - allocator: an instance of + - allocator: an instance of :py:class:`zipline.simulator.AddressAllocator` - - simulator_class: a :py:class:`zipline.core.host.ComponentHost` + - simulator_class: a :py:class:`zipline.core.host.ComponentHost` subclass (not an instance) - - simulation_style: optional parameter that configures the + - simulation_style: optional parameter that configures the :py:class:`zipline.finance.trading.TransactionSimulator`. Expects a SIMULATION_STYLE as defined in :py:mod:`zipline.finance.trading` """ @@ -127,10 +127,10 @@ class SimulatedTrading(object): self.allocator = config['allocator'] self.trading_environment = config['trading_environment'] self.sim_style = config.get('simulation_style') - + self.leased_sockets = [] self.sim_context = None - + sockets = self.allocate_sockets(8) addresses = { 'sync_address' : sockets[0], @@ -152,66 +152,66 @@ class SimulatedTrading(object): self.con.manage( 'freeform' ) - + self.started = False - + self.sim = config['simulator_class'](addresses) - + self.clients = {} self.trading_client = TradeSimulationClient( self.trading_environment, self.sim_style ) self.add_client(self.trading_client) - + # setup all sources self.sources = {} #self.order_source = OrderDataSource() #self.add_source(self.order_source) - + #setup transforms #self.transaction_sim = TransactionSimulator(self.sim_style) self.transforms = {} #self.add_transform(self.transaction_sim) - + self.sim.register_controller( self.con ) self.sim.on_done = self.shutdown() - - + + self.trading_client.set_algorithm(self.algorithm) - + @staticmethod def create_test_zipline(**config): """ :param config: A configuration object that is a dict with: - + - environment - a \ :py:class:`zipline.finance.trading.TradingEnvironment` - allocator - a :py:class:`zipline.simulator.AddressAllocator` - - sid - an integer, which will be used as the security ID. + - 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. - - simulator_class - optional parameter that provides an alternative + - simulator_class - optional parameter that provides an alternative subclass of ComponentHost to hold the whole zipline. Defaults to - :py:class:`zipline.simulator.Simulator` + :py:class:`zipline.simulator.Simulator` - 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:`ziplien.sources.SpecificEquityTrades` + If not present :py:class:`ziplien.sources.SpecificEquityTrades` is the source, with daily frequency in trades. - - simulation_style: optional parameter that configures the + - simulation_style: optional parameter that configures the :py:class:`zipline.finance.trading.TransactionSimulator`. Expects a SIMULATION_STYLE as defined in :py:mod:`zipline.finance.trading` """ assert isinstance(config, dict) - + allocator = config['allocator'] sid = config['sid'] - + #-------------------- # Trading Environment #-------------------- @@ -219,33 +219,33 @@ class SimulatedTrading(object): trading_environment = config['environment'] else: trading_environment = factory.create_trading_environment() - + if config.has_key('order_count'): order_count = config['order_count'] else: order_count = 100 - + if config.has_key('order_amount'): order_amount = config['order_amount'] else: order_amount = 100 - + if config.has_key('trade_count'): trade_count = config['trade_count'] else: # to ensure all orders are filled, we provide one more # trade than order trade_count = 101 - + if config.has_key('simulator_class'): simulator_class = config['simulator_class'] else: simulator_class = Simulator - + simulation_style = config.get('simulation_style') if not simulation_style: simulation_style = SIMULATION_STYLE.FIXED_SLIPPAGE - + #------------------- # Trade Source #------------------- @@ -285,41 +285,41 @@ class SimulatedTrading(object): zipline.add_source(trade_source) return zipline - + def add_source(self, source): """ Adds the source to the zipline, sets the sid filter of the source to the algorithm's sid filter. """ assert isinstance(source, DataSource) - self.check_started() + self.check_started() source.set_filter('SID', self.algorithm.get_sid_filter()) self.sim.register_components([source]) self.sources[source.get_id] = source - + def add_transform(self, transform): assert isinstance(transform, BaseTransform) self.check_started() self.sim.register_components([transform]) self.transforms[transform.get_id] = transform - + def add_client(self, client): assert isinstance(client, TradeSimulationClient) self.check_started() self.sim.register_components([client]) self.clients[client.get_id] = client - + def check_started(self): if self.started: raise ZiplineException("TradeSimulation", "You cannot add \ components after the simulation has begun.") - + def get_cumulative_performance(self): return self.trading_client.perf.cumulative_performance.to_dict() - + def publish_to(self, result_socket): self.trading_client.perf.publish_to(result_socket) - + def allocate_sockets(self, n): """ Allocate sockets local to this line, track them so @@ -333,7 +333,7 @@ class SimulatedTrading(object): self.leased_sockets.extend(leased) return leased - + def simulate(self, blocking=False): self.started = True self.sim_context = self.sim.simulate() @@ -343,11 +343,11 @@ class SimulatedTrading(object): def shutdown(self): pass #self.allocator.reaquire(*self.leased_sockets) - + #-------------------------------- # Component property accessors #-------------------------------- - + def get_positions(self): """ returns current positions as a dict. draws from the cumulative @@ -356,14 +356,14 @@ class SimulatedTrading(object): perf = self.trading_client.perf.cumulative_performance positions = perf.get_positions() return positions - + class ZiplineException(Exception): def __init__(self, zipline_name, msg): self.name = zipline_name self.message = msg - + def __str__(self): return "Unexpected exception {line}: {msg}".format( - line=self.name, + line=self.name, msg=self.message )