Dynamic values for strategy
-
Hi,
I'm new to Backtrader and am really enjoying it! I searched the documentation, articles, and forum for anything about dynamically changing the strategy parameters after initialization. I could only find one example on dynamically changing the an indicator which I could not figure out...
I am probably misunderstanding the Dynamic Indicators article. If this is the case, could someone please explain it to me with the example below.I am trying to add another indicator (EMA3cross) to the strategy - I want this indicator to be dynamically changed between the EMA1cross and EMA2cross proportionally according to the SMA indicator.
class Test(bt.Strategy): params = (('ema1fast', 20), ('ema1slow', 40), ('ema2fast', 50), ('ema2slow', 100), ('sma', 50)) def __init__(self): # EMAcross1 self.e1f = btind.EMA(self.data, period=self.p.ema1fast) self.e1s = btind.EMA(self.data, period=self.p.ema1slow) # EMAcross2 self.e2f = btind.EMA(self.data, period=self.p.ema2fast) self.e2s = btind.EMA(self.data, period=self.p.ema2slow) # SMA self.sma = btind.SMA(self.data, period=self.p.sma) def next(self): # EMA3cross self.ema3fast = (self.e1f._minperiod * self.sma) self.ema3slow = (self.e1s._minperiod * self.sma) EMA3fast = btind.EMA(self.data, period=self.ema3fast) EMA3slow = btind.EMA(self.data, period=self.ema3slow) self.buysig = btind.CrossOver(EMA3fast, EMA3slow) # Buy/Sell if self.buysig < 0: self.sell() elif self.buysig > 0: self.buy()
Error:
Traceback (most recent call last): File "dynamic1.py", line 97, in <module> thestrats = cerebro.run() File "/home/user1/.local/lib/python3.8/site-packages/backtrader/cerebro.py", line 1127, in run runstrat = self.runstrategies(iterstrat) File "/home/user1/.local/lib/python3.8/site-packages/backtrader/cerebro.py", line 1293, in runstrategies self._runonce(runstrats) File "/home/user1/.local/lib/python3.8/site-packages/backtrader/cerebro.py", line 1695, in _runonce strat._oncepost(dt0) File "/home/user1/.local/lib/python3.8/site-packages/backtrader/strategy.py", line 311, in _oncepost self.nextstart() # only called for the 1st value File "/home/user1/.local/lib/python3.8/site-packages/backtrader/lineiterator.py", line 347, in nextstart self.next() File "dynamic1.py", line 47, in next if self.buysig < 0: TypeError: __bool__ should return bool, returned LineOwnOperation
-
@agog Try [0] to get the line at the current date.
self.buysig[0]
-
@run-out, thanks for the help, but that did not work...
Has anyone implemented something like this?
I have some new code trying to make a MACD (MACD2) parameters dynamic:
class Test(bt.Strategy): params = (('macdfast', 50), ('macdslow', 200),('macdsignal', 500), \ ('bbtimeperiod', 50), ('nbdevup', 1),('nbdevdn', 1)) def __init__(self): # MACD1 self.talib_macd = bt.talib.MACD(self.data, fastperiod=int(self.p.macdfast), slowperiod=int(self.p.macdslow), signalperiod=int(self.p.macdsignal)) # BBANDS self.bb = bt.talib.BBANDS(self.data, timeperiod=self.p.bbtimeperiod, nbdevup=float(self.p.nbdevup), nbdevdn=float(self.p.nbdevdn), plot=True) def next(self): # MACD2 (Dynamic) macd2fast = self.p.macdfast * self.bb.upperband-self.bb.lowerband macd2slow = self.p.macdslow + self.p.macdslow * self.bb.upperband-self.bb.lowerband macd2signal = self.p.macdsignal + self.p.macdsignal * self.bb.upperband-self.bb.lowerband talib_macd2 = bt.talib.MACD(self.data, fastperiod=int(macd2fast), slowperiod=int(macd2slow), signalperiod=int(macd2signal), plot=False) # Getting MACD2 plotlines macd_line = talib_macd2.macd[0] signal_line = talib_macd2.macdsignal[0] # Buy/Sell if macd_line > signal_line: self.sell() elif macd_line < signal_line: self.buy()
The error I am getting is this:
File "dynamic3.py", line 41, in next macd_line = talib_macd2.macd[0] File "/home/user1/.local/lib/python3.8/site-packages/backtrader/linebuffer.py", line 163, in __getitem__ return self.array[self.idx + ago] IndexError: array index out of range
-
@agog
i am also facing same kind of issue "array index out of range" you were able to fix it -
@agog said in Dynamic values for strategy:
MACD2 (Dynamic)
macd2fast = self.p.macdfast * self.bb.upperband-self.bb.lowerband macd2slow = self.p.macdslow + self.p.macdslow * self.bb.upperband-self.bb.lowerband macd2signal = self.p.macdsignal + self.p.macdsignal * self.bb.upperband-self.bb.lowerband talib_macd2 = bt.talib.MACD(self.data, fastperiod=int(macd2fast), slowperiod=int(macd2slow), signalperiod=int(macd2signal), plot=False)
I think all of this needs to be in your init sections.