0

我正在尝试使用 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 所以如果缺少任何信息,我会提前道歉。

提前感谢您的帮助!

4

1 回答 1

0

尝试将 python 3.10 更改为 python 3.8 版本

于 2022-02-19T20:05:04.270 回答