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

Misunderstanding of the process: Order created but not executed at the same price



  • I used the code Quickstart in the documentation but with my own data (which is on a minute basis). I would like now to understand why my orders are created but not executed at the same price and days later... thanks! I am really a beginner with the platform, so any help is more than welcome. This is the code I used so far:

    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 60),
        )
        
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
            self.data_cpa = self.datas[0].high
            self.data_cpb = self.datas[0].low
            
            
            self.order = None
            self.buyprice = None
            self.buycomm = None
            
            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]:
                # 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, Price: %.8f, Cost: %.8f, Comm %.8f' %
                        (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: %.8f, Cost: %.8f, Comm %.8f' %
                             (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 %.8f, NET %.f' %
                     (trade.pnl, trade.pnlcomm))
            
            self.htrade = trade
        
        def next(self):
            # Simply log the closing price of the series from the reference
            self.log('Close, %.8f' % self.dataclose[0])
            
            if self.order:
                return
            
            if not self.position:
                
                if self.dataclose[0] >= self.sma[0]:
    
                    # BUY, BUY, BUY!!! (with all possible default parameters)
                    self.log('BUY CREATE, %.8f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.buy(price= self.dataclose[0])
            else:
                
                if self.dataclose[0] <= self.sma[0]:
                        # SELL, SELL, SELL!!! (with all possible default parameters)
                        self.log('SELL CREATE, %.8f' % self.dataclose[0])
    
                        # Keep track of the created order to avoid a 2nd order
                        self.order = self.sell(price= self.dataclose[0])

  • administrators

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

    I used the code Quickstart in the documentation but with my own data (which is on a minute basis)

    No you haven't. You are using something different. Your code

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.buy(price= self.dataclose[0])
    

    Code from: https://www.backtrader.com/docu/quickstart/quickstart.html#do-not-only-buy-but-sell

                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.buy()
    

    There is a clear obvious difference. When you code, small differences can mean a huge difference.

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

    I would like now to understand why my orders are created but not executed at the same price and days later... thanks! I am really a beginner with the platform, so any help is more than welcome.

    The code is apparently producing logs in the console. Why don't you paste them and point out an example of what you think is wrong? This is a rhetorical question to point out, that if you think there is something wrong, we cannot know it, because there is no information as to what yo think is wrong.

    Furthermore, you only show the strategy, but believe me: the most obvious mistake you are making it's not in that part of the code. It is in the code you aren't showing.

    In any case let me point you to this:

    and look at what a Market order is. Let me explain it here: it is an order for which YOU DON'T specify the price. The Market price is used. No, not the market price you currently see, but the one which you still haven't seen, i.e.: the next incoming price tick (if you use daily bars, that's already the next trading day)



  • @backtrader , I am still lost with your platform. I simplified my code so that it looks like this:

    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 60),
        )
        
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
            self.data_cpa = self.datas[0].high
            self.data_cpb = self.datas[0].low
            
            
            self.order = None
            self.buyprice = None
            self.buycomm = None
            
            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]:
                # 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, %.8f' % order.executed.price)
                elif order.issell():
                    self.log('SELL EXECUTED, %.8f' % order.executed.price)
    
                self.bar_executed = 0
    
            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
    
            self.log('OPERATION PROFIT, GROSS %.8f, NET %.f' %
                     (trade.pnl, trade.pnlcomm))
        
        def next(self):
            # Simply log the closing price of the series from the reference
            self.log('Close, %.8f' % self.dataclose[0])
    
            if self.order:
                return
    
            # Check if we are in the market
            if not self.position:
    
    
                if self.dataclose[0] > self.sma[0]:
    
                    # BUY, BUY, BUY!!! (with all possible default parameters)
                    self.log('BUY CREATE, %.8f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.buy(price= self.dataclose[0])
    
                
            else:
                
                if self.dataclose[0] < self.sma[0]:
                    # SELL, SELL, SELL!!! (with all possible default parameters)
                    self.log('SELL CREATE, %.8f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.sell(price= self.dataclose[0])
             
        
        
    
    if __name__ == '__main__':
        # Create a cerebro entity
        cerebro = bt.Cerebro(cheat_on_open=True)
    
        # Add a strategy
        cerebro.addstrategy(TestStrategy)
        
        # retrieve the csv file
        modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
        datapath = os.path.join(modpath, './datas/zrxeth_sample.txt')
    
        # Create a Data Feed
        data = bt.feeds.GenericCSVData(
        dataname = datapath,
    
        fromdate=datetime.datetime(2018, 9, 28),
        todate=datetime.datetime(2018, 12, 3),
    
        nullvalue=0.0,
    
        dtformat=('%Y-%m-%d %H:%M:%S'),
    
            datetime=0,
            high=1,
            low=2,
            open=3,
            close=4,
            volume=5,
            openinterest=-1
        )
        
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
    
        # Set our desired cash start
        cerebro.broker.setcash(100.0)
    
        # Print out the starting conditions
        print('Starting Portfolio Value: %.8f' % cerebro.broker.getvalue())
    
        # Run over everything
        cerebro.run()
    
        # Print out the final result
        print('Final Portfolio Value: %.8f' % cerebro.broker.getvalue())
    
    

    I did cerebro 'cheat_on_open' = true , but I do not understand why when the order is created at a price it is not executed at the same price, it looks like that:

    2018-09-28, Close, 0.00298747
    2018-09-28, BUY CREATE, 0.00298747
    2018-09-28, BUY EXECUTED, 0.00299252
    2018-09-28, Close, 0.00298747
    2018-09-28, Close, 0.00298865
    2018-09-28, Close, 0.00298813
    2018-09-28, Close, 0.00298808

  • administrators

    From: https://community.backtrader.com/topic/1596/cheat_on_open-true-how-to-execute-the-order-on-another-price-than-the-next-open-price

    @viktor-w said in Cheat_on_open true: how to execute the order on another price than the next open price:

    For now my code looks like this:

    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 60),
        )
        
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
            self.data_cpa = self.datas[0].high
            self.data_cpb = self.datas[0].low
            
            
            self.order = None
            self.buyprice = None
            self.buycomm = None
            
            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]:
                # 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, %.8f' % order.executed.price)
                elif order.issell():
                    self.log('SELL EXECUTED, %.8f' % order.executed.price)
    
                self.bar_executed = 0
    
            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
    
            self.log('OPERATION PROFIT, GROSS %.8f, NET %.f' %
                     (trade.pnl, trade.pnlcomm))
        
        def next(self):
            # Simply log the closing price of the series from the reference
            self.log('Close, %.8f' % self.dataclose[0])
    
            if self.order:
                return
    
            # Check if we are in the market
            if not self.position:
    
    
                if self.dataclose[0] > self.sma[0]:
    
                    # BUY, BUY, BUY!!! (with all possible default parameters)
                    self.log('BUY CREATE, %.8f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.buy(price= self.dataclose[0])
    
                
            else:
                
                if self.dataclose[0] < self.sma[0]:
                    # SELL, SELL, SELL!!! (with all possible default parameters)
                    self.log('SELL CREATE, %.8f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.sell(price= self.dataclose[0])
             
        
        
    
    if __name__ == '__main__':
        # Create a cerebro entity
        cerebro = bt.Cerebro(cheat_on_open=True)
    
        # Add a strategy
        cerebro.addstrategy(TestStrategy)
        
        # retrieve the csv file
        modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
        datapath = os.path.join(modpath, './datas/zrxeth_sample.txt')
    
        # Create a Data Feed
        data = bt.feeds.GenericCSVData(
        dataname = datapath,
    
        fromdate=datetime.datetime(2018, 9, 28),
        todate=datetime.datetime(2018, 12, 3),
    
        nullvalue=0.0,
    
        dtformat=('%Y-%m-%d %H:%M:%S'),
    
            datetime=0,
            high=1,
            low=2,
            open=3,
            close=4,
            volume=5,
            openinterest=-1
        )
        
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
    
        # Set our desired cash start
        cerebro.broker.setcash(100.0)
    
        # Print out the starting conditions
        print('Starting Portfolio Value: %.8f' % cerebro.broker.getvalue())
    
        # Run over everything
        cerebro.run()
    
        # Print out the final result
        print('Final Portfolio Value: %.8f' % cerebro.broker.getvalue())
    

    From my understanding of the library, when you use the parameter cheat_on_open=True, you can authorize the order the order to be executed directly and not the day after. However, the executed order takes as price the next open price, how is it possible to choose which price the order will apply? Thanks!


  • administrators

    Let me put all the answers in one place:

    1. If you use something which isn't `1-Day´ (which is the default) you have to tell the platform what your timeframe/compression is.

    2. If you issue a Market order, you will get the next incoming price, i.e.: the price the market wants to give you. It is irrelevant if you specify a price. See

    3. If you want to use cheat-on-open you should be using the corresponding method next_open. It is clearly specified in the documentation (and it is so for good reasons). See

    @backtrader said in Misunderstanding of the process: Order created but not executed at the same price:

    From my understanding of the library, when you use the parameter cheat_on_open=True, you can authorize the order the order to be executed directly and not the day after.

    Algotrading is not about understanding, it is about knowing what you have to expect.

    @backtrader said in Misunderstanding of the process: Order created but not executed at the same price:
    However, the executed order takes as price the next open price, how is it possible to choose which price the order will apply? Thanks!

    Again: Market orders won't guarantee you the price (hence the name Market) and there is no way to specify which price you will GET. Even for a Limit order the only guarantee is that you will get that (or a better) price if the order is executed, but it may never be executed.

    You may actually be looking for cheat-on-close. See Docs - Cerebro

    Some additional notes

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

    but I do not understand why when the order is created at a price it is not executed at the same price

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

    I am still lost with your platform

    Let me be blunt: you are not (only) lost with the platform. You are lost with trading in general.

    The most important part of algotrading is not the computer/programming part ... but knowing your trading. My very sincere advice: work very hard in understanding how trading works. If you don't know the rules of the house (which already holds the upper hand), the house is going to quickly get you out of business.



  • @backtrader, thanks for your reply. We are a company which does market making on new cryptocurrencies. So your statement saying that I do not have knowledge of trading is irrelevant as my goal is not trading. Stating that I am lost on trading and on your platform is thus a wrong statement as well, because you do not know what is my goal, what is my tragedy and at which end I will be using backtrader.
    Anyway, I tried to read a bit more in detail your documentation and I still does not see how I can execute an order on the closing price of the next minute, do you have any other advice? thanks for your time and help!



  • @backtrader the only line of code I needed was: cerebro.broker.set_coc(True)


  • administrators

    I am glad

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

    @backtrader the only line of code I needed was: cerebro.broker.set_coc(True)

    I am glad to know that was the only line of code you needed. I do truly and respectfully disagree.

    And you also disagree with yourself. For example:

    0_1549029789292_20109b0b-5536-4011-8fc5-ad81888232ab-image.png

    @viktor-w said in Misunderstanding of the process: Order created but not executed at the same price:

    We are a company

    You obviously can buy professional support then.


Log in to reply
 

});