Python: KeyError 'shift'错误

4 投票
1 回答
1231 浏览
提问于 2025-04-17 15:29

我刚开始学习Python,想修改一个我在这里找到的配对交易脚本:

https://github.com/quantopian/zipline/blob/master/zipline/examples/pairtrade.py

这个原始脚本只使用价格数据。我想用收益率来调整我的模型,同时用价格来计算投资数量,但我不知道该怎么做。

我尝试过:

  • 在主程序中定义一个收益率的数据框,并在运行时调用它
  • 在主程序中将收益率的数据框定义为全局对象,并在“处理数据”时使用
  • 直接在处理数据中定义一个收益率的数据框

我认为最后一个选项是最合适的,但我在使用pandas的'shift'属性时遇到了错误。

更具体地说,我尝试这样定义'DataRegression':

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)

其中'data'是一个数据框,包含价格、stock1、stock2和stock3这些全局定义的列名。在处理数据时,这些代码行返回了错误:

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'

有没有人知道为什么会这样,以及如何正确地做到这一点?

非常感谢,
Vincent

1 个回答

2

这是个有趣的想法。在zipline中,最简单的方法是使用Returns转换,这样可以在事件框架中添加一个返回值字段(这个框架是ndict,而不是某些人提到的pandas DataFrame)。

为此,你需要在初始化方法中添加这个转换:

self.add_transform(Returns, 'returns', window_length=1)

(记得在开头加上from zipline.transforms import Returns)。

然后,在batch_transform内部,你可以访问返回值而不是价格:

@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

另外,你也可以创建一个batch_transform,把价格转换成返回值,就像你想做的那样。

@batch_transform
def returns(data):
    return data.price / data.price.shift(1) - 1

然后把这个传递给OLS转换。或者在OLS转换内部进行这个计算。

希望这对你有帮助,

Thomas

撰写回答