You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:03:40