使用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库的类接口完全兼容。
其他可选解决方案
- 用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方法保持不变
- 手动转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
相关产品推荐
相关产品推荐

