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/

    Trailing

    General Code/Help
    1
    2
    231
    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.
    • Chirila Catalin
      Chirila Catalin last edited by

      Hi,

      It's the first time when I write here and I'm new to Backtrader, first of all congratulations on the idea, brilliant! I think with the right strategy this is like a money printing machine.

      I've tested over the last days Backtrader and it's great, my only problem... can't figure out how to setup the trailing stop for profits and losses...

      I'm trying to add a trailing stop to the oandav20test.py project, but it seems that is not working. Every time an order goes in the API it goes without S/L T/P or T/S

      So I'm not sure what I'm missing, if you can help me please...

      class TestStrategy(bt.Strategy):
          params = dict(
              smaperiod=5,
              trade=False,
              stake=10,
              exectype=bt.Order.Market,
              stopafter=0,
              valid=None,
              cancel=0,
              donotcounter=False,
              sell=False,
              usebracket=False,
          )
      
          def __init__(self):
              # To control operation entries
              self.orderid = list()
              self.order = None
      
              self.counttostop = 0
              self.datastatus = 0
      
              # Create SMA on 2nd data
              self.sma = bt.indicators.MovAv.SMA(self.data, period=self.p.smaperiod)
      
              print('--------------------------------------------------')
              print('Strategy Created')
              print('--------------------------------------------------')
      
          def notify_data(self, data, status, *args, **kwargs):
              print('*' * 5, 'DATA NOTIF:', data._getstatusname(status), *args)
              if status == data.LIVE:
                  self.counttostop = self.p.stopafter
                  self.datastatus = 1
      
          def notify_store(self, msg, *args, **kwargs):
              print('*' * 5, 'STORE NOTIF:', msg)
      
          def notify_order(self, order):
              if order.status in [order.Completed, order.Cancelled, order.Rejected]:
                  self.order = None
      
              print('-' * 50, 'ORDER BEGIN', datetime.datetime.now())
              print(order)
              print('-' * 50, 'ORDER END')
      
          def notify_trade(self, trade):
              print('-' * 50, 'TRADE BEGIN', datetime.datetime.now())
              print(trade)
              print('-' * 50, 'TRADE END')
      
          def prenext(self):
              self.next(frompre=True)
      
          def next(self, frompre=False):
              txt = list()
              txt.append('Data0')
              txt.append('%04d' % len(self.data0))
              dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
              txt.append('{:f}'.format(self.data.datetime[0]))
              txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt))
              txt.append('{:f}'.format(self.data.open[0]))
              txt.append('{:f}'.format(self.data.high[0]))
              txt.append('{:f}'.format(self.data.low[0]))
              txt.append('{:f}'.format(self.data.close[0]))
              txt.append('{:6d}'.format(int(self.data.volume[0])))
              txt.append('{:d}'.format(int(self.data.openinterest[0])))
              txt.append('{:f}'.format(self.sma[0]))
              print(', '.join(txt))
      
              if len(self.datas) > 1 and len(self.data1):
                  txt = list()
                  txt.append('Data1')
                  txt.append('%04d' % len(self.data1))
                  dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
                  txt.append('{}'.format(self.data1.datetime[0]))
                  txt.append('%s' % self.data1.datetime.datetime(0).strftime(dtfmt))
                  txt.append('{}'.format(self.data1.open[0]))
                  txt.append('{}'.format(self.data1.high[0]))
                  txt.append('{}'.format(self.data1.low[0]))
                  txt.append('{}'.format(self.data1.close[0]))
                  txt.append('{}'.format(self.data1.volume[0]))
                  txt.append('{}'.format(self.data1.openinterest[0]))
                  txt.append('{}'.format(float('NaN')))
                  print(', '.join(txt))
      
              if self.counttostop:  # stop after x live lines
                  self.counttostop -= 1
                  if not self.counttostop:
                      self.env.runstop()
                      return
      
              if not self.p.trade:
                  return
      
              if self.datastatus and not self.position and len(self.orderid) < 1:
                  if not self.p.usebracket:
                      if not self.p.sell:
                          # price = round(self.data0.close[0] * 0.90, 2)
                          price = self.data0.close[0] - 0.005
                          self.order = self.buy(size=self.p.stake,
                                                exectype=self.p.exectype,
                                                price=price,
                                                valid=self.p.valid)
                      else:
                          # price = round(self.data0.close[0] * 1.10, 4)
                          price = self.data0.close[0] - 0.05
                          self.order = self.sell(size=self.p.stake,
                                                 exectype=self.p.exectype,
                                                 price=price,
                                                 valid=self.p.valid)
      
                  else:
                      print('USING BRACKET')
                      price = self.data0.close[0] - 0.05
                      self.order, _, _ = self.buy_bracket(size=self.p.stake,
                                                          price=price,
                                                          exectype=bt.Order.StopTrail, 
                                                          trailpercent=0.02,
                                                          valid=self.p.valid)
      
                  self.orderid.append(self.order)
              elif self.position and not self.p.donotcounter:
                  if self.order is None:
                      if not self.p.sell:
                          self.order = self.sell(size=self.p.stake // 2,
                                                 exectype=bt.Order.Market,
                                                 price=self.data0.close[0])
                      else:
                          self.order = self.buy(size=self.p.stake // 2,
                                                exectype=bt.Order.Market,
                                                price=self.data0.close[0])
      
                  self.orderid.append(self.order)
      
              elif self.order is not None and self.p.cancel:
                  if self.datastatus > self.p.cancel:
                      self.cancel(self.order)
      
              if self.datastatus:
                  self.datastatus += 1
      
          def start(self):
              if self.data0.contractdetails is not None:
                  print('-- Contract Details:')
                  print(self.data0.contractdetails)
      
              header = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume',
                        'OpenInterest', 'SMA']
              print(', '.join(header))
      
              self.done = False
      

      I need this to be applied for when I place the order first time, but as well when the strategy triggers it, in neither cases is not working or at least I didn't configure it well (most likely)

      As a trigger in my terminal I use this:

      @xxxx: python oandav20test.py --account '101-004-XXXXXXXX' --token 'e8f4f3daabffXXXXXXXXX' --data0 GBP_JPY --resample --timeframe Minutes --compression 1 --no-backfill_start --stake 1000 --trade --broker
      

      Thank you very much again for this great tool and all the support.

      1 Reply Last reply Reply Quote 0
      • Chirila Catalin
        Chirila Catalin last edited by

        For example on GBP_JPY there is an opening price for 143.277, I should have a stop loss at let's say -0.2%, and a trailing stop which will follow the current price in case the strategy is right, with let's say -0.05% new stop loss; they should work in both directions either for sell or buy... I think this makes it a bit more clear what I'm after... thank you again

        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors