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

bt.Backtest回测Oanda行情报错'Series' object has no attribute 'columns'求助

问题排查与解决方案

错误根源

  • 核心问题出在price_data的类型不符合bt.Backtest的入参要求:bt.Backtest要求传入的行情数据是列名为交易标的名称的Pandas DataFrame,但你代码里用price_data=EURUSD_df['close']取出来的是Pandas Series类型,没有columns属性,触发报错。
  • 额外的问题:你给price_data追加空行price_data=price_data.append(pd.Series(name='NameOfNewRow'))的操作完全没有必要,还会引入无效索引干扰回测时间序列对齐,建议删除。
  • 隐性问题:你之前把索引转成字符串格式的操作不符合bt的要求,bt要求行情索引必须为datetime类型才能正常识别时间周期。

修复步骤

1. 修正索引格式

删除把索引转成字符串的strftime操作,保留datetime类型:

# 修正前(错误):EURUSD_df.index=pd.to_datetime(EURUSD_df.index, format = '%Y-%m-%d').strftime('%Y-%m-%d')
# 修正后(正确):
EURUSD_df.index = pd.to_datetime(EURUSD_df.index, format = '%Y-%m-%d')

2. 修正price_data的类型

把取收盘价的单括号改为双括号,得到DataFrame格式,同时给列命名为交易标的名称EURUSD:

# 修正前(错误):price_data=EURUSD_df['close']
# 修正后(正确):
price_data = EURUSD_df[['close']]
price_data.columns = ['EURUSD']

3. 修正信号列名匹配

bt.algos.WeighTarget要求信号DataFrame的列名和行情DataFrame的列名完全对应,所以给signal也设置相同的列名:

signal.columns = ['EURUSD']

4. 删除无效的追加空行代码

删掉这行冗余逻辑:

price_data=price_data.append(pd.Series(name='NameOfNewRow'))

修正后完整可运行代码

import pandas as pd
import talib
import bt
import matplotlib.pyplot as plt

# 修正索引为datetime类型
EURUSD_df.index = pd.to_datetime(EURUSD_df.index, format = '%Y-%m-%d')

# 计算长短周期EMA
EMA_short=talib.EMA(EURUSD_df['close'],timeperiod=10).to_frame()
EMA_long=talib.EMA(EURUSD_df['close'],timeperiod=40).to_frame()

# 生成交易信号
signal=EMA_long.copy()
signal[EMA_long.isnull()]=0
signal[EMA_short>EMA_long]=1
signal[EMA_short<EMA_long]=-1
# 信号列名和行情列名保持一致
signal.columns = ['EURUSD']

# 可视化信号与均线
combined_df=bt.merge(signal,EURUSD_df["close"],EMA_short,EMA_long)
combined_df.columns=["Signal","Price","EMA_short","EMA_long"]
combined_df.plot(secondary_y=["Signal"])

# 构建符合bt要求的行情DataFrame
price_data = EURUSD_df[['close']]
price_data.columns = ['EURUSD']

# 运行回测
bt_strategy = bt.Strategy('EMA_crossover',
                          [bt.algos.WeighTarget(signal),
                          bt.algos.Rebalance()])
bt_backtest = bt.Backtest(bt_strategy,price_data)
bt_result = bt.run(bt_backtest)
bt_result.plot(title='Backtest result')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 17:15:03