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/

    How to close a position if the stop loss wasn't triggered after "self.bar_executed + 1 "

    General Code/Help
    2
    4
    124
    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.
    • mama1baba
      mama1baba last edited by

      In my case, my position is closed at the next bar regardless of the stop loss order in place, even if my stop loss price is above the closing price (for long position) or below the closing price (for short position).

      What I wish to achieve is to check if the stop loss is hit first before proceed to close the position. How should I go about it?

      next() function

       def next(self):
              self.duration = len(self) - self.bar_executed + 1
              # Log OHLC and KC Band
              self.log('O: %.2f, H: %.2f, L: %.2f, C: %.2f, u: %.2f, l: %.2f, atr: %.2f'
                       %(self.data.open[0], self.data.high[0], 
                         self.data.low[0], self.data.close[0],
                         self.KC.l.upperKC[0], self.KC.l.lowerKC[0],
                         self.atr[0]
                        )
                      )
          
              # set up parameters for SL and TP
              above_upperKC = self.data.high[0] > self.KC.l.upperKC[0]
              below_lowerKC = self.data.low[0] < self.KC.l.lowerKC[0]
              long_trade = self.data.close[0] - self.data.low[0]
              short_trade = self.data.high[0] - self.data.close[0]
              long_stop = self.data.low[0] - (0.002 * self.data.close[0]) # low - 0.2% of close
              short_stop = self.data.high[0] + (0.002 * self.data.close[0]) # high + 0.2 % of close
              long_size = math.floor((self.p.percrisk * self.broker.get_value()) / ((self.data.close[0] - long_stop) * self.p.multiple))
              short_size = math.floor((self.p.percrisk * self.broker.get_value()) / ((short_stop - self.data.close[0]) * self.p.multiple))
              
          
              
              if not self.position: # not in the market
                  # Trade Logic
                  if below_lowerKC:
                      if long_trade >  self.atr[0]:
                          # Place BUY trade :
      
                          try:
                              o1 = self.buy(
                                      exectype= bt.Order.Market,
                                      size = long_size         
                                      )
                              self.log(
                              'BUY CREATE, {},KC LOWER, {},ATR, {},LOW, {}'.format(
                              self.data.close[0], self.KC.l.lowerKC[0], self.atr[0], self.data.low[0])
                              )
                              o2 = self.sell(price = long_stop,
                                         exectype= bt.Order.Stop,
                                         transmit = True,
                                         parent = o1,
                                         size = o1.size)
                              
                              self.orefs = [o1.ref, o2.ref]
                              
                          except AttributeError:
                              print("Minimum Sizing Exceeds The 1% Risk")
                  
                  elif above_upperKC:
                      if short_trade > self.atr[0]:
                          # Place SELL trade :
      
                          try:
                              
                              o1 = self.sell(
                                      exectype= bt.Order.Market,
                                      size = short_size
                                      )
                              self.log(
                              'SELL CREATE, {},KC UPPER, {},ATR, {},HIGH, {}'.format(
                              self.data.close[0], self.KC.l.upperKC[0], self.atr[0], self.data.high[0])
                              )
                              o2 = self.buy(price = short_stop,
                                             exectype= bt.Order.Stop,
                                             transmit = True,
                                             parent = o1,
                                             size = o1.size)
                              
                              self.orefs = [o1.ref, o2.ref]
      
                          except AttributeError:
                              print("Minimum Sizing Exceeds The 1% Risk")
              
              elif self.duration == 1: # close pos in the next bar
                      self.close()
      

      notify_order Function

          def notify_order(self, order):
              if order.status in [order.Submitted, order.Accepted]:
                  # Buy/Sell order submitted/accepted by broker. Do nothing
                  return 
              
              #Check if order has been completed
              if order.status in [order.Completed]:
                  if order.isbuy(): # Long
                      self.log(
                          'LONG EXECUTED Ref: %d, Price: %.4f, Cost: %.2f, Comm: %.2f' %
                          (order.ref,
                           order.executed.price,
                           order.executed.value,
                           order.executed.comm)
                          )
                      
                      
                      self.buy_price = order.executed.price
                      self.buy_comm = order.executed.comm
                      
                  else: # Short
                      self.log(
                          'SHORT EXECUTED Ref: %d, Price: %.4f, Cost: %.2f, Comm: %.2f' %
                          (order.ref,
                           order.executed.price,
                           order.executed.value,
                           order.executed.comm)
                          )
                      
                      self.sell_price = order.executed.price
                      self.sell_comm = order.executed.comm
          
                      
                  self.bar_executed = len(self)
                  
        
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Ref %03d : SL/TP Order Canceled/Margin/Rejected'
                           % (order.ref))
              
      

      Output

      2021-01-08 07:00, O: 1921.73, H: 1924.94, L: 1917.11, C: 1919.42, u: 1958.90, l: 1901.87, atr: 12.67
      2021-01-08 11:00, O: 1919.32, H: 1919.52, L: 1913.00, C: 1914.50, u: 1956.70, l: 1901.05, atr: 12.37
      2021-01-08 15:00, O: 1914.30, H: 1918.82, L: 1881.49, C: 1898.05, u: 1956.57, l: 1895.31, atr: 13.61
      2021-01-08 15:00, BUY CREATE, 1898.05,KC LOWER, 1895.3050964232048,ATR, 13.614035133805148,LOW, 1881.49
      2021-01-08 19:00, LONG EXECUTED Ref: 31, Price: 1898.0500, Cost: 6000.00, Comm: 10.00
      2021-01-08 19:00, Ref 031 : SL/TP Order Canceled/Margin/Rejected
      2021-01-08 19:00, O: 1898.05, H: 1901.26, L: 1863.53, C: 1870.75, u: 1954.03, l: 1887.34, atr: 14.82
      2021-01-08 23:00, SHORT EXECUTED Ref: 33, Price: 1870.7500, Cost: 6000.00, Comm: 10.00
      2021-01-08 23:00, OPERATION PROFIT, Gross -5460.00, Net -5480.00
      2021-01-08 23:00, O: 1870.85, H: 1872.36, L: 1834.03, C: 1844.46, u: 1949.41, l: 1877.43, atr: 16.00
      2021-01-09 03:00, O: 1844.16, H: 1856.20, L: 1843.36, C: 1856.20, u: 1943.61, l: 1872.34, atr: 15.84
      

      And by right, my stop loss price : presumably1877.69 should be executed before 1870.75 (next bar close)

      Thank You in advance!

      run-out 2 Replies Last reply Reply Quote 0
      • run-out
        run-out @mama1baba last edited by

        @mama1baba said in How to close a position if the stop loss wasn't triggered after "self.bar_executed + 1 ":

        2021-01-08 19:00, Ref 031 : SL/TP Order Canceled/Margin/Rejected

        Getting rejected because there's not enough cash to cover the sale. Try putting in a million dollars or something to see if the error goes away.

        RunBacktest.com

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

          @run-out I set my equity as 500k USD while the cost is only 6000 (arbitrary). So I think is not related to the broker balance?

          Its weird that the order reference for my stop order is the same as my main order. Could it be something wrong with my entry logic?

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

            @mama1baba said in How to close a position if the stop loss wasn't triggered after "self.bar_executed + 1 ":

            o1 = self.buy(
            exectype= bt.Order.Market,
            size = long_size
            )

            Try setting transmit = False on the first trade:

            transmit (default: True)
            
            Indicates if the order has to be transmitted, ie: not only placed in the broker but also issued. This is meant for example to control bracket orders, in which one disables the transmission for the parent and 1st set of children and activates it for the last children, which triggers the full placement of all bracket orders.
            

            RunBacktest.com

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