无法实例化含抽象方法的抽象类:Backtest策略代码报错求助
问题排查:无法实例化BuyAndHold策略类
问题重现
编写了继承自Strategy的BuyAndHold量化回测策略类:
import pandas as pd class BuyAndHold(Strategy): def __init__(self, data, buy_percentage, keep_buying_percentage, sell_percentage): Strategy.__init__(self) self.data = data self.buy_percentage = buy_percentage self.keep_buying_percentage = keep_buying_percentage self.sell_percentage = sell_percentage self.portfolio_history = [] def buy_more_quantity(self, current_price, initial_buy_price, last_quantity): return int(last_quantity * 2) def next(self, portfolio, current_price, initial_buy_price, last_quantity, cash): if portfolio is None: # Initial buy buy_price = initial_buy_price * (1 - self.buy_percentage) buy_quantity = int(cash / buy_price) portfolio = buy_price * buy_quantity cash -= portfolio self.portfolio_history.append(portfolio + cash) return portfolio, cash, buy_quantity sell_price = initial_buy_price * (1 + self.sell_percentage) if current_price >= sell_price: portfolio = current_price * last_quantity cash += portfolio self.portfolio_history.append(portfolio + cash) return None, cash, 0 keep_buying_price = initial_buy_price * (1 - self.keep_buying_percentage) if current_price <= keep_buying_price: buy_price = current_price buy_quantity = self.buy_more_quantity(current_price, initial_buy_price, last_quantity) portfolio = buy_price * buy_quantity cash -= portfolio self.portfolio_history.append(portfolio + cash) return portfolio, cash, buy_quantity self.portfolio_history.append(portfolio + cash) return portfolio, cash, last_quantity def stop(self): portfolio_value = 0 portfolio_history = [] for i, p in enumerate(self.portfolio): if 'sell_price' in p: portfolio_value += p['sell_price'] * p['quantity'] else: portfolio_value += self.data.close[-(len(self.portfolio) - i)] * p['quantity'] portfolio_history.append(portfolio_value) self.portfolio_history = pd.Series(portfolio_history, index=self.data.index)
执行回测初始化语句时:
bt = Backtest(data['Close']['XLB'], BuyAndHold(data['Close']['XLB'], buy_percentage=0.1, keep_buying_percentage=0.05, sell_percentage=0.1))
抛出错误:"Can't instantiate abstract class with abstract methods"
错误原因
Python抽象基类(ABC)要求子类必须完全实现所有标记为抽象的方法,否则无法实例化。BuyAndHold类继承自Strategy抽象类,但存在以下问题:
- 未实现
Strategy中定义的部分抽象方法 - 已实现的方法(如
next)参数签名与抽象类定义不一致,导致Python判定未正确实现该抽象方法
解决方案
步骤1:确认Strategy的抽象方法列表
用inspect模块查看Strategy类中所有必须实现的抽象方法:
import inspect # 列出Strategy类的所有抽象方法 abstract_methods = [name for name, _ in inspect.getmembers(Strategy, predicate=inspect.isabstractmethod)] print("必须实现的抽象方法:", abstract_methods)
步骤2:补全或修正方法实现
根据输出的抽象方法列表,确保BuyAndHold类实现了每一个方法,且参数签名与抽象类定义完全一致:
- 若
Strategy的next方法定义为def next(self, data):,当前next的参数列表不符合要求,需调整参数和逻辑匹配框架规范 - 检查
stop方法的参数、返回值是否符合抽象类定义
步骤3:检查回测初始化方式(可选)
部分量化回测框架要求传入策略类而非已实例化的对象,正确初始化方式可能为:
bt = Backtest(data['Close']['XLB'], BuyAndHold, params={"data": data['Close']['XLB'], "buy_percentage":0.1, "keep_buying_percentage":0.05, "sell_percentage":0.1})
具体需参照Backtest类的文档要求。
额外问题修复
stop方法中使用了self.portfolio但未在__init__中初始化,建议添加:
self.portfolio = []
内容的提问来源于stack exchange,提问作者Rajesh Nathani
相关产品推荐
相关产品推荐

