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

backtesting.py多时间框架回测报错:RangeIndex类型不兼容问题修复

问题定位与修正:backtesting.py多时间框架回测报错TypeError

问题背景

用户编写基于backtesting.py的多时间框架回测程序,运行时触发如下错误:

TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex'

完整代码如下:

import os
import warnings
from datetime import datetime
!pip install pandas_ta  > /dev/null 2>&1
import pandas as pd
import pandas_ta as ta
import numpy as np
import matplotlib.pyplot as plt

!pip install --upgrade backtesting > /dev/null 2>&1
from backtesting import Backtest, Strategy
from backtesting.lib import resample_apply, crossover
from backtesting.test import SMA

from google.colab import drive
drive.mount('/content/drive')

# -------------------------------------------------------
#  Data pre-processing
# -------------------------------------------------------
# File path to retrieve
file_name = "/content/drive/.../EURUSD_M15_2023"

# If a pickle file exists, retrieve it
try:
    data = pd.read_pickle(f"{file_name}.pkl")

# If a pickle file does not exist, retrieve the csv
except:
    data = pd.read_table(f"{file_name}.csv", sep='\t')

    # Change column names (Must include Open, High, Low, Close)
    data = data.rename(columns={'<OPEN>': 'Open', '<HIGH>': 'High', '<LOW>': 'Low', '<CLOSE>': 'Close', '<VOL>': 'Volume'})

    # Convert the date of the data to datetime type
    data['datetime'] = pd.to_datetime(data['<DATE>']+ ' '+ data['<TIME>'])

    # Specify datetime as the index
    data = data.set_index('datetime')

    # Save as a pkl file and store it in the drive
    data.to_pickle(f"{file_name}.pkl")

# -------------------------------------------------------
#  Logic Description
# -------------------------------------------------------
class Strategry(Strategy):

    def init(self):
        rsi_window = 14
        upper_bound = 70
        lower_bound = 30
        
        close = pd.Series(self.data.Close)
        self.daily_rsi = self.I(ta.rsi, close, self.rsi_window)
        self.weekly_rsi = resample_apply('W-FRI', ta.rsi, pd.Series(self.data.Close), self.rsi_window)


    def next(self):
        if (crossover(self.daily_rsi, self.upper_bound) and
                self.weekly_rsi[-1] > self.upper_bound):
            self.position.close()

        elif (crossover(self.lower_bound, self.daily_rsi) and
                self.lower_bound > self.weekly_rsi[-1]):
            self.buy()

问题定位

  1. 索引类型丢失:读取pickle文件时,原本设置的DatetimeIndex被转为RangeIndex,导致resample_apply无法按时间周期重采样,触发类型错误。
  2. 类名拼写错误:Strategry应为Strategy,会导致策略无法正确初始化。
  3. 参数作用域问题:rsi_window、upper_bound、lower_bound是init方法的局部变量,next方法无法访问,后续会引发NameError。

修正方法

1. 强制保留DatetimeIndex

读取pickle后强制转换索引为DatetimeIndex,避免类型丢失:

try:
    data = pd.read_pickle(f"{file_name}.pkl")
    # 强制转换索引为DatetimeIndex
    data.index = pd.to_datetime(data.index)
except:
    # 原csv处理代码不变
    ...

2. 修正策略类拼写

将类名改为正确的自定义名称(避免与父类冲突):

class MyStrategy(Strategy):
    ...

3. 调整参数为类属性

把策略参数定义为类属性,确保init和next方法都能访问:

class MyStrategy(Strategy):
    # 定义类属性参数
    rsi_window = 14
    upper_bound = 70
    lower_bound = 30
    
    def init(self):
        close = pd.Series(self.data.Close)
        self.daily_rsi = self.I(ta.rsi, close, self.rsi_window)
        self.weekly_rsi = resample_apply('W-FRI', ta.rsi, pd.Series(self.data.Close), self.rsi_window)

    def next(self):
        if (crossover(self.daily_rsi, self.upper_bound) and
                self.weekly_rsi[-1] > self.upper_bound):
            self.position.close()

        elif (crossover(self.lower_bound, self.daily_rsi) and
                self.lower_bound > self.weekly_rsi[-1]):
            self.buy()

4. 补充回测执行代码

原代码缺少回测运行逻辑,添加以下代码触发回测:

# 初始化回测
bt = Backtest(data, MyStrategy, cash=10000, commission=0.001)
# 运行回测
results = bt.run()
# 打印结果
print(results)
# 可视化回测
bt.plot()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:25:25