For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Cancelling orders get UnboundLocal Error



  • I am putting bracket orders on a futures and if the stops or take profits aren't hit I want to close at the end of the day.

                buytp = self.datas[0].close[0] + .5
                sellstp = self.datas[0].close[0] + .5
                selltp = self.datas[0].close[0] - .5
    
                if self.datas[0].FX_Idx_Slope[0] >= 0:
                    #if element in rank (first in list = AD 2nd = BP etc) = 5 4 3 then sell currency otherwise do nothing
                    if ranks[0] == 4 or ranks[0] == 3 or ranks[0] == 2:
                        brackets = self.sell_bracket(limitprice=selltp, stopprice=sellstp)
    
                if self.datas[0].FX_Idx_Slope[0] < 0:
                    # if element in rank (first in list = AD 2nd = BP etc) = 5 4 3 then sell currency otherwise do nothing
                    if ranks[0] == 4 or ranks[0] == 3 or ranks[0] == 2:
                        brackets = self.sell_bracket(limitprice=selltp, stopprice=sellstp)
    
            # close all at 4pm
            if self.datas[0].datetime.time(0) == datetime.time(15, 59, 0):
                if abs(self.position.size) > 0:
                    self.close(data)
                    self.broker.cancel(brackets)
    

    I am getting the following error

      File "C:/Users/Dropbox/v1.py", line 309, in <module>
        results = cerebro.run()
      File "C:\Python27\lib\site-packages\backtrader\cerebro.py", line 1127, in run
        runstrat = self.runstrategies(iterstrat)
      File "C:\Python27\lib\site-packages\backtrader\cerebro.py", line 1290, in runstrategies
        self._runonce(runstrats)
      File "C:\Python27\lib\site-packages\backtrader\cerebro.py", line 1691, in _runonce
        strat._oncepost(dt0)
      File "C:\Python27\lib\site-packages\backtrader\strategy.py", line 287, in _oncepost
        self.next()
      File "C:/Users/Dropbox/All Devices/v1.py", line 208, in next
        self.broker.cancel(brackets)
    UnboundLocalError: local variable 'brackets' referenced before assignment
    

    I am missing something. I just don't know what. I am getting the first days orders off but the second day I am getting an error. Thanks for the help!

    2018-02-02, SELL EXECUTED, Price: 79.88, Cost: 2000.00, Comm 1.00, Datetime: 2018-02-02 08:01:00
    2018-02-02, BUY EXECUTED, Price: 79.37, Cost: 2000.00, Comm 1.00, Datetime: 2018-02-02 08:35:00
    2018-02-02, Order Canceled
    2018-02-02, OPERATION PROFIT, GROSS 510.00, NET 508.00
    2018-02-05, SELL EXECUTED, Price: 79.30, Cost: 2000.00, Comm 1.00, Datetime: 2018-02-05 08:01:00
    

  • administrators

    brackets is a local variable and not something that persist across next invocations.



  • Thanks for the reply. I should of realized that.

    What would be the appropriate way to cancel all outstanding orders. I can only get the order numbers in Notify_Trade. Should I make a list and pass this list to the strategy section? Is there no cancel all?

    Thanks again!


  • administrators

    If you cancel any of the orders of a bracket, all other orders in the bracket are automatically cancelled.

    Your problem is the local variable. Keep the bracket orders under an instance attribute and loop over it, cancelling all of them.



  • Ah. I was on the right track-ish. Got it solved, thanks for your guidance!

    For good order here is the code I used.

     def __init__(self):
            self.orderlst = []
    
    
    def notify_order(self, order):
    
    
            if order.status in [order.Submitted, order.Accepted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                #self.orderlst.extend(self.order.ref)
                #print(order.ref)
                pass
            if order.status in [order.Accepted]:
                self.orderlst.append(order)
     def next(self):
          
           #exit position
           if tme == datetime.time(14, 59, 0):
                if abs(self.position.size) > 0:
                    #if in position and none of the brackets have executed then cancel all 3 orders and close position
                    #after cancelling orders, make list empty
                    #this also makes sure no orders are outstanding
                    for ordnum in self.orderlst:
                        self.cancel(ordnum)
                    self.orderlst = []
                    print (self.orderlst)
                    print('Canceles done')
                    self.close(data)