It worked, thanks!
But isn't vectorized mode much faster for optimization, etc.?
It worked, thanks!
But isn't vectorized mode much faster for optimization, etc.?
Hi guys,
I've found 2 problems when using 2 data feeds - one with history longer than the other:
from datetime import datetime
import backtrader as bt
class SmaCross(bt.SignalStrategy):
def __init__(self):
# ko
crossover1 = bt.ind.CrossOver(self.data0, self.data1)
# ok
crossover2 = bt.ind.CrossOver(self.data1, self.data0)
# ko
self.data0 - self.data1
# ok
self.data1 - self.data0
cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross)
# data since 2004-11-18
data0 = bt.feeds.YahooFinanceCSVData(dataname='data/GLD.csv',
fromdate=datetime(2006, 1, 1),
todate=datetime(2007, 1, 1))
cerebro.adddata(data0)
# data since 2006-04-28
data1 = bt.feeds.YahooFinanceCSVData(dataname='data/SLV.csv',
fromdate=datetime(2006, 1, 1),
todate=datetime(2007, 1, 1))
cerebro.adddata(data1)
cerebro.run()
cerebro.plot()
The first error is in indicators/crossover.py
:
$ python pair_bug.py
Traceback (most recent call last):
File "pair_bug.py", line 31, in <module>
cerebro.run()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 1127, in run
runstrat = self.runstrategies(iterstrat)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 1293, in runstrategies
self._runonce(runstrats)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 1652, in _runonce
strat._once()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineiterator.py", line 297, in _once
indicator._once()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineiterator.py", line 297, in _once
indicator._once()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineiterator.py", line 297, in _once
indicator._once()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineiterator.py", line 318, in _once
self.once(self._minperiod, self.buflen())
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/indicators/crossover.py", line 58, in once
d = d0array[i] - d1array[i]
IndexError: array index out of range
The second is in linebuffer.py
:
$ python pair_bug.py
Traceback (most recent call last):
File "pair_bug.py", line 31, in <module>
cerebro.run()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 1127, in run
runstrat = self.runstrategies(iterstrat)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 1293, in runstrategies
self._runonce(runstrats)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 1652, in _runonce
strat._once()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineiterator.py", line 297, in _once
indicator._once()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 631, in _once
self.once(self._minperiod, self.buflen())
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 755, in once
self._once_op(start, end)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 772, in _once_op
dst[i] = op(srca[i], srcb[i])
IndexError: array index out of range
As you can see in my code sample, it works when you flip the data feeds - if you put the shorter history data first (data1
), it works fine, otherwise it throws error.
My env is macOS Catalina 10.15.3, Python 3.5.9 with packages:
$ pip freeze
backtrader==1.9.74.123
cycler==0.10.0
kiwisolver==1.1.0
matplotlib==3.0.3
numpy==1.18.3
pyparsing==2.4.7
python-dateutil==2.8.1
six==1.14.0
Any help would be appreciated :)
Yeah that worked! Thanks a lot :)
Meanwhile I've found another workaround, using dedicated indicator and nesting other indicator inside it:
from datetime import datetime
import backtrader as bt
class NestedMomentum(bt.Indicator):
lines = ('mom', 'mommom', 'mommommom')
def __init__(self):
self.l.mom = bt.ind.Momentum()
self.l.mommom = bt.ind.Momentum(self.l.mom)
self.l.mommommom = bt.ind.Momentum(self.l.mommom)
class SmaCross(bt.SignalStrategy):
def __init__(self):
sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
crossover = bt.ind.CrossOver(sma1, sma2)
self.signal_add(bt.SIGNAL_LONG, crossover)
# plotmaster workaround
mom = bt.ind.Momentum()
mommom = bt.ind.Momentum(mom, plotmaster=mom)
mommommom = bt.ind.Momentum(mommom, plotmaster=mom)
# custom indicator workaround
nested = NestedMomentum()
cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross)
data0 = bt.feeds.YahooFinanceCSVData(dataname='data/GLD.csv',
fromdate=datetime(2011, 1, 1),
todate=datetime(2012, 12, 31))
cerebro.adddata(data0)
cerebro.run()
cerebro.plot()
Anyway it looks like a bug, but I'm happy there are workarounds :)
Hi guys,
First of all, thanks for such a great tool for backtesting investing ideas!
I try to plot a nested indicator. By nesting I mean using one's indicator data as entry data for another's indicator data.
Here is what I do, based on the simple example from readme:
from datetime import datetime
import backtrader as bt
class SmaCross(bt.SignalStrategy):
def __init__(self):
sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
crossover = bt.ind.CrossOver(sma1, sma2)
self.signal_add(bt.SIGNAL_LONG, crossover)
mom = bt.ind.Momentum()
mommom = bt.ind.Momentum(mom)
mommommom = bt.ind.Momentum(mommom, plotforce=True)
cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross)
data0 = bt.feeds.YahooFinanceCSVData(dataname='data/GLD.csv',
fromdate=datetime(2011, 1, 1),
todate=datetime(2012, 12, 31))
cerebro.adddata(data0)
cerebro.run()
cerebro.plot()
It crashes with:
$ python smacross.py
Traceback (most recent call last):
File "smacross.py", line 21, in <module>
cerebro.plot()
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 991, in plot
start=start, end=end, use=use)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/plot/plot.py", line 134, in plot
self.sortdataindicators(strategy)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/plot/plot.py", line 856, in sortdataindicators
if key not in strategy.datas:
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 281, in __eq__
return self._operation(other, operator.__eq__)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 86, in _operation
other, operation, r=r, intify=intify)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 201, in _operation_stage1
return self._makeoperation(other, operation, r, self)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 331, in _makeoperation
return self.lines[0]._makeoperation(other, operation, r, _ownerskip)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 378, in _makeoperation
_ownerskip=_ownerskip)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 522, in __call__
return super(MetaLineActions, cls).__call__(*args, **kwargs)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/metabase.py", line 89, in __call__
_obj, args, kwargs = cls.dopostinit(_obj, *args, **kwargs)
File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 566, in dopostinit
_obj._owner.addindicator(_obj)
AttributeError: 'NoneType' object has no attribute 'addindicator'
Without plotforce=True
it won't crash, but the plot is still not visible.
My env is macOS Catalina 10.15.3, Python 3.5.9 with packages:
$ pip freeze
backtrader==1.9.74.123
cycler==0.10.0
kiwisolver==1.1.0
matplotlib==3.0.3
numpy==1.18.3
pyparsing==2.4.7
python-dateutil==2.8.1
six==1.14.0
Any help would be appreciated :)
Thanks in advance and keep up the fantastic work!
Adam