Quantopian自定义因子报错:零尺寸数组与类型错误求助
解决Quantopian自定义因子的两类错误
让我一步步帮你排查和解决这两个问题:
错误1:ValueError: zero-size array to reduction operation fmin which has no identity
这个错误的根源是你用了反向切片,导致生成了空数组,np.amin/np.amax没法处理空数组,所以抛出了这个异常。
看你代码里这两行:
atr = np.mean(tr[-1:-21], axis=0) #skip the first one as it will be NaN aprcomp = (apr[-1] - np.amin(apr[-2:-101], axis=0))/(np.amax(apr[-2:-101], axis=0) - np.amin(apr[-2:-101], axis=0))
在NumPy中,切片的格式是[start:end],当start的位置比end更靠后(比如-1比-21更接近当前时间),且步长为正的时候,切片结果就是空数组。你本来想取最近20天的TR,结果写成了从倒数第1天到倒数第21天(反向),自然拿不到数据。
修正后的代码:
class ATrComp(CustomFactor): inputs = [USEquityPricing.close, USEquityPricing.high, USEquityPricing.low] window_length = 200 def compute(self, today, assets, out, close, high, low): hml = high - low hmpc = np.abs(high - np.roll(close, 1, axis=0)) lmpc = np.abs(low - np.roll(close, 1, axis=0)) tr = np.maximum(hml, np.maximum(hmpc, lmpc)) # 取最近20天的TR(跳过第一天的NaN,所以取最后20个元素) atr = np.mean(tr[-20:], axis=0) apr = atr * 100 / close[-1] # 取倒数第100天到倒数第2天的apr数据,避免空数组 apr_window = apr[-100:-1] # 加入小epsilon防止分母为0(极端情况) aprcomp = (apr[-1] - np.amin(apr_window, axis=0)) / (np.amax(apr_window, axis=0) - np.amin(apr_window, axis=0) + 1e-8) out[:] = aprcomp
错误2:TypeError: zipline.pipeline.term.__getitem__() expected a value of type zipline.assets._assets.Asset for argument 'key', but got int instead
这个错误是因为你误解了CustomFactor的使用方式:你不能在一个CustomFactor的compute方法里直接实例化另一个CustomFactor,然后用整数索引去取值。ATrp()是一个Pipeline Term,它的索引只能用于资产(Asset对象),不能用整数。
解决方案:把两个因子的逻辑合并(最直接)
既然ATrp只是计算apr,不如直接把它的逻辑整合到ATrComp里,避免跨因子调用的问题(就像上面修正后的ATrComp代码那样)。如果一定要拆分,你需要把ATrp作为ATrComp的输入项,具体做法如下:
class ATrp(CustomFactor): inputs = [USEquityPricing.close, USEquityPricing.high, USEquityPricing.low] window_length = 200 def compute(self, today, assets, out, close, high, low): hml = high - low hmpc = np.abs(high - np.roll(close, 1, axis=0)) lmpc = np.abs(low - np.roll(close, 1, axis=0)) tr = np.maximum(hml, np.maximum(hmpc, lmpc)) atr = np.mean(tr[-20:], axis=0) apr = atr * 100 / close[-1] out[:] = apr # 把ATrp作为输入传递给ATrComp class ATrComp(CustomFactor): # 注意这里的inputs是ATrp()实例,不是原始价格数据 inputs = [ATrp()] window_length = 200 def compute(self, today, assets, out, apr): # apr的形状是(window_length, num_assets),所以取最近的窗口数据 apr_window = apr[-100:-1] aprcomp = (apr[-1] - np.amin(apr_window, axis=0)) / (np.amax(apr_window, axis=0) - np.amin(apr_window, axis=0) + 1e-8) out[:] = aprcomp
这样Pipeline会自动处理ATrp的计算,并把结果传递给ATrComp的compute方法。
内容的提问来源于stack exchange,提问作者Mathew Crogan
相关产品推荐
相关产品推荐

