Backtrader issue - optstrategy AttributeError: module 'collections' has no attribute 'Iterable'
Backtrader issue - optstrategy AttributeError: module 'collections' has no attribute 'Iterable'
我正在尝试使用 python 优化我在 Backtrader 上的策略,但一直出现此错误,而且我在网络上找不到任何说明我为什么会收到它的信息。
我的代码简单且松散地基于快速入门示例:
from alpaca_trade_api.rest import REST, TimeFrame, TimeFrameUnit
import backtrader as bt
from config import API_KEY, SECRET_KEY
class EMACross(bt.Strategy):
params = dict(
ema_short_period=5,
ema_long_period=10
)
def __init__(self):
self.order = None
self.short_ma = bt.indicators.ExponentialMovingAverage(period=self.p.ema_short_period)
self.long_ma = bt.indicators.ExponentialMovingAverage(period=self.p.ema_long_period)
self.crossover = bt.ind.CrossOver(self.short_ma, self.long_ma) # crossover signal
self.crossdown = bt.ind.CrossDown(self.short_ma, self.long_ma)
self.crossdown.plotinfo.subplot = False
self.crossover.plotinfo.subplot = False
def next(self):
self.log('Close, %.2f' % self.data.close[0])
if self.position.size > 0:
if self.crossdown > 0:
self.log('SELL CREATE, %.2f' % self.data.close[0])
self.close()
else:
if self.crossover > 0:
self.log('BUY CREATE, %.2f' % self.data.close[0])
self.buy()
def log(self, txt, dt=None):
dt = dt or self.data.datetime.datetime()
print('%s, %s' % (dt.isoformat(), txt))
def stop(self):
self.log('(short EMA Period %2d) (long EMA Period %2d) Ending Value %.2f' %
(self.p.ema_short_period, self.p.ema_long_period, self.broker.getvalue()))
rest_api = REST(API_KEY, SECRET_KEY, 'https://paper-api.alpaca.markets')
def run_backtest(strategy, symbols, start, end, timeframe, cash=100000):
# initialize backtrader broker
cerebro = bt.Cerebro()
cerebro.broker.setcash(cash)
cerebro.addsizer(bt.sizers.PercentSizer, percents=90)
cerebro.optstrategy(strategy, ema_short_period=4, ema_long_period=6)
# historical data request
if type(symbols) == str:
symbol = symbols
alpaca_data = rest_api.get_bars(symbol, timeframe, start, end, adjustment='all').df
data = bt.feeds.PandasData(dataname=alpaca_data, name=symbol)
cerebro.adddata(data)
elif type(symbols) == list or type(symbols) == set:
for symbol in symbols:
alpaca_data = rest_api.get_bars(symbol, timeframe, start, end, adjustment='all').df
data = bt.feeds.PandasData(dataname=alpaca_data, name=symbol)
cerebro.adddata(data)
# run
initial_portfolio_value = cerebro.broker.getvalue()
print(f'Starting Portfolio Value: {initial_portfolio_value}')
results = cerebro.run()
final_portfolio_value = cerebro.broker.getvalue()
print(
f'Final Portfolio Value: {final_portfolio_value} ---> Return: {(final_portfolio_value / initial_portfolio_value - 1) * 100}%')
run_backtest(EMACross, 'QQQ', '2018-01-01', '2022-01-01', TimeFrame(1, TimeFrameUnit.Day))
运行 脚本,我得到这个错误:
Traceback (most recent call last):
File "/Users/usrname/PycharmProjects/test3/main.py", line 79, in <module>
run_backtest(EMACross, 'QQQ', '2018-01-01', '2022-01-01', TimeFrame(1, TimeFrameUnit.Day))
File "/Users/usrname/PycharmProjects/test3/main.py", line 54, in run_backtest
cerebro.optstrategy(strategy, ema_short_period=4, ema_long_period=6)
File "/Users/usrname/PycharmProjects/test3/venv/lib/python3.10/site-packages/backtrader/cerebro.py", line 893, in optstrategy
vals = self.iterize(kwargs.values())
File "/Users/usrname/PycharmProjects/test3/venv/lib/python3.10/site-packages/backtrader/cerebro.py", line 333, in iterize
elif not isinstance(elem, collections.Iterable):
AttributeError: module 'collections' has no attribute 'Iterable'
Process finished with exit code 1
当 运行 在没有 optstrategy() 而是使用 addstrategy() 的情况下使用脚本时,一切都运行良好。只有在更改为 optstrategy 时才会出现此错误。
我也尝试 运行 在 Google colab 上使用相同的代码(使用 optstrategy() 方法),一切都很好,所以这让我很困惑...
我正在 运行宁 python 3.10 与 PyCharm CE on macOS。
尝试从 python 3.10 降级到 python 3.8 版本
我正在尝试使用 python 优化我在 Backtrader 上的策略,但一直出现此错误,而且我在网络上找不到任何说明我为什么会收到它的信息。 我的代码简单且松散地基于快速入门示例:
from alpaca_trade_api.rest import REST, TimeFrame, TimeFrameUnit
import backtrader as bt
from config import API_KEY, SECRET_KEY
class EMACross(bt.Strategy):
params = dict(
ema_short_period=5,
ema_long_period=10
)
def __init__(self):
self.order = None
self.short_ma = bt.indicators.ExponentialMovingAverage(period=self.p.ema_short_period)
self.long_ma = bt.indicators.ExponentialMovingAverage(period=self.p.ema_long_period)
self.crossover = bt.ind.CrossOver(self.short_ma, self.long_ma) # crossover signal
self.crossdown = bt.ind.CrossDown(self.short_ma, self.long_ma)
self.crossdown.plotinfo.subplot = False
self.crossover.plotinfo.subplot = False
def next(self):
self.log('Close, %.2f' % self.data.close[0])
if self.position.size > 0:
if self.crossdown > 0:
self.log('SELL CREATE, %.2f' % self.data.close[0])
self.close()
else:
if self.crossover > 0:
self.log('BUY CREATE, %.2f' % self.data.close[0])
self.buy()
def log(self, txt, dt=None):
dt = dt or self.data.datetime.datetime()
print('%s, %s' % (dt.isoformat(), txt))
def stop(self):
self.log('(short EMA Period %2d) (long EMA Period %2d) Ending Value %.2f' %
(self.p.ema_short_period, self.p.ema_long_period, self.broker.getvalue()))
rest_api = REST(API_KEY, SECRET_KEY, 'https://paper-api.alpaca.markets')
def run_backtest(strategy, symbols, start, end, timeframe, cash=100000):
# initialize backtrader broker
cerebro = bt.Cerebro()
cerebro.broker.setcash(cash)
cerebro.addsizer(bt.sizers.PercentSizer, percents=90)
cerebro.optstrategy(strategy, ema_short_period=4, ema_long_period=6)
# historical data request
if type(symbols) == str:
symbol = symbols
alpaca_data = rest_api.get_bars(symbol, timeframe, start, end, adjustment='all').df
data = bt.feeds.PandasData(dataname=alpaca_data, name=symbol)
cerebro.adddata(data)
elif type(symbols) == list or type(symbols) == set:
for symbol in symbols:
alpaca_data = rest_api.get_bars(symbol, timeframe, start, end, adjustment='all').df
data = bt.feeds.PandasData(dataname=alpaca_data, name=symbol)
cerebro.adddata(data)
# run
initial_portfolio_value = cerebro.broker.getvalue()
print(f'Starting Portfolio Value: {initial_portfolio_value}')
results = cerebro.run()
final_portfolio_value = cerebro.broker.getvalue()
print(
f'Final Portfolio Value: {final_portfolio_value} ---> Return: {(final_portfolio_value / initial_portfolio_value - 1) * 100}%')
run_backtest(EMACross, 'QQQ', '2018-01-01', '2022-01-01', TimeFrame(1, TimeFrameUnit.Day))
运行 脚本,我得到这个错误:
Traceback (most recent call last):
File "/Users/usrname/PycharmProjects/test3/main.py", line 79, in <module>
run_backtest(EMACross, 'QQQ', '2018-01-01', '2022-01-01', TimeFrame(1, TimeFrameUnit.Day))
File "/Users/usrname/PycharmProjects/test3/main.py", line 54, in run_backtest
cerebro.optstrategy(strategy, ema_short_period=4, ema_long_period=6)
File "/Users/usrname/PycharmProjects/test3/venv/lib/python3.10/site-packages/backtrader/cerebro.py", line 893, in optstrategy
vals = self.iterize(kwargs.values())
File "/Users/usrname/PycharmProjects/test3/venv/lib/python3.10/site-packages/backtrader/cerebro.py", line 333, in iterize
elif not isinstance(elem, collections.Iterable):
AttributeError: module 'collections' has no attribute 'Iterable'
Process finished with exit code 1
当 运行 在没有 optstrategy() 而是使用 addstrategy() 的情况下使用脚本时,一切都运行良好。只有在更改为 optstrategy 时才会出现此错误。
我也尝试 运行 在 Google colab 上使用相同的代码(使用 optstrategy() 方法),一切都很好,所以这让我很困惑...
我正在 运行宁 python 3.10 与 PyCharm CE on macOS。
尝试从 python 3.10 降级到 python 3.8 版本