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