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

Help with limit orders- (getting executed at market prices)



  • Hi,My limit orders keep getting executed at market prices. Will be a great help if someone can help me find what i am doing wrong here

    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 2),
        )
    
        def log(self, txt, dt=None):
            ''' Logging function fot this strategy'''
            dt = dt or self.datas[0].datetime.datetime(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
          
            self.dataclose = self.datas[0].close
    
            self.order = None
            self.buyprice = None
            self.buycomm = None
    
            # Add a MovingAverageSimple indicator
            self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)
    
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                return
            
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                         order.executed.value,
                         order.executed.comm))
    
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
                else:  # Sell
                    self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                             (order.executed.price,
                              order.executed.value,
                              order.executed.comm))
    
                self.bar_executed = len(self)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
    
            self.order = None
    
        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):
         
                if self.order:
                    return
        
                if self.position.size ==0:
        
                  if self.dataclose[0] > self.sma[0]:
        
                    self.order = self.buy(price=6000.00,exec=bt.Order.Limit)
    
    
    
          
    
    if __name__ == '__main__':
        cerebro = bt.Cerebro()
        cerebro.addstrategy(TestStrategy)
        data = bt.feeds.PandasData(dataname=dataframe)
        cerebro.adddata(data)
        cerebro.broker.setcash(100000)
        cerebro.broker.setcommission(commission=0.00025)
    
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.run()
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())


  • Please provide some logs and a glimpse on the relevant data from your dataframe (could it be that the market prices are well below 6000.00 ? )



  • Hi @vladisld ,

    Starting Portfolio Value: 100000.00
    2020-04-07T06:12:00, BUY EXECUTED, Price: 7277.00, Cost: 7277.00, Comm 1.82
    Final Portfolio Value: 99901.68
    


  • Code to try this in Google colab / jupyter note book

    !pip install backtrader[plotting]
    import requests
    import pandas as pd
    import backtrader as bt
    import backtrader.feeds as btfeeds
    import datetime
    
    response=requests.get('https://www.bitmex.com/api/v1/trade/bucketed?binSize=1m&partial=false&symbol=XBTUSD&count=1000&reverse=false&startTime=2020-04-07T06:09:48')
    a=response.text
    dataframe=pd.read_json(a)
    dataframe['datetime']=pd.to_datetime(dataframe['timestamp'],unit='ms')
    dataframe.set_index('datetime',inplace=True)
    
    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 2),
        )
    
        def log(self, txt, dt=None):
            ''' Logging function fot this strategy'''
            dt = dt or self.datas[0].datetime.datetime(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
          
            self.dataclose = self.datas[0].close
    
            self.order = None
            self.buyprice = None
            self.buycomm = None
    
            # Add a MovingAverageSimple indicator
            self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)
    
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                return
            
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                         order.executed.value,
                         order.executed.comm))
    
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
                else:  # Sell
                    self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                             (order.executed.price,
                              order.executed.value,
                              order.executed.comm))
    
                self.bar_executed = len(self)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
    
            self.order = None
    
        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):
         
                if self.order:
                    return
        
                if self.position.size ==0:
        
                  if self.dataclose[0] > self.sma[0]:
        
                    self.order = self.buy(price=6000.00,exec=bt.Order.Limit)
    
    
    
          
    
    if __name__ == '__main__':
        cerebro = bt.Cerebro()
        cerebro.addstrategy(TestStrategy)
        data = bt.feeds.PandasData(dataname=dataframe)
        cerebro.adddata(data)
        cerebro.broker.setcash(100000)
        cerebro.broker.setcommission(commission=0.00025)
    
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.run()
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
    


  • @Akshay said in Help with limit orders- (getting executed at market prices):

    self.order = self.buy(price=6000.00,exec=bt.Order.Limit)

    Please try to use the exectype argument for buy method instead of exec (it was probably a typo)

    self.order = self.buy(price=6000.00,exectype=bt.Order.Limit)
    


  • @vladisld Thanks a lot, that worked!


Log in to reply
 

});