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



  • 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
    


  • 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.



  •     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.



  • I have this problem too. any solution?



  • 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.


Log in to reply
 

});