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

During market closing hours double buy or double sell orders are placed for multiple stocks back trading.



  • Re: Cancel Repeated Order When Multiple DataFeed

    I know that this topic was solved but I am kind of a newbie to backtrader. Can someone help me to solve this issue by elaborating a little bit more. Basically there are times during market closing hours that buy and sell orders are executed twice. I don't think a code is needed here since I think this is the exact same problem that was solved in the referenced topic which was solved but I am still putting the code and the output here just to not miss out on anything.
    Thanks in advance.

    next() function

                if not pos:  # no market / no orders
                    if self.inds[d]['atr14'][-1] * 5 < (d.close[0]-d.open[0]):
    #                     self.buy(data=d, size=1)
                        self.log(' BUYING.  ||| symbol: %s , atr14 : %.2f , close-open :  %.2f , rsi3crossD: %.2f' % (d._name,self.inds[d]['atr14'][0],(d.close[0]-d.open[0]),self.inds[d]['rsi3crossD'][0]))
                        self.order_target_percent(data=d, target = 0.14)
                        
    #                 elif self.inds[d]['cross'][0] == -1:
    # #                     self.sell(data=d, size=1)
    #                     self.order_target_percent(data=d, target = -0.16)
                else:
                    if self.inds[d]['rsi3crossD'][0]:
                        self.close(data=d)
                        self.log(' SELLING.  ||| symbol: %s ,rsi3crossD: %.2f' % (d._name,self.inds[d]['rsi3crossD'][0]))
    
    
    

    2nd way I tried doing this in next() so that no stock is shorted is as follows:

                if not pos:  # no market / no orders
                    if self.inds[d]['atr14'][-1] * 5 < (d.close[0]-d.open[0]):
    #                     self.buy(data=d, size=1)
                        self.log(' BUYING.  ||| symbol: %s , atr14 : %.2f , close-open :  %.2f , rsi3crossD: %.2f' % (d._name,self.inds[d]['atr14'][0],(d.close[0]-d.open[0]),self.inds[d]['rsi3crossD'][0]))
                        self.order_target_percent(data=d, target = 0.14)
                        
    #                 elif self.inds[d]['cross'][0] == -1:
    # #                     self.sell(data=d, size=1)
    #                     self.order_target_percent(data=d, target = -0.16)
                elif pos:
                    if self.inds[d]['rsi3crossD'][0]:
                        self.close(data=d)
                        self.log(' SELLING.  ||| symbol: %s ,rsi3crossD: %.2f' % (d._name,self.inds[d]['rsi3crossD'][0]))
    
    
    

    This is the notify() function to know if there is an error here:

            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED: %s, Price: %.2f,status: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.data._name,
                         order.executed.price,
                         order.status,
                         order.executed.value,
                         order.executed.comm))
    #                 self.p.lotFilled = self.p.lotFilled + self.lotstoFill
    #                 self.p.lotsHold = 0
    #                 self.p.totalCost = self.p.totalCost + order.executed.value
    #                 self.buyprice = order.executed.price
    #                 self.buycomm = order.executed.comm
    #                 self.opsize = order.executed.size
                else:  # Sell
                    self.log('SELL EXECUTED: %s, Price: %.2f, Cost: %.2f, Comm %.2f' %
                             (order.data._name,
                              order.executed.price,
                              order.executed.value,
                              order.executed.comm))
    #                 self.p.lotFilled = self.p.totalLots - self.lotstoExit
    #             print('Total lots: ',self.p.totalLots,'lots filled: ',self.p.lotFilled,'hold lots: ',self.p.lotsHold,' lots size: ',self.p.lotSize,'high: ', self.data.high[0],'action : ',self.p.stockPosition,'total cost',self.p.totalCost)
            elif order.status in [order.Canceled]:
                self.log('%s:: Order Canceled' % order.data._name)
            elif order.status in [order.Rejected]:
                self.log('%s:: Order Rejected' % order.data._name)
    
            elif order.status in [order.Margin]:
                self.log('%s:: Order Margin' % order.data._name)
    
    
    

    A sample output is as below. Since the full output is long.

    2019-03-27T14:30:00,  BUYING.  ||| symbol: ADHUNIK , atr14 : 0.02 , close-open :  0.10 , rsi3crossD: 0.00
    2019-03-27T14:45:00, BUY EXECUTED: ADHUNIK, Price: 2.80,status: 4.00, Cost: 13742.40, Comm 12.00
    2019-03-28T14:15:00,  BUYING.  ||| symbol: ADVANIHOT , atr14 : 0.29 , close-open :  1.05 , rsi3crossD: 0.00
    2019-03-28T14:30:00, BUY EXECUTED: ADVANIHOT, Price: 69.50,status: 4.00, Cost: 13205.00, Comm 12.00
    2019-03-28T15:15:00,  BUYING.  ||| symbol: ADROITINF , atr14 : 0.19 , close-open :  1.35 , rsi3crossD: 0.00
    2019-03-28T15:15:00,  SELLING.  ||| symbol: AGARIND ,rsi3crossD: 1.00
    2019-03-29T09:15:00,  BUYING.  ||| symbol: ADROITINF , atr14 : 0.19 , close-open :  1.35 , rsi3crossD: 0.00
    2019-03-29T09:15:00,  SELLING.  ||| symbol: AGARIND ,rsi3crossD: 1.00
    2019-03-29T09:30:00, BUY EXECUTED: ADROITINF, Price: 17.15,status: 4.00, Cost: 12536.65, Comm 12.00
    2019-03-29T09:30:00, BUY EXECUTED: ADROITINF, Price: 17.15,status: 4.00, Cost: 12502.35, Comm 12.00
    2019-03-29T09:30:00,  SELLING.  ||| symbol: AGARIND ,rsi3crossD: 1.00
    2019-03-29T09:45:00, SELL EXECUTED: AGARIND, Price: 163.45, Cost: 13317.15, Comm 12.00
    2019-03-29T09:45:00, SELL EXECUTED: AGARIND, Price: 163.45, Cost: -12585.65, Comm 12.00
    2019-03-29T09:45:00, SELL EXECUTED: AGARIND, Price: 163.45, Cost: -12585.65, Comm 12.00
    2019-03-29 AGARIND Closed: PnL Gross -731.5, Net -755.5
    

    Please notice how the symbol AGARIND is behaving. If I run this code for only 1 ticker i.e. AGARIND such issue won't come up. This happens only when multiple data for the same timeframe is input to cerebro.

    One more notable output I would like to show is as follows. Please notice how symbol ADROITINF is behaving.

    2019-07-22T13:30:00, BUY EXECUTED: ADROITINF, Price: 9.75,status: 4.00, Cost: 12762.75, Comm 12.00
    2019-07-22T15:15:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-22T15:15:00,  BUYING.  ||| symbol: ADVANIHOT , atr14 : 0.34 , close-open :  1.70 , rsi3crossD: 0.00
    2019-07-23T09:15:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T09:15:00,  BUYING.  ||| symbol: ADVANIHOT , atr14 : 0.34 , close-open :  1.70 , rsi3crossD: 0.00
    2019-07-23T09:30:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T09:30:00,  BUYING.  ||| symbol: ADVANIHOT , atr14 : 0.34 , close-open :  1.70 , rsi3crossD: 0.00
    2019-07-23T09:45:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T09:45:00,  BUYING.  ||| symbol: ADVANIHOT , atr14 : 0.34 , close-open :  1.70 , rsi3crossD: 0.00
    2019-07-23T10:00:00, BUY EXECUTED: ADVANIHOT, Price: 55.70,status: 4.00, Cost: 12254.00, Comm 12.00
    2019-07-23T10:00:00, BUY EXECUTED: ADVANIHOT, Price: 55.70,status: 4.00, Cost: 12309.70, Comm 12.00
    2019-07-23T10:00:00, BUY EXECUTED: ADVANIHOT, Price: 55.70,status: 4.00, Cost: 12142.60, Comm 12.00
    2019-07-23T10:00:00, ADVANIHOT:: Order Margin
    2019-07-23T10:00:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T10:00:00,  SELLING.  ||| symbol: ADVANIHOT ,rsi3crossD: 1.00
    2019-07-23T10:15:00, SELL EXECUTED: ADVANIHOT, Price: 55.70, Cost: 36706.30, Comm 12.00
    2019-07-23 ADVANIHOT Closed: PnL Gross 0.0, Net -48.0
    2019-07-23T10:15:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T10:30:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T10:45:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T11:00:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T11:15:00,  SELLING.  ||| symbol: ADROITINF ,rsi3crossD: 1.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: 12762.75, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23T11:30:00, SELL EXECUTED: ADROITINF, Price: 9.50, Cost: -12435.50, Comm 12.00
    2019-07-23 ADROITINF Closed: PnL Gross -327.25, Net -351.25
    

    I didn't put the entire code here since I thought it would be better to summarise the issue according to my understanding. If need be I'll paste the entire code here.
    Thanks again.



  • Update to the above problem I was facing I have changed the way I am sending in data but still doesn't seem to work. Maybe I am going in a completely different / wrong direction to solve this issue but here is the code to enter data using pandas df.

    for i in stocks_5:
        stock_ohlc = data_csv[data_csv['Symbol'] == i][['open','high','low','close','volume']] 
        data = bt.feeds.PandasData(dataname=stock_ohlc, timeframe = bt.TimeFrame.Minutes, compression=15, sessionstart = datetime.time(9,15), sessionend=datetime.time(15,15))
        cerebro.adddata(data, name = i)
    
    
    

    I am still getting those double execution of sell and buy orders although I think I have written the logic of buying 14% of 100000 position if no position available and a condition is satisfied and selling if position is available, sell if there is a down crossover of 3RSI with 70. I have no idea why there is an issue with my logic in order execution during end market hours. According to my analysis the problem is occurring near the end of market hours.
    Any help would be appreciated. Thank you.



  • This is the 3rd reply from me on my post. This is what worked for me. I am just posting it so that it might be helpful for someone.

                elif pos:
                    if self.inds[d]['rsi3crossD'][0]==1:
                        self.close(data=d)
                        self.log(' SELLING.  ||| symbol: %s ,rsi3crossD: %.2f' % (d._name,self.inds[d]['rsi3crossD'][0]))
    
    
    

    For crossovers you need to use ==1 .



  • Even this is not working in every circumstance? I really need to find the issue with this code of mine. Any help would be appreciated. Thanks in advance.



  • If you really need help, please show the whole script.



  • @ab_trader Thank you for the reply. I wasn't using the condition to check if self.order exists then return.
    It worked for me. So anyone having the same issue in the future kindly make sure these 3 things are taken care of. I think I have solved the issue entirely but if not I'll update this in the future.

    1. Use self.order condition in code to check if we already have a similar order in place.
                if not pos:  # no market / no orders
                    if self.inds[d]['atr14'][-1] * 10 < (d.high[0]-d.low[0]) and (d.close[0]-d.open[0])>0:
    #                     self.buy(data=d, size=1)
                        if self.order[d._name]:
                            self.log('We already have a buy order for %s in place' % d._name)
                            return
                        self.log(' BUYING.  ||| symbol: %s , atr14 : %.2f , close-open :  %.2f , rsi3crossD: %.2f' % (d._name,self.inds[d]['atr14'][0],(d.close[0]-d.open[0]),self.inds[d]['rsi3crossD'][0]))
                        self.order[d._name] = self.order_target_value(data=d, target = 30000)
            
                        
    #                 elif self.inds[d]['cross'][0] == -1:
    # #                     self.sell(data=d, size=1)
    #                     self.order_target_percent(data=d, target = -0.16)
                elif pos:
                    if self.inds[d]['rsi3'][0]<65:
                        if self.order[d._name]:
                            self.log('We already have a sell order for %s in place' % d._name)
                            return
                        self.order[d._name] = self.close(data=d)
                        self.log(' SELLING.  ||| symbol: %s ,rsi3crossD: %.2f' % (d._name,self.inds[d]['rsi3crossD'][0]))
    #
    
    1. Make sure that crossovers are used in the way above i.e. crossovercondition==1
    2. Make sure you add the pandas data with parameters timeframe, compression, session start and session end.

Log in to reply
 

});