From d21b500db6b508f5093dfeb61f8ed236845679c5 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Wed, 10 Apr 2013 16:20:44 -0400 Subject: [PATCH] ENH: Emit a rollup of day's performance in minutely emission mode. During minute emissions, it is still helpful to have a final daily performance result, analogous to what would be the final packet in a daily emitted backtest, so that all transactions, etc. are contained in one place. --- zipline/finance/performance.py | 8 +++++--- zipline/gens/tradesimulation.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 6ac8fad4..92d0bef8 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -232,24 +232,26 @@ class PerformanceTracker(object): def get_portfolio(self): return self.cumulative_performance.as_portfolio() - def to_dict(self): + def to_dict(self, emission_type=None): """ Creates a dictionary representing the state of this tracker. Returns a dict object of the form described in header comments. """ + if not emission_type: + emission_type = self.emission_rate _dict = { 'period_start': self.period_start, 'period_end': self.period_end, 'capital_base': self.capital_base, 'cumulative_perf': self.cumulative_performance.to_dict(), } - if self.emission_rate == 'daily': + if emission_type == 'daily': _dict.update({'cumulative_risk_metrics': self.cumulative_risk_metrics.to_dict(), 'daily_perf': self.todays_performance.to_dict(), 'progress': self.progress}) - if self.emission_rate == 'minute': + if emission_type == 'minute': # Currently reusing 'todays_performance' for intraday trading # result, should be analogous, but has the potential for needing # its own configuration down the line. diff --git a/zipline/gens/tradesimulation.py b/zipline/gens/tradesimulation.py index cd4b1491..6a58866f 100644 --- a/zipline/gens/tradesimulation.py +++ b/zipline/gens/tradesimulation.py @@ -290,6 +290,17 @@ class AlgorithmSimulator(object): self.algo.recorded_vars yield message + # When emitting minutely, it is still useful to have a final + # packet with the entire days performance rolled up. + if self.perf_tracker.emission_rate == 'minute': + daily_rollup = self.perf_tracker.to_dict( + emission_type='daily' + ) + daily_rollup['daily_perf']['recorded_vars'] = \ + self.algo.recorded_vars + log.info("emitting daily rollup: %s" % daily_rollup) + yield daily_rollup + yield risk_message def update_universe(self, event):