我正在尝试使用 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() 运行脚本时,evrything 运行良好。只有在更改为 optstrategy 时才会出现此错误。
我还尝试在 Google colab 上运行相同的代码(使用 optstrategy() 方法)并且那里一切正常,所以这让我非常困惑......
我在 macOS 上使用 PyCharm CE 运行 python 3.10。如果需要任何其他信息来解决此问题,请告诉我。Nooby to python 所以如果缺少任何信息,我会提前道歉。
提前感谢您的帮助!