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/

    Sell order not executing from notify order

    General Code/Help
    2
    5
    43
    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.
    • V
      Vypy1 last edited by

      I am testing a strategy and I am issuing a sell order from notify order after execution of the buy leg. I use a custom sizer to size my position. My problem is that my strategy enters only 1 trade in the entire backtest when I use my custom sizer but when I use a fixed size sizer for the same conditions multiple trades are issued from the strategy.

      Not sure why that is happening. Can anyone help with this.

      # Custom sizer class
      class MySizer(bt.Sizer):
          
          def _getsizing(self, comminfo, cash, data, isbuy):
              
              size = (cash * 0.01)/(data.open[1] * 0.05)
              
              return math.floor(size)
      
      
      # Dummy strategy
      class test_strat(bt.Strategy):
          
          params = (('fma', 20), ('sma', 50), ('trail', 0.08),)
          
          
          def __init__(self):
              
              self.open = self.data.open
              self.high = self.data.high
              self.low = self.data.low
              self.close = self.data.close
              self.fma = bt.indicators.EMA(self.close, period = self.p.fma)
              self.sma = bt.indicators.EMA(self.close, period = self.p.sma)
              self.cross = bt.indicators.CrossUp(self.fma, self.sma)
      
              
              self.orders = None
              self.orefs = []
      
                   
          def log(self, txt, dt=None):
              dt = self.datas[0].datetime.date()
              print(f'Date: {dt}, {txt}')
              
          
          def notify_order(self, order):
              
                  
                  if order.status in [order.Submitted, order.Accepted]:
                      return
      
      
                  if order.status in [order.Completed]:
      
                      if order.isbuy():
                          self.log(f'BUY EXECUTED: {order.executed.price}, Cost: {order.executed.value}, Size: {self.getposition().size}')
      
      
                          self.execprice = order.executed.price
                          self.totalcost = order.executed.value    
      
      
      #                     o2 = self.sell(exectype=bt.Order.Stop, price=self.execprice * 0.95)
                          o2 = self.sell(exectype=bt.Order.StopTrail, trailpercent = 0.05)
                          
                          
                          self.orders = [o2]
                          self.orefs = [o2.ref]
                          
                          self.log(f'SELL ORDERS CREATED: {self.orefs}')
                          self.log(f'ORDERS IN THE SYSTEM: {self.orders}')
        
      
                          self.log(f'Stop Created At: {self.execprice * 0.95}, Cash: {cerebro.broker.getcash()}')
      
      
                      elif order.issell():
                          self.sellprice = order.executed.price
                          self.sellcost = order.executed.value
                          self.log(f'SELL EXECUTED: {self.sellprice}, Cost: {self.sellcost}')
      
                  elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                      self.log('Order Canceled/Margin/Rejected')
      
                  
                  if not order.alive() and order.ref in self.orefs:
                      self.orefs.remove(order.ref)
                      self.log(f'ORDERS ALIVE: {self.orefs}')
      
                  self.log(f'LIVE ORDERS: {self.orders}')
      
          
          def notify_trade(self, trade):
              if trade.isopen:
                  return  
              
              
              else:
                  self.log(f'OPERATION PROFIT: GROSS {trade.pnl}, NET {trade.pnlcomm}, Trade PnL: {trade.pnlcomm/self.totalcost}')
                  self.log(f'Updated Account Balance: {cerebro.broker.getcash()}')
                  
              
                  
          def next(self):
              
              self.log(f'Close: {self.close[0]}')
              
              if self.orefs:
                  return
              
              if not self.position:
                  
                  if self.cross > 0:
                      
      
                      o1 = self.buy()
                      self.log(f'BUY CREATED: {o1.created.price}')
      
      
                      self.orders = [o1]
                      self.orefs = [o1.ref]
                      self.log(f'INITIAL ORDERS: {self.orefs}')
                  
              
      
                      
      cerebro = bt.Cerebro()
      cerebro.broker.set_cash(200000)
      
      print(f'Starting Portfolio Value: {cerebro.broker.getvalue()}')
      
      
      data = bt.feeds.PandasData(dataname=hdfcbank, datetime=None, open=-1, high=-1, low=-1, close=-1, volume=-1)
      cerebro.adddata(data, name = 'hdfcbank')
      
      
      cerebro.addstrategy(test_strat)
      cerebro.addsizer(MySizer)
      cerebro.addanalyzer(trades_list, _name='tradelist')
      
      
      strat = cerebro.run(tradehistory = True)
      tradeslist = strat[0].analyzers.tradelist.get_analysis()
      trades = pd.DataFrame(tradeslist)
      
      
      
      print(f'Final Portfolio Value: {cerebro.broker.getvalue()}')
      
      run-out 1 Reply Last reply Reply Quote 0
      • run-out
        run-out @Vypy1 last edited by

        @vypy1 Hi can you include your logs showing the trades? Thanks.

        RunBacktest.com

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

          @run-out Hi, for some reason when I add the attribute

          size = order.executed.size
          

          to my sell order in notify order while MySizer class is in use things work out as expected.

          Without this when I look at the logs as provided below, I cant seem to understand why the trade does not close. After closing, it should notify me of this closed trade along with my profits.

          Date: 2008-04-23, Close: 144.54
          Date: 2008-04-24, Close: 144.26
          Date: 2008-04-25, Close: 150.04
          Date: 2008-04-28, Close: 152.34
          Date: 2008-04-29, Close: 154.78
          Date: 2008-04-30, Close: 152.42
          Date: 2008-04-30, BUY CREATED: 152.42
          Date: 2008-04-30, INITIAL ORDERS: [1868]
          Date: 2008-05-02, BUY EXECUTED: 154.5, Cost: 39861.0, Size: 258
          Date: 2008-05-02, Stop Created At: 146.775, Cash: 160139.0
          Date: 2008-05-02, Close: 154.04
          Date: 2008-05-05, Close: 152.86
          Date: 2008-05-06, Close: 154.29
          Date: 2008-05-07, Close: 154.19
          Date: 2008-05-08, SELL EXECUTED: 146.5755, Cost: 31981.5
          Date: 2008-05-08, ORDERS ALIVE: []
          Date: 2008-05-08, Close: 150.84
          Date: 2008-05-09, Close: 145.25
          Date: 2008-05-12, Close: 146.81
          Date: 2008-05-13, Close: 148.03
          Date: 2008-05-14, Close: 146.48
          Date: 2008-05-15, Close: 147.85
          Date: 2008-05-16, Close: 150.04
          Date: 2008-05-20, Close: 146.12
          Date: 2008-05-21, Close: 141.01
          Date: 2008-05-22, Close: 138.38
          Date: 2008-05-23, Close: 138.15
          Date: 2008-05-26, Close: 134.76
          Date: 2008-05-27, Close: 133.27
          
          run-out 1 Reply Last reply Reply Quote 0
          • run-out
            run-out @Vypy1 last edited by

            @vypy1 Your logs are not informative enough. Try using some or all of the following and then you'll get better data as to what's happening with your trades.

               def notify_order(self, order):
                    """ Triggered upon changes to orders. """
            
                    # Suppress notification if it is just a submitted order.
                    if order.status == order.Submitted:
                        return
            
                    # Print out the date, security name, order number and status.
                    dt, dn = self.datetime.date(), order.data._name
                    type = "Buy" if order.isbuy() else "Sell"
                    self.log(
                        f"{order.data._name:<6} Order: {order.ref:3d}\tType: {type:<5}\tStatus"
                        f" {order.getstatusname():<8} \t"
                        f"Size: {order.created.size:9.4f} Price: {order.created.price:9.4f} "
                        f"Position: {self.getposition(order.data).size}"
                    )
                    if order.status == order.Margin:
                        return
            
                    # Check if an order has been completed
                    if order.status in [order.Completed]:
                        self.log(
                            f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
                            # f"EXECUTED for: {dn} "
                            f"Price: {order.executed.price:6.2f} "
                            f"Cost: {order.executed.value:6.2f} "
                            f"Comm: {order.executed.comm:4.2f} "
                            f"Size: {order.created.size:9.4f} "
                        )
            

            RunBacktest.com

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

              @run-out Thanks will try this out.

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