Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Change backtrader.Strategy params depending on asset?

    General Code/Help
    1
    2
    881
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • K
      kav last edited by kav

      I just started playing with bt and have been struggling with this all afternoon.

      So my starting point is this post here.

      It works out of the box. So far so good.

      Now I try to change things a bit. My objective is to allow the indicator values
      to be different for the different assets. I figured one simple way of doing that would be to flip sma1 and sma2 in the code above for the 'cross' indicator some of the assets.

      import backtrader 
      
      
      class maCross(backtrader.Strategy):
          '''
          For an official backtrader blog on this topic please take a look at:
      
          https://www.backtrader.com/blog/posts/2017-04-09-multi-example/multi-example.html
      
          oneplot = Force all datas to plot on the same master.
          '''
          params = (
          ('sma1', 80),
          ('sma2', 200),
          ('oneplot', True),
          ('list_plus', []),
          ('list_minus', [])
          )
      
          def __init__(self):
              '''
              Create an dictionary of indicators so that we can dynamically add the
              indicators to the strategy using a loop. This mean the strategy will
              work with any number of data feeds. 
              '''
              self.inds = dict()
              for i, d in enumerate(self.datas):
                  self.inds[d] = dict()
                  self.inds[d]['sma1'] = backtrader.indicators.SMA(d.close, 
                                                                   period=self.params.sma1)
                  self.inds[d]['sma2'] = backtrader.indicators.SMA(d.close, 
                                                                   period=self.params.sma2)
                  if d._name in self.params.list_plus:
                      print('list_plus')
                      self.inds[d]['cross'] = backtrader.indicators.CrossOver(self.inds[d]['sma1'],
                                                                              self.inds[d]['sma2'])
                  if d._name in self.params.list_minus:
                      print('list_minus')
                      self.inds[d]['cross'] = backtrader.indicators.CrossOver(self.inds[d]['sma2'],
                                                                              self.inds[d]['sma1']) 
                
                  if i > 0: #Check we are not on the first loop of data feed:
                      if self.p.oneplot == True:
                          d.plotinfo.plotmaster = self.datas[0]
      
          def next(self):
              for i, d in enumerate(self.datas):
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  if not pos:  # no market / no orders
                      if self.inds[d]['cross'][0]:
                          self.buy(data=d, size=1000)
                      elif self.inds[d]['cross'][0]:
                          self.sell(data=d, size=1000)
                  else:
                      if self.inds[d]['cross'][0]:
                          self.close(data=d)
                          self.buy(data=d, size=1000)
                      elif self.inds[d]['cross'][0]:
                          self.close(data=d)
                          self.sell(data=d, size=1000)
      
          def notify_trade(self, trade):
              dt = self.data.datetime.date()
              if trade.isclosed:
                  print('{} {} Closed: PnL Gross {}, Net {}'.format(
                                                      dt,
                                                      trade.data._name,
                                                      round(trade.pnl,2),
                                                      round(trade.pnlcomm,2)))
      

      I set the parameters:

      cerebro.addstrategy(maCross, list_plus = ['CADCHF', 'EURUSD'], list_minus = ['GBPAUD'], oneplot=False)
      

      Now when I run the strategy, I get the print outs I would expect on the screen:

      list_plus
      list_plus
      list_minus
      

      So far so good (cerebro.run() runs without a warning/error).

      But is seems no trades are executed:

      The PnL is the initial one and the triangles on the plot are no longer there.

      I presume a rookie problem (I'm a rookie). Is it one that can be easily fixed?

      K 1 Reply Last reply Reply Quote 0
      • K
        kav @kav last edited by

        @kav
        Everything is fixed. I had introduced a mistake in the next() (visible above). Please ignore my post!

        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
        $(document).ready(function () { app.coldLoad(); }); }