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

Wanted exit long and open short on the same bar, and vice versa



  • Hello,

    My strategy conditions are:

    (1) self.crossover > 0 and rsi > 20 , expected action - go Buy
    (2) self.crossover < 0 and rsi < 80 , expected action - go Sell
    (3) self.crossover < 0, expected action - exit Buy
    (4) self.crossover > 0, expected action - exit Sell

    So the issue that I'm facing is that when both (3) and (2) occur, only (3) is executed, expected action for (2) is not fulfilled. Same when (4) and (1) occur, only (4) is executed, expected action for (1) is not fulfilled. Any suggestion on how can I resolve it? Many tks.

    def next(self):
    
        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return
    
        # Check if we are in the market
        if not self.position:  # not in the market
    
            if self.crossover > 0 and rsi > 20 :
    
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
                self.order = self.buy()
    
            elif self.crossover < 0 and rsi < 80 :
    
                self.log('SELL CREATE, %.2f' % self.dataclose[0])
                self.order = self.sell()
                           
        if self.position:  # in the market
        
            if self.crossover < 0:
    
                self.log('EXIT BUY CREATE, %.2f' % self.dataclose[0])
                self.order = self.close()
    
            elif self.crossover > 0:
    
                self.log('EXIT SELL CREATE, %.2f' % self.dataclose[0])
                self.order = self.close()


  • @kian-hong-Tan said in Wanted exit long and open short on the same bar, and vice versa:

    So the issue that I'm facing is that when both (3) and (2) occur, only (3) is executed, expected action for (2) is not fulfilled.

    Your code is not going to match your expectations. You want to have both 2 and 3 occur simultaneously but they are located in mutually exclusive if conditions.

    One only executes if there is no position, and the other only executes if there is a position. Naturally, you cannot both have and not have a position on the same instrument in the same bar.

    Also, you may wish to check the greater than and less than operators in front of your rsi. I suspect they are backwards.



  • @run-out

    "One only executes if there is no position, and the other only executes if there is a position. Naturally, you cannot both have and not have a position on the same instrument in the same bar."

    What you said did strike me. I have removed the 'no position' condition for both (1) and (2) and it works. You are spot on! Thanks.



  • I have a comparable trading scenario where position gets 'flipped', rather than closing and then opening a new order. As long as your broker/account is set up for 'account netting' this will work.

    The scenario below is when there is an open short position, then a scenario is hit where I want to flip the position to long, cancel stop loss from the old short position and set a new stop loss for the new long position.

    #IN SHORT POSITION THEN TRIGGER FOR FLIP OCCURS#
    
    posi = abs(self.position.size)  #Get open position size
    stake_flip = (2 * posi)  #Double the open position size for flipping
    
    buy_ord = self.buy(exectype=bt.Order.Market, size=stake_flip)  #Reverse short position by buying 2 x position
    buy_ord.addinfo(name='Long_' + self.productname + self.stratname)  #Add info to order
    
    cancel = self.cancel(self.stop_ord_buy)  #Cancel old short position stop loss
    
    self.stop_ord_sell = self.sell(exectype=bt.Order.Stop, price=self.long_stop, size=posi)  #Create new stop loss for long position
    self.stop_ord_sell.addinfo(name=self.productname+'LongStopLoss') #Add info to order
    

    This approach allows for only one order to be processed instead of two (closing and opening new) in the same bar.



  • @mics tks for your input. This will be helpful when i'm going to live trading. So the code you share should be put under 'def notify_order(self, order)' function right?



  • @mics Thank you very much for sharing this!



  • @kian-hong-Tan I have it in next() once the conditions of the strategy have been met. I can't remember the reason why. I know I tried it in Notify_order but there was some other complexity in my system (not shown here) that meant information associated with this could not be accessed. Give it shot both ways.



  • @mics ok cool. I shall try it. tks.


Log in to reply
 

});