Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. zarbov
    3. Posts
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    Z
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 1
    • Best 0
    • Groups 0

    Posts made by zarbov

    • optstrategy AttributeError: module 'collections' has no attribute 'Iterable'

      Hi
      i'm trying to optimize my strategy but keeps getting this error and i can't find anything on the web showing why I'm getting it.
      My code is simple and loosely based on the getting started examples:

      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))
      
      

      Running the script, i get this error:

      Traceback (most recent call last):
        File "/Users/shohamshaulian/PycharmProjects/test3/main.py", line 79, in <module>
          run_backtest(EMACross, 'QQQ', '2018-01-01', '2022-01-01', TimeFrame(1, TimeFrameUnit.Day))
        File "/Users/shohamshaulian/PycharmProjects/test3/main.py", line 54, in run_backtest
          cerebro.optstrategy(strategy, ema_short_period=4, ema_long_period=6)
        File "/Users/shohamshaulian/PycharmProjects/test3/venv/lib/python3.10/site-packages/backtrader/cerebro.py", line 893, in optstrategy
          vals = self.iterize(kwargs.values())
        File "/Users/shohamshaulian/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
      

      When running the script without optstrategy but rather with addstrategy, evrything is working great. Only when changing to optstrategy is when i'm getting this error.

      I also tried to run the same code on google colab (with optstrategy) and everything worked great there, so this got me really puzzled...

      I'm running python 3.10 with PyCharm CE on macOS. Please let me know if any additional information needed in order to solve this issue.

      Thanks in advance for any help!

      posted in General Code/Help
      Z
      zarbov
    • 1 / 1