Python: KeyError 'shift'

I am new to Python and trying to change a couple of trading scripts that I found here: https://github.com/quantopian/zipline/blob/master/zipline/examples/pairtrade.py

The original script is for price use only. I would like to use returns to fit my models and price for the quantity invested, but I don’t see how to do it.

I tried:

  • to define the data frame of returns in the main line and call it in run
  • to define the return data frame mainly as a global object and use it where necessary in the "descriptor data"
  • to define a frame of retun data directly in the descriptor data

I assume the latter option is the most suitable, but then I have an error with the panda 'shift attribute.

In particular, I am trying to define "DataRegression" as follows:

DataRegression = data.copy() DataRegression[Stock1]=DataRegression[Stock1]/DataRegression[Stock1].shift(1)-1 DataRegression[Stock2]=DataRegression[Stock2]/DataRegression[Stock2].shift(1)-1 DataRegression[Stock3]=DataRegression[Stock3]/DataRegression[Stock3].shift(1)-1 DataRegression = DataRegression.dropna(axis=0) 

where "data" is a data frame that contains prices, column names stock1, stock2 and stock3 defined globally. These lines in the descriptor data return an error:

 File "A:\Apps\Python\Python.2.7.3.x86\lib\site-packages\zipline-0.5.6-py2.7.egg\zipline\utils\protocol_utils.py", line 85, in __getattr__ return self.__internal[key] KeyError: 'shift' 

Does anyone know why and how to do it right?

Thanks a lot Vincent

+4
source share
1 answer

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

+2
source

All Articles