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/

    Problems with cancelling order

    General Code/Help
    3
    17
    1732
    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.
    • ZHUOER ZHANG
      ZHUOER ZHANG last edited by

      Hi, sorry to bother you guys with such a naive question, but I've read through the cancel strategy in the doc and did not fully understand it.

      It seems that, the order self.cancel(self.order) did not work at all, not any orders have been successfully canceled, and I'm a bit confused.

              if self.data.pre[0] == 2:
                  if self.position.size == 0:
                  #try to cancel the stop order I have created after I buy/sell
                      self.cancel(self.order)
                      self.log('Buy CREATE, %.2f' % self.dataclose[0])
                      self.order = self.buy(size=10)
                      price = self.dataclose[0]
                      self.order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 10)
                      print(self.position)
                      print('Equity, %2f' % cerebro.broker.getvalue())
                  elif self.position.size < 0:
                      self.cancel(self.order)
                      self.log('Buy CREATE, %.2f' % self.dataclose[0])
                      self.order = self.buy(size=20)
                      price = self.dataclose[0] 
                      self.order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 20)
                      print(self.position)
                      print('Equity, %2f' % cerebro.broker.getvalue())
              if self.data.pre[0]== 0 :
                  if self.position.size == 0:
                      self.cancel(self.order)
                      self.log('Sell CREATE, %.2f' % self.dataclose[0])
                      self.order = self.sell(size=10)
                      price = self.dataclose[0]
                      self.order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 10)
                      print(self.position)
                      print('Equity, %2f' % cerebro.broker.getvalue())
                           
                  elif self.position.size>0:
                       self.cancel(self.order)
                       self.log('Sell CREATE, %.2f' % self.dataclose[0])
                       self.order = self.sell(size=20)
                       price = self.dataclose[0]
                       self.order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 20)
                       print(self.position)
                       print('Equity, %2f' % cerebro.broker.getvalue())
      
      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        It works, and works as expected. Share more details on what you want to achieve, full strategy script etc and we will try to 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 1
        • ZHUOER ZHANG
          ZHUOER ZHANG last edited by

          Just for testing purpose, I add a column indicating ‘Buy’(2), ‘Sell’(0) and ‘Do Nothing’(1) in the csv file and feed it into the datafeed.
          When the Buy signal showed up, if our position is 0, we cancel all the unexecuted orders (the stop order in this context) and buy 10 sizes at market price. After which we want to give a stop-loss order, the price of this stop order is to sell at (our executed price – 8), and the size is our position after the buys. (10 in which case)
          If our position is 10, we do nothing.
          If our position is -10, we cancel all the unexecuted orders and buy 20 sizes at market price , then give a stop order at 20 size.

          When the Sell signal showed up, if our position is 0, we cancel all the unexecuted orders and sell 10 sizes at market price. After which we want to give a stop-loss order, the price of the stop-loss order is to buy at (our executed price + 8), and the size is our position after the buys. (10 in which case)
          If our position is -10, we do nothing.
          If our position is 10, we cancel all the unexecuted orders and buy 20 sizes at market price , then give a stop order at 20 size.

          And I’m trying to print out the information of the canceled order (time, type, price, size) as well. For your full information, I give you the full code.

          Thank you again for your help and timely reply! Sorry my reply is a bit late coming.

          from __future__ import (absolute_import, division, print_function,
                                  unicode_literals)
          
          import datetime
          import pandas as pd
          import backtrader as bt
          import backtrader.feeds as btfeeds
          from backtrader.feeds import GenericCSVData
          
          
          class dataFeed(btfeeds.GenericCSVData):
          
              # Add a 'pe' line to the inherited ones from the base class
              lines = ('pre',)
          
              # openinterest in GenericCSVData has index 7 ... add 1
              # add the parameter to the parameters inherited from the base class
          
              params = (
                  ('dtformat', '%Y/%m/%d %H:%M'),
                  ('datetime', 0),
                  ('open', 1),
                  ('high', 2),
                  ('low', 3),
                  ('close', 4),
                  ('pre', 5),
                  ('volume',-1),
                  ('openinterest',-1)
                  )
          
          
          # Create a Stratey
          class TestStrategy(bt.Strategy):
          
              def log(self, txt, dt=None):
                  ''' Logging function fot this strategy'''
                  dt = dt or self.datas[0].datetime.date(0)
                  print('%s, %s' % (dt.isoformat(), txt))
           
              def __init__(self):
                  # Keep a reference to the "close" line in the data[0] dataseries
                  self.dataclose = self.datas[0].close
                  # To keep track of pending orders
                  self.order = None
           
              def notify_order(self, order):
                      print('{}: Order ref: {} / Type {} / Status {}'.format(
                          self.data.datetime.date(0),
                          order.ref, 'Buy' * order.isbuy() or 'Sell',
                          order.getstatusname()))
                      
                      if order.status in [order.Submitted, order.Accepted]:
                      # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                          return
          
                  # Check if an order has been completed
                  # Attention: broker could reject order if not enougth cash
          
          
                      if order.status in [order.Completed]:
                          if order.isbuy():
                              self.log(
                                  "Buy EXECUTED, Price: %.2f. ,size:%.2f"
                                  % (order.executed.price, order.executed.size) 
                              )
                          elif order.issell():
                              self.log(
                                  "Sell EXECUTED, Price: %.2f, size:%.2f"
                                  % (order.executed.price, order.executed.size)
                              )
                      elif order.status in [order.Canceled]:
                          self.log('Order Canceled')
          
           
                  # Write down: no pending order
                      self.order = None
           
              def next(self):
                  # Check if an order is pending ... if yes, we cannot send a 2nd one
                  if self.order:
                      return
                  # Simply log the closing price of the series from the reference
                  self.log('Close, %.2f' % self.dataclose[0])
          
                  order = None
          
                  if self.data.pre[0] == 2:
                      if self.position.size == 0:
                      #try to cancel the stop order I have created here
                          self.cancel(self.order)
                          self.log('Buy CREATE, %.2f' % self.dataclose[0])
                          self.order = self.buy(size=10)
                          price = self.dataclose[0]
                          self.order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 10)
                          print(self.position)
                          print('Equity, %2f' % cerebro.broker.getvalue())
                      elif self.position.size < 0:
                          self.cancel(self.order)
                          self.log('Buy CREATE, %.2f' % self.dataclose[0])
                          self.order = self.buy(size=20)
                          price = self.dataclose[0] 
                          self.order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 20)
                          print(self.position)
                          print('Equity, %2f' % cerebro.broker.getvalue())
                  if self.data.pre[0]== 0 :
                      if self.position.size == 0:
                          self.cancel(self.order)
                          self.log('Sell CREATE, %.2f' % self.dataclose[0])
                          self.order = self.sell(size=10)
                          price = self.dataclose[0]
                          self.order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 10)
                          print(self.position)
                          print('Equity, %2f' % cerebro.broker.getvalue())
                               
                      elif self.position.size>0:
                           self.cancel(self.order)
                           self.log('Sell CREATE, %.2f' % self.dataclose[0])
                           self.order = self.sell(size=20)
                           price = self.dataclose[0]
                           self.order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 20)
                           print(self.position)
                           print('Equity, %2f' % cerebro.broker.getvalue())
                                                 
          if __name__ == '__main__' :
              cerebro = bt.Cerebro()
              data = dataFeed(dataname='D:/TEST_SL_ODA.csv', timeframe=bt.TimeFrame.Minutes)
                  
                   
          
                  # Add the Data Feed to Cerebro
              cerebro.adddata(data)
          
              cerebro.addstrategy(TestStrategy)
          
              # Set our desired cash start
              cerebro.broker.setcash(500000.0)
          
          
              # Set the commission
              cerebro.broker.setcommission(commission=0.0)
              
              print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
          
              cerebro.run()
          
              cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name = 'SharpeRatio')
              cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW')
              results = cerebro.run()
              strat = results[0]
              print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
              print('SR:', strat.analyzers.SharpeRatio.get_analysis())
              print('DW:', strat.analyzers.DW.get_analysis())
          
          
              cerebro.plot()
          
          
          

          Really Appreciate your help! :)

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

            @ZHUOER-ZHANG said in Problems with cancelling order:

            def notify_order(self, order):

            In order to print out details of your cancelled orders, you do it in def notify_order,

            @ZHUOER-ZHANG said in Problems with cancelling order:

            elif order.status in [order.Canceled]:
            self.log('Order Canceled')

            Just add in more details. like date time, order reference etc.

            @ZHUOER-ZHANG said in Problems with cancelling order:

                 self.order = self.buy(size=10)
                 price = self.dataclose[0]
                 self.order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 10)
            

            In next you are using self.order improperly. self.order is just a variable, and you keep reassigning it. So first you assign it to

            self.order = self.buy(size=10)
            

            for which your self.order will now be referencing a orderbuy object, and then you immediately reassign it as

            self.order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 10)
            

            and now your self.order references a sell object. You will need to use a list or dictionary to keep track of multiple orders that you plan to cancel all at once.
            Example can be found in this blog and in the docs.

            RunBacktest.com

            ZHUOER ZHANG 1 Reply Last reply Reply Quote 2
            • A
              ab_trader last edited by

              Also re-write (maybe even remove) self.order = None from the notify_order(self). With this statement you literally do self.cancel(None) in the next().

              • 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
              ZHUOER ZHANG 1 Reply Last reply Reply Quote 1
              • ZHUOER ZHANG
                ZHUOER ZHANG @run-out last edited by

                @run-out First of all Thank you for your detailed explanation! Very clear and informative.

                For the order management part, is it because of my constant re-assigning of self.order causing the whole algorithm to behave strangely? ( and my ultimate failure to cancel an order)
                Because it seems to me that the first order is an market order and hence cannot be Cancelled
                Still the Stop Order can be cancelled and the mean goal of this self.cancel(self.order) is to cancel the Stop Order. I will follow your advice and use a list to improve my code!

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

                  @ab_trader Thank you! Corrected that and Hit the reputation :)
                  Sadly I also met a common problem cannot import name 'warnings' from 'matplotlib.dates'
                  The algorithm seems to run well on the Jupyter but not on other platforms.
                  Do you know why it happened?

                  A 1 Reply Last reply Reply Quote 0
                  • ZHUOER ZHANG
                    ZHUOER ZHANG last edited by

                    Also, what is the difference between self.cancel(self.order) and self.broker.cancel(self.order)?

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

                      @ZHUOER-ZHANG said in Problems with cancelling order:

                      Still the Stop Order can be cancelled and the mean goal of this self.cancel(self.order) is to cancel the Stop Order.

                      It can't be cancelled because of the following:

                      • you issue stop order in the next as `self.order = self.sell(...)
                      • than in notification you set self.order = None
                      • therefore self.cancel(self.order) doesn't cancel anything
                      • 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
                      ZHUOER ZHANG 1 Reply Last reply Reply Quote 1
                      • A
                        ab_trader @ZHUOER ZHANG last edited by

                        @ZHUOER-ZHANG said in Problems with cancelling order:

                        Do you know why it happened?

                        https://community.backtrader.com/topic/2784/cannot-import-name-warnings-from-matplotlib-dates

                        • 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 1
                        • ZHUOER ZHANG
                          ZHUOER ZHANG @ab_trader last edited by

                          @ab_trader I changed the code the variable of the stop order, and it seems that I still can't cancel anything... Would you mind looking at my (messed) code and further point out some mistakes?

                          Thank you!

                              def __init__(self):
                                  # Keep a reference to the "close" line in the data[0] dataseries
                                  self.dataclose = self.datas[0].close
                                  # To keep track of pending orders
                                  self.order = None
                                  self.stop_order = None
                           
                              def notify_order(self, order):
                                      print('{}: Order ref: {} / Type {} / Status {}'.format(
                                          self.data.datetime.date(0),
                                          order.ref, 'Buy' * order.isbuy() or 'Sell',
                                          order.getstatusname()))
                                      
                                      if order.status in [order.Submitted, order.Accepted]:
                                      # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                                          return
                          
                          
                          
                                      if order.status in [order.Completed]:
                                          if order.isbuy():
                                              self.log(
                                                  "Buy EXECUTED, Price: %.2f. ,size:%.2f"
                                                  % (order.executed.price, order.executed.size) 
                                              )
                                          elif order.issell():
                                              self.log(
                                                  "Sell EXECUTED, Price: %.2f, size:%.2f"
                                                  % (order.executed.price, order.executed.size)
                                              )
                                      elif order.status in [order.Canceled]:
                                          self.log('Order Canceled')
                          
                           
                              def next(self):
                                  # Check if an order is pending ... if yes, we cannot send a 2nd one
                                  if self.order:
                                      return
                                  # Simply log the closing price of the series from the reference
                                  self.log('Close, %.2f' % self.dataclose[0])
                          
                                  if self.data.pre[0] == 2:
                                      if self.position.size == 0:
                                      #try to cancel the stop order I have created here
                                          self.cancel(self.stop_order)
                                          self.order = self.buy(size=10)
                                          self.log('Buy Create! , %.2f' % self.dataclose[0])
                                          price = self.dataclose[0]
                                          self.stop_order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 10)
                                          print(self.position)
                                          print('Equity, %2f' % cerebro.broker.getvalue())
                                      elif self.position.size < 0:
                                          self.cancel(self.stop_order)
                                          self.order = self.buy(size=20)
                                          self.log('Buy Create! , %.2f' % self.dataclose[0])
                                          price = self.dataclose[0] 
                                          self.stop_order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 20)
                                          print(self.position)
                                          print('Equity, %2f' % cerebro.broker.getvalue())
                                          
                                  if self.data.pre[0] == 0 :
                                      if self.position.size == 0:
                                          self.cancel(self.stop_order)
                                          self.order = self.sell(size=10)
                                          self.log('Sell Create, %.2f' % self.dataclose[0])
                                          price = self.dataclose[0]
                                          self.stop_order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 10)
                                          print(self.position)
                                          print('Equity, %2f' % cerebro.broker.getvalue())    
                                      elif self.position.size>0:
                                           self.cancel(self.stop_order)
                                           self.log('Sell Create!, %.2f' % self.dataclose[0])
                                           self.order = self.sell(size=20)
                                           price = self.dataclose[0]
                                           self.stop_order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 20)
                                           print(self.position)
                                           print('Equity, %2f' % cerebro.broker.getvalue())
                                                                 
                          
                          1 Reply Last reply Reply Quote 0
                          • A
                            ab_trader last edited by

                            Post some outputs. It seems to me that you have only one buy order issued and executed and nothing else, but want to take a look on the script outputs.

                            • 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 0
                            • ZHUOER ZHANG
                              ZHUOER ZHANG last edited by

                              2020-07-24 (4).png 2020-07-24 (3).png

                              Here are some posts.
                              I keep on trying to improve the code and somehow successfully canceled... ( I delete the logic if self.order return and I suspect that is the reason(?)

                              1 Reply Last reply Reply Quote 0
                              • ZHUOER ZHANG
                                ZHUOER ZHANG last edited by

                                Anyway here is the improved code.
                                I received some suggestions about moving the canceling order into the notify_order section.

                                    def next(self):
                                        self.log('Close, %.2f' % self.dataclose[0])
                                
                                        if self.data.pre[0] == 2:
                                        # When the strategy told us to buy
                                            if self.position.size == 0:
                                            #try to cancel the stop order I have created here
                                                self.cancel(self.stop_order)
                                                self.order = self.buy(size=10)
                                                self.log('Buy Create! , %.2f' % self.dataclose[0])
                                                price = self.data.open[1]
                                                self.stop_order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 10)
                                                print(self.position)
                                                print('Equity, %2f' % cerebro.broker.getvalue())
                                            elif self.position.size < 0:
                                                self.cancel(self.stop_order)
                                                self.order = self.buy(size=20)
                                                self.log('Buy Create! , %.2f' % self.dataclose[0])
                                                price = self.data.open[1] 
                                                self.stop_order = self.sell(exectype =bt.Order.Stop, price = price - 8,size = 20)
                                                print(self.position)
                                                print('Equity, %2f' % cerebro.broker.getvalue())
                                                
                                        if self.data.pre[0] == 0 :
                                       # when the strategy told us to sell
                                            if self.position.size == 0:
                                                self.cancel(self.stop_order)
                                                self.order = self.sell(size=10)
                                                self.log('Sell Create, %.2f' % self.dataclose[0])
                                                price = self.data.open[1]
                                                self.stop_order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 10)
                                                print(self.position)
                                                print('Equity, %2f' % cerebro.broker.getvalue())    
                                            elif self.position.size>0:
                                                 self.cancel(self.stop_order)
                                                 self.log('Sell Create!, %.2f' % self.dataclose[0])
                                                 self.order = self.sell(size=20)
                                                 price = self.data.open[1]
                                                 self.stop_order = self.buy(exectype =bt.Order.Stop, price = price + 8,size = 20)
                                                 print(self.position)
                                                 print('Equity, %2f' % cerebro.broker.getvalue())
                                
                                1 Reply Last reply Reply Quote 0
                                • A
                                  ab_trader last edited by

                                  Please, next time post just text between backticks similar to the script and start from the very beginning of the output. Having orders with ref 40 and than 60 brings not a lot of understanding in what is going on. I would recommend to keep only data required to generate couple trades in both directions and debug script on this data.

                                  Anyway, you are able to cancel orders now, what is the problem?

                                  • 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
                                  ZHUOER ZHANG 1 Reply Last reply Reply Quote 2
                                  • ZHUOER ZHANG
                                    ZHUOER ZHANG @ab_trader last edited by

                                    @ab_trader What if I move the cancel order into the notify order part? Can I successfully cancel it?

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

                                      @ZHUOER-ZHANG try it. For bt it doesn't matter, but may be a big deal for your trading algo.

                                      • 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 1
                                      • 1 / 1
                                      • First post
                                        Last post
                                      Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors