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

使用Backtesting.py回测策略报错:'_Array' object has no attribute 'diff'

解决Backtesting.py回测中RSI指标报错'_Array' object has no attribute 'diff'的问题

修复后的代码(推荐方案)

import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
import ta
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import GOOG

class RsiOscillator(Strategy):
    upper_bound = 70
    lower_bound = 30

    def init(self):
        # 使用ta库的函数式RSI接口,适配Backtesting的_Array类型
        self.rsi = self.I(ta.momentum.rsi, self.data.Close, window=14)

    def next(self):
        if crossover(self.rsi, self.upper_bound):
            self.position.close()
        elif crossover(self.lower_bound, self.rsi):
            self.buy()

bt = Backtest(GOOG, RsiOscillator, cash=10000, commission=0.002)
stats = bt.run()
print(stats)

问题原因

报错核心是数据类型不兼容:

  • Backtesting.py新版本中self.data.Close返回的是自定义的_Array对象,而非pandas Series
  • ta库的RSIIndicator类内部依赖pandas Series的diff()方法做计算,但_Array没有这个方法,因此抛出异常

视频里代码能正常运行,大概率是因为当时使用的Backtesting.py版本较旧,那时self.data.Close直接返回pandas Series,和ta库的类接口完全兼容。

其他可选解决方案

  1. 用Backtesting内置RSI实现(最省心)
    直接导入backtesting.lib里的rsi函数,它是专门适配Backtesting数据类型的:
from backtesting.lib import rsi, crossover

class RsiOscillator(Strategy):
    upper_bound = 70
    lower_bound = 30

    def init(self):
        self.rsi = self.I(rsi, self.data.Close, window=14)

    # next方法保持不变
  1. 手动转Series后用ta的类接口
    如果一定要用RSIIndicator类,可以先把_Array转成Series再传入:
from ta.momentum import RSIIndicator

class RsiOscillator(Strategy):
    upper_bound = 70
    lower_bound = 30

    def init(self):
        close_series = pd.Series(self.data.Close)
        # 用lambda包装,让self.I能正确调用指标计算
        self.rsi = self.I(lambda c: RSIIndicator(c, window=14).rsi(), close_series)

    # next方法保持不变

内容的提问来源于stack exchange,提问作者user18625843

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:31:05