diff --git a/zipline/gens/returns.py b/zipline/gens/returns.py index 1fcfabaa..6b04bc43 100644 --- a/zipline/gens/returns.py +++ b/zipline/gens/returns.py @@ -9,18 +9,17 @@ class Returns(object): def __init__(self, days): self.days = days self.mapping = defaultdict(self._create) - + def update(self, event): """ Update and return the calculated returns for this event's sid. """ assert event.has_key('dt') assert event.has_key('price') - - import nose.tools; nose.tools.set_trace() + tracker = self.mapping[event.sid] tracker.update(event) - + return tracker.get_returns() def _create(self): @@ -29,7 +28,7 @@ class Returns(object): class ReturnsFromPriorClose(object): """ Records the last N closing events for a given security as well as the - last event for the security. When we get an event for a new day, we + last event for the security. When we get an event for a new day, we treat the last event seen as the close for the previous day. """ @@ -43,11 +42,11 @@ class ReturnsFromPriorClose(object): return self.returns def update(self, event): - + if self.last_event: # Day has changed since the last event we saw. Treat - # the last event as the closing price for its day and + # the last event as the closing price for its day and # clear out the oldest close if it has expired. if self.last_event.dt.date() != event.dt.date(): @@ -68,11 +67,10 @@ class ReturnsFromPriorClose(object): # to avoid. if len(self.closes) == self.days: - last_close = self.closes[0] + last_close = self.closes[0] change = event.price - last_close self.returns = change / last_close # the current event is now the last_event self.last_event = event - diff --git a/zipline/lines.py b/zipline/lines.py index 4a54fb5d..5fe87a0d 100644 --- a/zipline/lines.py +++ b/zipline/lines.py @@ -61,7 +61,10 @@ before invoking simulate. """ import sys import zmq +import os +from signal import SIGHUP import multiprocessing +from setproctitle import setproctitle from zipline.test_algorithms import TestAlgorithm from zipline.finance.trading import SIMULATION_STYLE @@ -111,15 +114,17 @@ class SimulatedTrading(object): # optional process if we fork simulate into an # independent process. self.proc = None + self.send_sighup = False self.logger = Logger(sim_id) - def simulate(self, blocking=True): + def simulate(self, blocking=True, send_sighup=False): # for non-blocking, if blocking: self.run_gen() else: + self.send_sighup = send_sighup return self.fork_and_sim() def fork_and_sim(self): @@ -128,7 +133,7 @@ class SimulatedTrading(object): return self.proc def run_gen(self): - + setproctitle(self.sim_id) self.open() if self.zmq_out: @@ -169,6 +174,10 @@ class SimulatedTrading(object): def close(self): log.info("Closing Simulation: {id}".format(id=self.sim_id)) + if self.proc and self.send_sighup: + ppid = os.getppid() + log.warning("Sending SIGHUP") + os.kill(ppid, SIGHUP) def cancel(self): if self.proc and self.proc.is_alive(): @@ -234,6 +243,12 @@ class SimulatedTrading(object): if self.proc: self.proc.join() + def get_pids(self): + if self.proc: + return [self.proc.pid] + else: + return [] + @staticmethod def create_test_zipline(**config): """ diff --git a/zipline/utils/test_utils.py b/zipline/utils/test_utils.py index 036ebe02..e94c49ee 100644 --- a/zipline/utils/test_utils.py +++ b/zipline/utils/test_utils.py @@ -113,6 +113,7 @@ def drain_receiver(receiver): def assert_single_position(test, zipline): + import nose.tools; nose.tools.set_trace() output, transaction_count = drain_zipline(test, zipline) test.assertEqual(