Backtrader传入数据触发AttributeError问题求助
问题分析
报错AttributeError: 'tuple' object has no attribute 'lower'出现在Backtrader的PandasData加载数据阶段,核心原因是yfinance新版本返回的DataFrame列名采用MultiIndex(元组格式),而Backtrader的PandasData默认会遍历列名并调用lower()方法,元组类型不支持该方法,因此触发错误。
解决方案
方法1:转换MultiIndex列名为普通字符串
下载数据后先处理列名,将元组格式的列名转为字符串,适配Backtrader的自动识别逻辑:
import backtrader as bt import yfinance as yf cerebro = bt.Cerebro() # 下载数据并处理列名 df = yf.download('BTC-USD', start='2020-01-01', end='2020-12-31') # 单个资产场景下,提取元组的第二个元素作为列名 df.columns = [col[1] if isinstance(col, tuple) else col for col in df.columns] # 多资产场景可改用下划线拼接元组元素:df.columns = ['_'.join(col) for col in df.columns] # 加载处理后的数据 data = bt.feeds.PandasData(dataname=df) cerebro.adddata(data) cerebro.run() cerebro.plot()
方法2:手动指定列名映射
直接在PandasData中明确指定各字段对应的元组列名,跳过自动识别的列名处理步骤:
import backtrader as bt import yfinance as yf cerebro = bt.Cerebro() df = yf.download('BTC-USD', start='2020-01-01', end='2020-12-31') # 直接使用元组格式列名完成字段映射 data = bt.feeds.PandasData( dataname=df, open=('Open', 'BTC-USD'), high=('High', 'BTC-USD'), low=('Low', 'BTC-USD'), close=('Close', 'BTC-USD'), volume=('Volume', 'BTC-USD'), openinterest=None ) cerebro.adddata(data) cerebro.run() cerebro.plot()
方法3:降级yfinance版本
如果不想修改代码,可以降级到返回普通字符串列名的旧版本yfinance:
pip install yfinance==0.2.31
补充说明
旧版bt.feeds.YahooFinanceData无法使用是因为Yahoo Finance的API已更新,该接口已失效,建议采用yfinance配合PandasData的方案。
内容的提问来源于stack exchange,提问作者Navid Yaghmaei
相关产品推荐
相关产品推荐

