From 2600bbe1deaafef8cf5a351df9e134622f130357 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Sun, 10 Feb 2013 21:35:41 -0500 Subject: [PATCH] Backfills a batch transform panel with supplemental data. For the case where the window isn't covered by the data streaming through the simulator. e.g. in a case where the stocks being iterated over change every quarter, the supplemental data will fill in the 'gap' missing from the transform since the 'new' stocks were not streaming before the beginning of the quarter. Of note, test cases are covered by internal suites, but this could use tests with completely mocked data. --- zipline/transforms/utils.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/zipline/transforms/utils.py b/zipline/transforms/utils.py index e4a4ed42..7aa60c73 100644 --- a/zipline/transforms/utils.py +++ b/zipline/transforms/utils.py @@ -381,6 +381,12 @@ class BatchTransform(EventWindow): self.updated = False self.cached = None + # Data panel that provides bar information to fill in the window, + # when no bar ticks are available from the data source generator + # Used in universes that 'rollover', e.g. one that has a different + # set of stocks per quarter + self.supplemental_data = None + def handle_data(self, data, *args, **kwargs): """ New method to handle a data frame as sent to the algorithm's @@ -466,6 +472,16 @@ class BatchTransform(EventWindow): data = pd.Panel(data_dict, major_axis=self.field_names, minor_axis=self.sids) + if self.supplemental_data: + # item will be a date stamp + for item in data.items: + try: + data[item] = self.supplemental_data[item].combine_first( + data[item]) + except KeyError: + # Only filling in data available in supplemental data. + pass + data = data.swapaxes(0, 1) if self.clean_nans: @@ -478,6 +494,11 @@ class BatchTransform(EventWindow): # This will drop a leading row of N/A data = data.dropna(axis=1) + # Hold on to a reference to the data, + # so that it's easier to find the current data when stepping + # through with a debugger + self.curr_data = data + return data def handle_remove(self, event):