help with indicator added to two strategies
-
Hi,
When I am adding an indicator (TestIndicator1 below) and I have two strategies, then the indicator values in the second strategy seem to be wrong. However, if I have a single strategy or next instead of init used for indicator, the values are correct.
It seems though that this behaviour does not apply to all indicators. For example values for TestIndicator2 below are correct for both strategies.
import backtrader as bt import sys import pandas as pd class TestStrategy(bt.Strategy): params = dict(name="TestStrategy") def __init__(self): self._indicators = None def start(self): self._indicators = self.getindicators_lines() def next(self): print("{}: {}, {}, {}, {}".format(self.params.name, self.datas[0].datetime.date(0), self.datas[0].lines.close[0], self._indicators[0].lines[0][0], self._indicators[1].lines[0][0])) class TestIndicator1(bt.Indicator): lines = ('signal',) params=dict(threshold=30) def __init__(self): self.lines.signal = bt.If(self.datas[0].lines.close > self.params.threshold, 1, 0) # def next(self): # if self.datas[0].lines.close[0] > self.params.threshold: # self.lines.signal[0] = 1 # else: # self.lines.signal[0] = 0 class TestIndicator2(bt.Indicator): lines = ('signal',) params=dict(period=1) def __init__(self): self.addminperiod(self.params.period) self.lines.signal = bt.If(self.datas[0].lines.close > self.datas[0].lines.close(-self.params.period), 1, 0) def main(argv): cerebro = bt.Cerebro() df1 = pd.DataFrame({'Close': [1,2,3,4,100,5,7,6], 'Open': [0,1,2,3,99,4,6,5], 'High': [0,0,0,1,-1,0,0,0]}, index=pd.date_range(start='1/1/2018', periods=8)) cerebro.adddata(bt.feeds.PandasData(dataname=df1, nocase=True)) cerebro.broker.setcash(100000.0) cerebro.broker.set_coc(True) cerebro.addstrategy(TestStrategy, name="Strat1") cerebro.addstrategy(TestStrategy, name="Strat2") cerebro.addindicator(TestIndicator1, threshold=4) cerebro.addindicator(TestIndicator2, period=1) cerebro.run(runonce=True, preload=True) if __name__ == "__main__": main(sys.argv)
Output is
Strat1: 2018-01-02, 2.0, 0.0, 1.0 Strat2: 2018-01-02, 2.0, 1.0, 1.0 Strat1: 2018-01-03, 3.0, 0.0, 1.0 Strat2: 2018-01-03, 3.0, 1.0, 1.0 Strat1: 2018-01-04, 4.0, 0.0, 1.0 Strat2: 2018-01-04, 4.0, 1.0, 1.0 Strat1: 2018-01-05, 100.0, 1.0, 1.0 Strat2: 2018-01-05, 100.0, 1.0, 1.0 Strat1: 2018-01-06, 5.0, 1.0, 0.0 Strat2: 2018-01-06, 5.0, 1.0, 0.0 Strat1: 2018-01-07, 7.0, 1.0, 1.0 Strat2: 2018-01-07, 7.0, 1.0, 1.0 Strat1: 2018-01-08, 6.0, 1.0, 0.0 Strat2: 2018-01-08, 6.0, 1.0, 0.0
while with next I get the expected one:
Strat1: 2018-01-02, 2.0, 0.0, 1.0 Strat2: 2018-01-02, 2.0, 0.0, 1.0 Strat1: 2018-01-03, 3.0, 0.0, 1.0 Strat2: 2018-01-03, 3.0, 0.0, 1.0 Strat1: 2018-01-04, 4.0, 0.0, 1.0 Strat2: 2018-01-04, 4.0, 0.0, 1.0 Strat1: 2018-01-05, 100.0, 1.0, 1.0 Strat2: 2018-01-05, 100.0, 1.0, 1.0 Strat1: 2018-01-06, 5.0, 1.0, 0.0 Strat2: 2018-01-06, 5.0, 1.0, 0.0 Strat1: 2018-01-07, 7.0, 1.0, 1.0 Strat2: 2018-01-07, 7.0, 1.0, 1.0 Strat1: 2018-01-08, 6.0, 1.0, 0.0 Strat2: 2018-01-08, 6.0, 1.0, 0.0
Thanks for your help
-
@momentum said in help with indicator added to two strategies:
def __init__(self): self.lines.signal = bt.If(self.datas[0].lines.close > self.params.threshold, 1, 0)
I know you know your problem is there. And I know because you crafted that after going through some errors.
@momentum said in help with indicator added to two strategies:
def __init__(self): self.addminperiod(self.params.period) self.lines.signal = bt.If(self.datas[0].lines.close > self.datas[0].lines.close(-self.params.period), 1, 0)
addminperiod
is pointless there, because you already have a constraint forcing the period withclose(-period)
What actually takes us to the point ... if you know that
close(period_to_consider)
exists, why do you do:self.lines.signal = bt.If(self.datas[0].lines.close > self.params.threshold, 1, 0)
instead of
self.lines.signal = self.data.close(0) > self.p.threshold
-
Many thanks again for your prompt reply and help. However, I am confused since I actually got this without any errors apart from the ones mentioned.
Isn't self.datas[0].lines.close equivalent to self.data.close(0)? I also understand that bt.If is redundant but I fail to see why these two lines would not produce the same results.
self.lines.signal = bt.If(self.datas[0].lines.close > self.params.threshold, 1, 0) self.lines.signal = self.data.close(0) > self.p.threshold
I mean in a similar fashion I used
self.lines.signal = bt.If(self.datas[0].lines.close > self.datas[0].lines.close(-self.params.period), 1, 0)
instead of
self.lines.signal = self.data.close(0) > self.data.close(-self.p.period)
Thanks