Backtrader Community

    • 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/

    Cancel buy_bracket order after it's closed

    Indicators/Strategies/Analyzers
    3
    9
    1017
    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.
    • Eduardo Menges Mattje
      Eduardo Menges Mattje last edited by

      I'm trying to implement a stop loss in my strategy by using buy_bracket, but I'm getting multiple closes, as you can see on the log. What I think is happening is that the stop order issued by the buy_bracket is not being canceled after the buy_bracket is closed. This is the code:

      import backtrader as bt
      from datetime import datetime
      
      
      class RSI(bt.Strategy):
          params = dict(
              stopLoss=0.2,
              upperband=75,
              lowerband=25,
              period=9
          )
      
          def __init__(self):
              self.rsi = bt.indicators.RelativeStrengthIndex(period=self.p.period, upperband=self.p.upperband, lowerband=self.p.lowerband, safediv=True)
      
          def log(self, txt, dt=None):
              dt = dt or self.data.datetime[0]
              if isinstance(dt, float):
                  dt = bt.num2date(dt)
              print('%s, %s' % (dt.isoformat(), txt))
      
          def notify_order(self, order):
              price = round(order.executed.price, 2)
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(f'BUY EXECUTED, Price: {price}')
                  else:
                      self.log(f'CLOSE EXECUTED, Price: {price}')
      
              self.order = None
      
          def next(self):
              price = round(self.data.close[0], 2)
              if not self.position and self.rsi <= self.p.lowerband:
                  self.buy_bracket(limitexec=None, stopprice=(self.data.close * (1 - self.p.stopLoss)), exectype=bt.Order.Market)
                  self.log(f'BUY CREATE, price:{price}')
              if self.position and self.rsi >= self.p.upperband:
                  self.close()
                  self.log(f'CLOSE CREATE, price:{price}')
      
      
      start_cash = 100
      
      cerebro = bt.Cerebro()
      
      cerebro.addstrategy(RSI)
      
      data = bt.feeds.GenericCSVData(
          dataname='NEOUSDT-15m-data.csv',
          fromdate=datetime(2020, 2, 1, 0, 0),
          todate=datetime(2020, 6, 1, 0, 0),
          timeframe=bt.TimeFrame.Minutes,
          compression=15,
          dtformat='%Y-%m-%d %H:%M:%S',
          openinterest=None
      )
      
      cerebro.adddata(data)
      
      cerebro.broker.setcash(start_cash)
      
      cerebro.addsizer(bt.sizers.PercentSizer, percents=90)  # Set the order size
      
      cerebro.addanalyzer(bt.analyzers.DrawDown, _name='Drawdown')
      
      cerebro.broker.setcommission(commission=0.0001, margin=False)
      
      cerebro.run()
      
      portvalue = round(cerebro.broker.getvalue(), 2)
      pnl = round(portvalue - start_cash, 2)
      
      print('Final Portfolio Value: ${}'.format(portvalue))
      print('P/L: ${}'.format(pnl))
      cerebro.plot(style='candlestick')
      
      

      Is there a way to cancel that order or am I doing something wrong?

      1 Reply Last reply Reply Quote 1
      • run-out
        run-out last edited by

        You might wish to consider using stop loss instead of bracket orders, since you aren't using the limit side.

        RunBacktest.com

        Eduardo Menges Mattje 1 Reply Last reply Reply Quote 0
        • Eduardo Menges Mattje
          Eduardo Menges Mattje @run-out last edited by

          @run-out said in Cancel buy_bracket order after it's closed:

          You might wish to consider using stop loss instead of bracket orders, since you aren't using the limit side.

          I've tried to implement it with this:

              def next(self):
                      price = round(self.data.close[0], 2)
                      stop_price = price * (1 - self.p.stopLoss)
                      if not self.position and self.rsi <= self.p.lowerband:
                          buy = self.buy()
                          stop = self.close(price=stop_price)
                          self.log(f'BUY CREATE, price:{price}')
                      if self.position and self.rsi >= self.p.upperband:
                          self.close()
                          self.log(f'CLOSE CREATE, price:{price}')
                          if self.stop:
                              self.cancel(stop)
          

          However, it doesn't work. I get an UnboundLocalError.

          1 Reply Last reply Reply Quote 0
          • run-out
            run-out last edited by

            Try implementing the stop/close/cancel order something like this:

                    price = round(self.data.close[0], 2)
                    stop_price = price * (1 - self.p.stopLoss)
                    if not self.position and self.rsi[0] <= self.p.lowerband:
                        self.buy_order = self.buy(transmit=False)
                        self.stop_order = self.sell(exectype=bt.Order.Stop, price=stop_price,
                                  parent=self.buy_order, transmit=True)
                        self.log(f'BUY CREATE, price: {price}')
            
                    if self.position and self.rsi >= self.p.upperband:
                        self.close()
                        self.cancel(self.stop_order)
                        self.log(f'CLOSE CREATE, price {price}')
            
            
            

            @Eduardo-Menges-Mattje said in Cancel buy_bracket order after it's closed:

            stop_price = price * (1 - self.p.stopLoss)

            A comment on the stop_price. Your parameter is 0.2, which means your stop price is:

            price * (1-.2) 
            # or
            price * (0.8)
            

            This will rarely trigger while the other sell condition is in place. I lowered this to .02 using 15 minute data and there seemed to be a good balance between stops and close orders.

            RunBacktest.com

            Eduardo Menges Mattje 1 Reply Last reply Reply Quote 1
            • A
              ab_trader last edited by

              OCO orders were developed to treat situations when orders depends on each other. Use of theses type of the orders might help.

              • If my answer helped, hit reputation up arrow at lower right corner of the post.
              • Python Debugging With Pdb
              • New to python and bt - check this out
              1 Reply Last reply Reply Quote 2
              • Eduardo Menges Mattje
                Eduardo Menges Mattje @run-out last edited by

                @run-out said in Cancel buy_bracket order after it's closed:

                Try implementing the stop/close/cancel order something like this:

                        price = round(self.data.close[0], 2)
                        stop_price = price * (1 - self.p.stopLoss)
                        if not self.position and self.rsi[0] <= self.p.lowerband:
                            self.buy_order = self.buy(transmit=False)
                            self.stop_order = self.sell(exectype=bt.Order.Stop, price=stop_price,
                                      parent=self.buy_order, transmit=True)
                            self.log(f'BUY CREATE, price: {price}')
                
                        if self.position and self.rsi >= self.p.upperband:
                            self.close()
                            self.cancel(self.stop_order)
                            self.log(f'CLOSE CREATE, price {price}')
                
                
                

                Now I have a question. If I use self.buy(), the self.sell() from the stop loss will open a short order or will it simply close the buy order?

                @Eduardo-Menges-Mattje said in Cancel buy_bracket order after it's closed:

                stop_price = price * (1 - self.p.stopLoss)

                A comment on the stop_price. Your parameter is 0.2, which means your stop price is:

                price * (1-.2) 
                # or
                price * (0.8)
                

                This will rarely trigger while the other sell condition is in place. I lowered this to .02 using 15 minute data and there seemed to be a good balance between stops and close orders.

                Yes, this high number I've used only for testing, to see if it's working at all.

                1 Reply Last reply Reply Quote 0
                • Eduardo Menges Mattje
                  Eduardo Menges Mattje last edited by

                  BUMP....

                  1 Reply Last reply Reply Quote 0
                  • A
                    ab_trader last edited by

                    @Eduardo-Menges-Mattje said in Cancel buy_bracket order after it's closed:

                    Is there a way to cancel that order or am I doing something wrong?

                    OCO orders were developed to treat situations when orders depends on each other. Use of theses type of the orders might help.

                    @Eduardo-Menges-Mattje said in Cancel buy_bracket order after it's closed:

                    Now I have a question. If I use self.buy(), the self.sell() from the stop loss will open a short order or will it simply close the buy order?

                    self.sell just sells shares. If it uses the same size as it was used in the self.buy, than the long position will be closed. If the self.sell size is less, than part of the long position will be still open. If the self.sell size is more, than long position will be closed, and short position will be open.

                    • If my answer helped, hit reputation up arrow at lower right corner of the post.
                    • Python Debugging With Pdb
                    • New to python and bt - check this out
                    1 Reply Last reply Reply Quote 3
                    • Eduardo Menges Mattje
                      Eduardo Menges Mattje last edited by

                      @ab_trader @run-out Thank you for your everything!

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