Backtrader Community

    • 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/

    StopLimit Order not executing

    General Code/Help
    2
    8
    673
    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.
    • Shivanshu Bohara
      Shivanshu Bohara last edited by

      I have 5 min data of the Stock/Index. Suppose I buy the share at 9:30:00 at 100 and place the Stop Loss at 99, but in the next candle the price goes down to 94, so if the order is market order then it executes at 9:35:00 at 94 and if it is limit order, then it remains unexecuted.
      But in real life there will be tick by tick data and my order will execute at 99 only, can anybody please help me to resolve that discrepancy!!
      Thank you in advance!

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

        If you issue stop loss at 99 at the end of the current bar (bt issues and processes orders at the end of the current bar), and next bar open price is 94, than your order will be executed at 94 since there is no ticks between close of the current bar and open of the next bar. This is so called price gap.

        • 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
        • Shivanshu Bohara
          Shivanshu Bohara last edited by

          I understand @ab_trader what you are saying, so in order to prevent this situation for even a single trade, I placed the main order (long/short) and the stop loss order at the same time ,i.e., without waiting to check that the main order was executed or not. This resolved the problem and the losses were limited to stop loss criteria only but a new problem arose, the transactions analyzer lost the track of all such trades in which the main order and the stop loss order were executed by the ohlc prices of the same candle.
          Any idea how can I cure this?

          A 1 Reply Last reply Reply Quote 0
          • Shivanshu Bohara
            Shivanshu Bohara last edited by

            There is no price gap in the actual data, just the gap arose because earlier main trade was executed after 1 candle and SL trade after another(created after notification of first being executed)

            1 Reply Last reply Reply Quote 0
            • A
              ab_trader @Shivanshu Bohara last edited by

              @Shivanshu-Bohara said in StopLimit Order not executing:

              Any idea how can I cure this?

              If you share the script, piece of data and outputs of the transactions analyzer to illustrate the problem, than we can come up with ideas, if the problem exists and this is not a bug in the script. Otherwise it is not clear what is the issue.

              • 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
              • Shivanshu Bohara
                Shivanshu Bohara last edited by

                    def notify_order(self, order):
                        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 enough cash
                        if order.status in [order.Completed]:
                            if order.isbuy():
                                self.log('BUY EXECUTED, %.2f' % order.executed.price)
                                if self.position and self.params.SL:
                                    self.stop_price = order.executed.price*(1-self.params.StopLoss)
                                    self.log('STOP LOSS CREATE, %.2f' % self.stop_price)
                                    self.SLorder = self.close(size = self.sharelot, exectype=bt.Order.Stop, price=self.stop_price)
                            elif order.issell():
                                self.log('SELL EXECUTED, %.2f' % order.executed.price)
                                if self.position and self.params.SL:
                                    self.stop_price = order.executed.price*(1+self.params.StopLoss)
                                    self.log('STOP LOSS CREATE, %.2f' % self.stop_price)
                                    self.SLorder = self.close(size = self.sharelot, exectype=bt.Order.Stop, price=self.stop_price)
                            elif order.isclose():
                                self.log('CLOSE EXECUTED, %.2f' % order.executed.price)
                            self.bar_executed = len(self)
                        #Check cancellation
                        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                            self.log('Order Canceled/Margin/Rejected')
                        # Write down: no pending order
                        self.order = None
                    
                    def notify_trade(self, trade):
                        if not trade.isclosed:
                            return
                        #Add trade finances
                        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                                 (trade.pnl, trade.pnlcomm))
                    
                    def next(self):
                        currtime = self.datas[0].datetime.time(0)
                        
                        if(currtime==self.params.sessionstart):
                            if self.params.PreventTradeOnGaps:
                                if self.minopen[0]>1.005*self.minclose[-1] or self.minopen[0]<0.995*self.minclose[-1]:
                                    self.dotrade = False
                                else:
                                    self.dotrade = True
                        
                        if(currtime==self.params.mytime):
                            YesterdayHigh = self.dayhigh[0]
                            YesterdayLow = self.daylow[0]
                            First10minHigh = max(self.minhigh[0],self.minhigh[-1])
                            First10minLow = min(self.minlow[0],self.minlow[-1])
                            YesterdayRange = YesterdayHigh - YesterdayLow
                            Rangeoffirst10min = First10minHigh - First10minLow
                            RangeFactor = YesterdayRange + Rangeoffirst10min
                            GoldenValue = self.params.FibRatio * RangeFactor
                            self.LongLevel = self.dayclose[0] + GoldenValue
                            self.ShortLevel = self.dayclose[0] - GoldenValue
                            
                        if(currtime>self.params.sessionstart and currtime<self.params.lastorder):
                            if not self.position:
                                if self.minclose[0]>=self.LongLevel and self.dotrade:
                                    if(self.params.SingleEntryInaDir==False or (self.params.SingleEntryInaDir==True and self.allowedtrade!=1)):
                                        self.log('BUY CREATE, %.2f' % self.minclose[0])
                                        self.sharelot = self.ActualLotSize*math.floor((1-self.params.Commission)*self.broker.getcash()/(self.minclose[0]*self.ActualLotSize))
                                        self.order = self.buy(size = self.sharelot)
                                        self.allowedtrade = 1
                                                        
                                elif self.minclose[0]<=self.ShortLevel and self.dotrade:
                                    if(self.params.SingleEntryInaDir==False or (self.params.SingleEntryInaDir==True and self.allowedtrade!=2)):
                                        self.log('SELL CREATE, %.2f' % self.minclose[0])
                                        self.sharelot = self.ActualLotSize*math.floor(self.broker.getcash()/(self.minclose[0]*self.ActualLotSize))
                                        self.order = self.sell(size = self.sharelot)
                                        self.allowedtrade = 2
                                
                        elif(currtime==self.params.squareofftime):
                            self.allowedtrade = 0
                            if self.position:
                                self.broker.cancel(self.SLorder)
                                self.log('CLOSE CREATE, %.2f' % self.minclose[0])
                                self.order = self.close(size = self.sharelot)  
                

                This is the part of the previous code which entered the Stop Loss after checking if the main trade is executed or not. Now I changed the code to the following:

                    def notify_order(self, order):
                        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 enough cash
                        if order.status in [order.Completed]:
                            if order.isbuy():
                                self.log('BUY EXECUTED, %.2f' % order.executed.price)
                            elif order.issell():
                                self.log('SELL EXECUTED, %.2f' % order.executed.price)
                            elif order.isclose():
                                self.log('CLOSE EXECUTED, %.2f' % order.executed.price)
                            self.bar_executed = len(self)
                        #Check cancellation
                        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                            self.log('Order Canceled/Margin/Rejected')
                            
                        # Write down: no pending order
                        self.order = None
                    
                    def notify_trade(self, trade):
                        if not trade.isclosed:
                            return
                        #Add trade finances
                        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                                 (trade.pnl, trade.pnlcomm))
                    
                    def next(self):
                        currtime = self.datas[0].datetime.time(0)
                        
                        if(currtime==self.params.sessionstart):
                            if self.params.PreventTradeOnGaps:
                                if self.minopen[0]>1.005*self.minclose[-1] or self.minopen[0]<0.995*self.minclose[-1]:
                                    self.dotrade = False
                                else:
                                    self.dotrade = True
                        
                        if(currtime==self.params.mytime):
                            YesterdayHigh = self.dayhigh[0]
                            YesterdayLow = self.daylow[0]
                            First10minHigh = max(self.minhigh[0],self.minhigh[-1])
                            First10minLow = min(self.minlow[0],self.minlow[-1])
                            YesterdayRange = YesterdayHigh - YesterdayLow
                            Rangeoffirst10min = First10minHigh - First10minLow
                            RangeFactor = YesterdayRange + Rangeoffirst10min
                            GoldenValue = self.params.FibRatio * RangeFactor
                            self.LongLevel = self.dayclose[0] + GoldenValue
                            self.ShortLevel = self.dayclose[0] - GoldenValue
                            
                        if(currtime>self.params.sessionstart and currtime<self.params.lastorder):
                            if not self.position:
                                if self.minclose[0]>=self.LongLevel and self.dotrade:
                                    if(self.params.SingleEntryInaDir==False or (self.params.SingleEntryInaDir==True and self.allowedtrade!=1)):
                                        self.log('BUY CREATE, %.2f' % self.minclose[0])
                                        self.sharelot = self.ActualLotSize*math.floor((1-self.params.Commission)*self.broker.getcash()/(self.minclose[0]*self.ActualLotSize))
                                        self.order = self.buy(size = self.sharelot)
                                        self.allowedtrade = 1
                                        if self.params.SL:
                                            self.stop_price = self.minclose[0]*(1-self.params.StopLoss)
                                            self.log('STOP LOSS CREATE, %.2f' % self.stop_price)
                                            self.SLorder = self.sell(size = self.sharelot, exectype=bt.Order.Stop, price=self.stop_price, valid=bt.Order.DAY)
                                                        
                                elif self.minclose[0]<=self.ShortLevel and self.dotrade:
                                    if(self.params.SingleEntryInaDir==False or (self.params.SingleEntryInaDir==True and self.allowedtrade!=2)):
                                        self.log('SELL CREATE, %.2f' % self.minclose[0])
                                        self.sharelot = self.ActualLotSize*math.floor((1-self.params.Commission)*self.broker.getcash()/(self.minclose[0]*self.ActualLotSize))
                                        self.order = self.sell(size = self.sharelot)
                                        self.allowedtrade = 2
                                        if self.params.SL:
                                            self.stop_price = self.minclose[0]*(1+self.params.StopLoss)
                                            self.log('STOP LOSS CREATE, %.2f' % self.stop_price)
                                            self.SLorder = self.buy(size = self.sharelot, exectype=bt.Order.Stop, price=self.stop_price, valid=bt.Order.DAY)
                                
                                
                        elif(currtime==self.params.squareofftime):
                            self.allowedtrade = 0
                            if self.position:
                                self.broker.cancel(self.SLorder)
                                self.log('CLOSE CREATE, %.2f' % self.minclose[0])
                                self.order = self.close(size = self.sharelot)  
                

                This solved the problem, now there is no gap between the functioning of main trade and the stop loss(that 1 candle gap, which existed earlier, was no more existing).
                Now a new problem arose that the analyzer transactions did not record the trades opened and closed with the values of the same candle.
                I read about the analyzer and found that analyzers worked every time before calling the next function and recorded the change in position, which logically justifies why those trades were omitted.

                So now the problem finally boils down to creation of my own trade log instead of using transactions analyzer.
                Can anybody please help me in providing a way to get the _trades attribute of the strategy into the file in which I'm running my cerebro!
                Or suggest any other possible way to get a trade log..

                1 Reply Last reply Reply Quote 0
                • Shivanshu Bohara
                  Shivanshu Bohara last edited by

                  47be0115-9291-40af-ae40-597cbf3c7f97-image.png

                  These are some of the trades from the previous program, sorted in %profit order.
                  After shifting to the second code, I limited all those trades to 0.5% loss(which was my stop loss) but total trades shown by trade analyzer and console were 455 and transactions analyzer only provided 380 trades omitting those executing in the same candle..

                  1 Reply Last reply Reply Quote 0
                  • Shivanshu Bohara
                    Shivanshu Bohara last edited by

                    Okay, the issue resolved, I can get it from _trades attribute of strategy

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