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/

    Multiple filled orders despite "if not position" condition

    General Code/Help
    order market order.market bracket
    1
    2
    46
    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.
    • G
      Gianlu last edited by

      Hello, trying to backtest a simple RSI strategy.
      It sends a buy_bracket if current position==0 and rsi indicator crossup oversold thersold and close the position when the rsi crossdown the opposite threshold.
      The opposite for selling; always only if current position==0.

      What I cannot understand it is that sometimes multiple unwanted entries happen. I added some "check print" ad notify_order status in order to better understand but I gave up.

      Here the logic:

      import backtrader as bt
      import datetime
      
      class rsi_strategy(bt.Strategy):
          params = (
              ('backtest', False),
              ('printLog', True),
              ('rsi_period', 19),
              ('rsi_overSold', 21),
              ('rsi_overBought', 77),
              ('stopLoss_perc', 7),
              ('takeProfit_perc', 20)
          )
      
          def __init__(self):
              # self.live_bars = False
              self.rsi_ind = bt.indicators.RSI(self.data.close,
                                               period=self.p.rsi_period,
                                               plot=True,
                                               plotname='RSI',
                                               subplot=True)
      
              # Buy Signals
              self.CrossedOS = bt.indicators.CrossUp(self.rsi_ind, self.p.rsi_overSold, plotname='x ↑ OS')
              # Sell Signals
              self.CrossedOB = bt.indicators.CrossDown(self.rsi_ind, self.p.rsi_overBought, plotname='x ↓ OB')
      
          def next(self):
      
              self.closePrice = self.data.close[0]
              self.Bar_time = self.data.datetime.time()
              self.Bar_date = self.data.datetime.date()
              self.order_size = int((self.broker.cash / self.closePrice / 4))
              self.highside_offset = round(self.closePrice * self.p.takeProfit_perc / 100, 2)
              self.lowside_offset = round(self.closePrice * self.p.stopLoss_perc / 100, 2)
              self.current_position = self.getposition().size
      
              print(len(self))
              print('BarDataTime >>', self.Bar_date, self.Bar_time, '  /  Equity >>', int(self.broker.getvalue()),
                    '  /  Current Size >>', self.current_position)
              print('close >>', self.closePrice, '  /  RSI >>', self.rsi_ind[0].__round__(1))
              print('-------------')
              #
              #     # If flat and rsi Cross-up Over-Sold level then buy_bracket
              if self.current_position == 0:
                  if self.broker.getvalue() > 9500 and self.CrossedOS:
                      print('Buy Condition met, current position size>>', self.current_position)  # control string
                      self.buy_bracket(size=self.order_size, stopprice=self.closePrice - self.lowside_offset,
                                       limitprice=self.closePrice + self.highside_offset,
                                       exectype=bt.Order.Limit)
              elif self.current_position < 0 and self.CrossedOS:
                  print('Close-Sell Condition met, current position size>>', self.current_position)  # control string
                  self.close()
      
              # If flat and rsi Cross-Down Over-Bought level then buy_bracket
              if self.current_position == 0:
                  if self.broker.getvalue() > 9500 and self.CrossedOB:
                      print('Sell Condition met, current position size>>', self.current_position)  # control string
                      self.sell_bracket(size=self.order_size, stopprice=self.closePrice + self.lowside_offset,
                                        limitprice=self.closePrice - self.highside_offset,
                                        exectype=bt.Order.Limit)
              elif self.current_position > 0 and self.CrossedOB:
                  print('Close-Buy Condition met, current position size>>', self.current_position)  # control string
                  self.close()
      
          def notify_order(self, order):
              if order.status in [order.Submitted]:
                  print('Order Submitted')
      
              if order.status in [order.Accepted]:
                  print('Order Accepted')
      
              if order.status in [order.Completed]:
                  print('Order Completed')
      
      
      
      

      the plot:

      a1d737f6-615d-4b24-8772-eb418dccc7c9-image.png

      and some of the terminal prints for "standard behaviour:

      close >> 1.334   /  RSI >> 20.5
      -------------
      62879
      BarDataTime >> 2022-06-13 16:24:00   /  Equity >> 10991   /  Current Size >> 0
      close >> 1.33425   /  RSI >> 21.3
      -------------
      Buy Condition met, current position size>> 0
      Order Submitted
      Order Submitted
      Order Submitted
      Order Accepted
      Order Accepted
      Order Accepted
      Order Completed
      62880
      BarDataTime >> 2022-06-13 16:27:00   /  Equity >> 10987   /  Current Size >> 2059
      close >> 1.3325   /  RSI >> 19.8
      -------------
      62881
      BarDataTime >> 2022-06-13 16:30:00   /  Equity >> 10992   /  Current Size >> 2059
      close >> 1.33475   /  RSI >> 26.9
      -------------
      62882
      BarDataTime >> 2022-06-13 16:33:00   /  Equity >> 10998   /  Current Size >> 2059
      

      and of the strange behaviour:

      62921
      BarDataTime >> 2022-06-14 10:00:00   /  Equity >> 10986   /  Current Size >> 2059
      close >> 1.332   /  RSI >> 41.4
      -------------
      62922
      BarDataTime >> 2022-06-14 10:03:00   /  Equity >> 10979   /  Current Size >> 2059
      close >> 1.32875   /  RSI >> 38.2
      -------------
      Order Completed
      62923
      BarDataTime >> 2022-06-14 10:06:00   /  Equity >> 10971   /  Current Size >> 3684
      close >> 1.3255   /  RSI >> 35.3
      -------------
      62924
      BarDataTime >> 2022-06-14 10:09:00   /  Equity >> 10971   /  Current Size >> 3684
      close >> 1.3255   /  RSI >> 35.3
      -------------
      62925
      BarDataTime >> 2022-06-14 10:12:00   /  Equity >> 10966   /  Current Size >> 3684
      

      I really hope someone has already faced the problem and be kind to give explanation.

      Thanks in advance
      Gianluca

      1 Reply Last reply Reply Quote 0
      • G
        Gianlu last edited by

        Ok guys, thanks to some friends of mine, it came out that I was wrongly using bracket orders.
        I should have used the following logic:

        if buy_condition:
            self.buy(size=self.p.size)
            self.limitOrderSL = self.sell(size=self.p.size, 
             exectype=Order.Stop, price=stop_price)
            self.limitOrderTP = self.sell(size=self.p.size, 
             exectype=Order.Limit, price=profit_price)
        
        if close_condition:
            self.close()
            self.cancel(self.limitOrderSL)
            self.cancel(self.limitOrderTP)
        

        Regards

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