This is an interesting idea. The easiest way to do this in zipline is to use the Returns transform, which adds a return field to the event frame (which is an ndict, not a pandas DataFrame, as someone pointed out).
To do this, you need to add the transformation to the initialize method: self.add_transform(Returns, 'returns', window_length=1)
(be sure to add from zipline.transforms import Returns at the beginning).
Then inside batch_transform you can access revenue instead of prices:
@batch_transform def ols_transform(data, sid1, sid2): """Computes regression coefficient (slope and intercept) via Ordinary Least Squares between two SIDs. """ p0 = data.returns[sid1] p1 = sm.add_constant(data.returns[sid2]) slope, intercept = sm.OLS(p0, p1).fit().params return slope, intercept
Alternatively, you can also create batch_transform to convert prices to revenue as you wish.
@batch_transform def returns(data): return data.price / data.price.shift(1) - 1
And then pass it on to the OLS transformation. Or do this calculation inside the OLS transform itself.
NTN, Thomas
source share