Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Optimizer gives me " only size-1 arrays can be converted to Python scalars" error

    General Code/Help
    7
    9
    689
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • David Wood
      David Wood last edited by

      I've been trying to optimize a new strategy that I have based off of previous strategies. The previous strategies work, but the new one gives me an error saying "only size-1 arrays can be converted to Python scalars" from inside cerebro.run(). Does anybody have an idea of what would be causing this?

      The optimizer works when I put a single value into the parameter instead of using np.arange. for bbfactor So it's most likely an issue with that, but I can't figure out what's going on.

      import datetime
      import backtrader as bt
      from strategies import *
      import numpy as np
      
      cerebro = bt.Cerebro(optreturn=False)
      
      data = bt.feeds.GenericCSVData(
          dataname=tickerSymbol + '_'+ Interval + '_data.csv',
      
          fromdate = datetime.datetime(2019, 10, 1),
          todate = datetime.date.today(),
      
          nullvalue=0.0,
      
          dtformat=('%Y-%m-%d'),
      
          datetime=0,
          open=1,
          high=2,
          low=3,
          close=4,
          volume=5,
          openinterest=-1
      )
      
      cerebro.adddata(data)
      
      #Add analyzer to Cerebro
      cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe_ratio')
      cerebro.addanalyzer(bt.analyzers.SQN, _name='SQN')
      
      #Add strategy to Cerebro
      cerebro.optstrategy(BB_EMA, emaperiod=np.arange(20,40,5), bbperiod=np.arange(20,40,5),
                          bbfactor=np.arange(1,4,1))
      
      #Default position size
      cerebro.broker.setcash(10000.0)
      cerebro.addsizer(bt.sizers.PercentSizerInt,percents = 99)
      
      if __name__ == '__main__':
          optimized_runs = cerebro.run()
      
          final_results_list = []
              print('EMA Period|BB Period|BB factor|   PnL|               SQN') # for SQN analysis
          
          for run in optimized_runs:
              for strategy in run:
                  PnL = round(strategy.broker.get_value() - 10000,2)
                  sqn = strategy.analyzers.SQN.get_analysis()
      
                      sqnF = '{:<10}|{:<9}|{:<9}|{:<6}|{:<18}'
                      final_results_list.append([strategy.params.emaperiod,
                                                 strategy.params.bbperiod,
                                                 strategy.params.bbfactor,
                                                 PnL, sqn['sqn']])
      
          sort_by_sharpe = sorted(final_results_list, key=lambda x: x[3], reverse=True)
          filter(None, sort_by_sharpe)
          #print(sort_by_sharpe)
          for line in sort_by_sharpe[:5]:
              if line is not None:
                  print(sqnF.format(*line))
            
          print('\n1.6 - 1.9 Below average \n2.0 - 2.4 Average \n2.5 - 2.9 Good \n3.0 - 5.0 Excellent \n5.1 - 6.9 Superb \n7.0 - Holy Grail')
      

      Error log:

      ---------------------------------------------------------------------------
      RemoteTraceback                           Traceback (most recent call last)
      RemoteTraceback: 
      """
      Traceback (most recent call last):
        File "C:\Users\David\Anaconda3\lib\multiprocessing\pool.py", line 119, in worker
          result = (True, func(*args, **kwds))
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1007, in __call__
          return self.runstrategies(iterstrat, predata=predata)
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1293, in runstrategies
          self._runonce(runstrats)
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1652, in _runonce
          strat._once()
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\lineiterator.py", line 297, in _once
          indicator._once()
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\lineiterator.py", line 297, in _once
          indicator._once()
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\linebuffer.py", line 630, in _once
          self.oncestart(self._minperiod - 1, self._minperiod)
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\lineroot.py", line 165, in oncestart
          self.once(start, end)
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\linebuffer.py", line 758, in once
          self._once_val_op(start, end)
        File "C:\Users\David\Anaconda3\lib\site-packages\backtrader\linebuffer.py", line 793, in _once_val_op
          dst[i] = op(srca[i], srcb)
      TypeError: only size-1 arrays can be converted to Python scalars
      """
      
      The above exception was the direct cause of the following exception:
      
      TypeError                                 Traceback (most recent call last)
      <ipython-input-4-2f6d49262766> in <module>
           51 
           52 if __name__ == '__main__':
      ---> 53     optimized_runs = cerebro.run()
           54 
           55     final_results_list = []
      
      ~\Anaconda3\lib\site-packages\backtrader\cerebro.py in run(self, **kwargs)
         1141 
         1142             pool = multiprocessing.Pool(self.p.maxcpus or None)
      -> 1143             for r in pool.imap(self, iterstrats):
         1144                 self.runstrats.append(r)
         1145                 for cb in self.optcbs:
      
      ~\Anaconda3\lib\multiprocessing\pool.py in next(self, timeout)
          733         if success:
          734             return value
      --> 735         raise value
          736 
          737     __next__ = next                    # XXX
      
      TypeError: only size-1 arrays can be converted to Python scalars
      
      1 Reply Last reply Reply Quote 0
      • vladisld
        vladisld last edited by

        could you please share the code the BB_EMA strategy - at least its __init__ method - so that we could see how the indicators we defined and/or line operations were used.

        1 Reply Last reply Reply Quote 1
        • David Wood
          David Wood last edited by

              def __init__(self):     
                  self.dataclose = self.datas[0].close  
                 
                  # Order variable will contain ongoing order details/status
                  self.order = None
             
                  self.bb = bt.indicators.BBands(self.datas[0],
                                                 period = self.params.bbperiod,
                                                 devfactor = self.params.bbfactor,
                                                 )
          
                  self.ema = bt.indicators.EMA(self.datas[0], period=self.params.emaperiod)
          

          This init has been used in other strategies and has no problems. I'm not sure what's going on.

          1 Reply Last reply Reply Quote 1
          • Pooya
            Pooya last edited by

            I have this problem too. any solution?

            1 Reply Last reply Reply Quote 1
            • vladisld
              vladisld last edited by

              Please try to call the optstrategy with explicit array for bbfactor:

              cerebro.optstrategy(BB_EMA, emaperiod=np.arange(20, 40, 5), bbperiod=np.arange(20, 40, 5), bbfactor=[1.0, 2.0, 3.0, 4.0])
              

              It seems np.arange with floating numbers cause some problems. If this is indeed the problem, will update with more investigation info.

              hghhgghdf dfdf 1 Reply Last reply Reply Quote 2
              • hghhgghdf dfdf
                hghhgghdf dfdf @vladisld last edited by

                @vladisld Had the same issue. problem is that arange returns numpy datatypes which causes this operation to return a numpy array:

                stddev = self.p.devfactor * StdDev(self.data, ma, period=self.p.period,
                                                           movav=self.p.movav)
                

                Converting self.p.devfactor to a standard float fixes the problem

                earlcharles1 1 Reply Last reply Reply Quote 2
                • earlcharles1
                  earlcharles1 @hghhgghdf dfdf last edited by

                  @hghhgghdf-dfdf Do you mind helping me a bit on this? I'm trying to convert devfactor to float with no avail.

                  1 Reply Last reply Reply Quote 1
                  • run-out
                    run-out last edited by

                    Have you tried just using a list instead of numpy.arange?

                    RunBacktest.com

                    1 Reply Last reply Reply Quote 1
                    • MiXaLFtruck
                      MiXaLFtruck last edited by

                      Yeah, using a list instead of numpy.arange helps.
                      Looks like the reason causing this error is inside BBands indicator class. Because, for example, feeding ATR indicator with numpy.arange array works perfect!

                      1 Reply Last reply Reply Quote 0
                      • 1 / 1
                      • First post
                        Last post
                      Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors