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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:19:56