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

Buy/Sell order at the closing price of the same day



  • Hello! How do I code my backtrader to buy / sell at the closing price of the same day ?

    self.buy(exectype=bt.Order.Close) does not work.

    Thanks!



  • use cheat-on-close feature.
    Docs - Broker



  • @ab_trader Thanks again!



  • @ab_trader Sorry to bother you again... What you think is wrong here?

    If I print what Im doing in my code this is what I get. Trades direction and prices are ok, but PNL is wrong when I get it from self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)).

    Open Position: 0
    2020-06-04, SELL CREATE, 21.43
    Open Position: -5000
    2020-06-05, Closing short position, 22.10
    2020-06-05, BUY CREATE, 22.10
    Open Position: 5000
    2020-06-08, Closing long position, 22.53
    2020-06-08, SELL CREATE, 22.53
    Open Position: -5000
    2020-06-09, Closing short position, 21.72

    On the other hand PNL here is calculated correctly but trade direction is going to the wrong way...

    ref ticker dir datein pricein dateout priceout chng% pnl pnl% size value cumpnl nbars pnl/bar mfe% mae%


    1981 Teste short 2020-06-05 22.1 2020-06-08 22.53 1.95 -2373.15 -1.2 -5000 -110500 -2373.15 1 -2373.15 -2.22 -2.04
    1982 Teste long 2020-06-08 22.53 2020-06-09 21.72 -3.6 -4271.25 -2.21 5000 112650 -6644.4 1 -4271.25 0.09 -2.17

    Bellow is my code inside def next():

        if current_position > 0:
            self.log('Closing long position, %.2f' % self.dataclose[0])
            #self.order = self.sell(size=tamanho)   
            self.close(exectype=bt.Order.Close) 
            
        if current_position < 0:
            self.log('Closing short position, %.2f' % self.dataclose[0])
            #self.order = self.buy(size=tamanho)      
            self.close(exectype=bt.Order.Close)
    
        
        if modelAI(self.datas[0].datetime.date(0)) == 1:
            self.log('BUY CREATE, %.2f' % self.dataclose[0])
            self.buy(size=tamanho, exectype=bt.Order.Close)
            
        if modelAI(self.datas[0].datetime.date(0)) == 2:
            self.log('SELL CREATE, %.2f' % self.dataclose[0])
            self.sell(size=tamanho, exectype=bt.Order.Close)


  • you may want to elaborate what do you think is wrong here. right now both outputs shown match at least for short position open on 6/5 and closed on 6/8.



  • No.
    04/may opened short @ 21.43
    05/may Closed short position @ 22.10
    05/may opened long position @ 22.10
    06/may Closed long position @ 22.53
    ...

    Its not what backtrader is reading...
    short 2020-06-05 22.1 2020-06-08 22.53
    ....

    Trading day looks wrong and position are inverted (long/short)



  • Unless you are using tricks like cheat-on-open or cheat-on-close and assuming (since no evidence shown) that Open Position: xxxx statement is printed from notify_order() the sequence is following:

    6/4 sell order issued
    6/5 short position open on 6/5 bar `open` price
    6/5 buy order issued, will close short position
    6/5 another buy order issued
    6/8 short position closed and long position opened on 6/8 bar `open` price
    6/8 sell order issued, will close long position
    6/8 another sell order issued
    6/9 long position closed and short position opened on 6/9 bar `open` price
    6/9 buy order issued, will close short position
    


  • @ab_trader Hi, yes I`m using coc as True and getting open position from next. My trade system must trade on close of the same day and unwind the position at the close of the next day.

    def next(self):
    current_position = self.getposition().size
    print("Open Position:", current_position)



  • post full script please



  • @ab_trader

    def notify_trade(self, trade):
    if not trade.isclosed:
    return

        #self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm))
                
    def next(self):
        current_position = self.getposition().size
        print("Open Position:", current_position)
      
        tamanho = 5000
        #print("Size", tamanho)
    
        if current_position > 0:
            self.log('Closing long position, %.2f' % self.dataclose[0])
            self.order = self.sell(size=tamanho)   
            #self.close(price=self.data.close[0])
            
        if current_position < 0:
            self.log('Closing short position, %.2f' % self.dataclose[0])
            self.order = self.buy(size=tamanho)      
            #self.close(price=self.data.close[0])
    
        
        if modelAI(self.datas[0].datetime.date(0)) == 1:
            self.log('BUY CREATE, %.2f' % self.dataclose[0])
            self.order = self.buy(size=tamanho, price=self.dataclose[0],data=self.data0)
            
        if modelAI(self.datas[0].datetime.date(0)) == 2:
            self.log('SELL CREATE, %.2f' % self.dataclose[0])
            self.order = self.sell(size=tamanho,price=self.dataclose[0],data=self.data0)


  • this is not the full script. there is no any sign of using cheat-on-close.



  • @ab_trader cerebro.broker.set_coc(True)



  • Remove exectype=bt.Order.Close from the entry orders. This parameter shifts order execution to the next bar. Also a note about cheat-on-close - the order is executed on the current bar close price, but the date for the order execution will be the next bar date. For example: your sell order created on the 06/04 will have the execution price of 21.43 (close of the 06/04 bar) but execution date will be 06/05. this is how the cheat-on-closeis implemented.


Log in to reply
 

});